Command line progress bar in Java

前端 未结 15 1846
[愿得一人]
[愿得一人] 2020-11-28 01:04

I have a Java program running in command line mode. I would like to display a progress bar, showing the percentage of job done. The same kind of progress bar you would see u

相关标签:
15条回答
  • 2020-11-28 01:36
    public class ProgressBar
    {
        private int max;
    
        public ProgressBar(int max0) {
            max = max0;
            update(0);
        }
    
        public void update(int perc) {
            String toPrint = "|";
            for(int i = 0; i < max; i++) {
                if(i <= (perc + 1))
                    toPrint += "=";
                else
                    toPrint += " ";
            }
    
            if(perc >= max)
                Console.print("\r");
            else
                Console.print(toPrint + "|\r");
        }
    }
    
    0 讨论(0)
  • 2020-11-28 01:46

    C# Example but I'm assuming this is the same for System.out.print in Java. Feel free to correct me if I'm wrong.

    Basically, you want to write out the \r escape character to the start of your message which will cause the cursor to return to the start of the line (Line Feed) without moving to the next line.

        static string DisplayBar(int i)
        {
            StringBuilder sb = new StringBuilder();
    
            int x = i / 2;
            sb.Append("|");
            for (int k = 0; k < 50; k++)
                sb.AppendFormat("{0}", ((x <= k) ? " " : "="));
            sb.Append("|");
    
            return sb.ToString();
        }
    
        static void Main(string[] args)
        {
            for (int i = 0; i <= 100; i++)
            {
                System.Threading.Thread.Sleep(200);
                Console.Write("\r{0} {1}% Done", DisplayBar(i), i);
            }
    
            Console.ReadLine();
    
        }
    
    0 讨论(0)
  • 2020-11-28 01:48
    static String progressBar(int progressBarSize, long currentPosition, long startPositoin, long finishPosition) {
        String bar = "";
        int nPositions = progressBarSize;
        char pb = '░';
        char stat = '█';
        for (int p = 0; p < nPositions; p++) {
            bar += pb;
        }
        int ststus = (int) (100 * (currentPosition - startPositoin) / (finishPosition - startPositoin));
        int move = (nPositions * ststus) / 100;
        return "[" + bar.substring(0, move).replace(pb, stat) + ststus + "%" + bar.substring(move, bar.length()) + "]";
    }
    

    enter image description here

    0 讨论(0)
  • 2020-11-28 01:53

    I edited Eoin Campbell's code to java and added formatted progress in percents.

    public static String progressBar(int currentValue, int maxValue) {
        int progressBarLength = 33; //
        if (progressBarLength < 9 || progressBarLength % 2 == 0) {
            throw new ArithmeticException("formattedPercent.length() = 9! + even number of chars (one for each side)");
        }
        int currentProgressBarIndex = (int) Math.ceil(((double) progressBarLength / maxValue) * currentValue);
        String formattedPercent = String.format(" %5.1f %% ", (100 * currentProgressBarIndex) / (double) progressBarLength);
        int percentStartIndex = ((progressBarLength - formattedPercent.length()) / 2);
    
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int progressBarIndex = 0; progressBarIndex < progressBarLength; progressBarIndex++) {
            if (progressBarIndex <= percentStartIndex - 1
            ||  progressBarIndex >= percentStartIndex + formattedPercent.length()) {
                sb.append(currentProgressBarIndex <= progressBarIndex ? " " : "=");
            } else if (progressBarIndex == percentStartIndex) {
                sb.append(formattedPercent);
            }
        }
        sb.append("]");
        return sb.toString();
    }
    
    int max = 22;
    System.out.println("Generating report...");
    for (int i = 0; i <= max; i++) {
       Thread.sleep(100);
       System.out.print(String.format("\r%s", progressBar(i, max)));
    }
    System.out.println("\nSuccessfully saved 32128 bytes");
    

    And output:

    Generating report...
    
    [========      24.2 %             ]
    
    [============  45.5 %             ]
    
    [============  78.8 % =====       ]
    
    [============  87.9 % ========    ]
    
    [============ 100.0 % ============]
    
    Successfully saved 32128 bytes
    
    0 讨论(0)
  • 2020-11-28 01:56

    I have implemented this sort of thing before. Its not so much about java, but what characters to send to the console.

    The key is the difference between \n and \r. \n goes to the start of a new line. But \r is just carriage return - it goes back to the start of the same line.

    So the thing to do is to print your progress bar, for example, by printing the string

    "|========        |\r"
    

    On the next tick of the progress bar, overwrite the same line with a longer bar. (because we are using \r, we stay on the same line) For example:

    "|=========       |\r"
    

    What you have to remember to do, is when done, if you then just print

    "done!\n"
    

    You may still have some garbage from the progress bar on the line. So after you are done with the progress bar, be sure to print enough whitespace to remove it from the line. Such as:

    "done             |\n"
    

    Hope that helps.

    0 讨论(0)
  • 2020-11-28 01:56

    I found the following code to work correctly. It writes bytes to the output buffer. Perhaps that methods using a writer like the System.out.println() method replaces the occurrences of \r to \n to match the target's native line ending(if not configured properly).

    public class Main{
        public static void main(String[] arg) throws Exception {
            String anim= "|/-\\";
            for (int x =0 ; x < 100 ; x++) {
                String data = "\r" + anim.charAt(x % anim.length()) + " " + x;
                System.out.write(data.getBytes());
                Thread.sleep(100);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题