1

I wanted to have CMD character-based one-line-updating progressbar that would work not only in CMD once project is compiled but also in NetBeans OutputWindow which basically everybody here was saying simply does not work (well at least those many post I read here before I made my own progressbar below).

The real problem why it does not work normally in NB output window is with System.out.print() together with using \r and by pure coincidence I noticed that when Thread.sleep() is set lower than some 250/300 it stops responding when testing in NB OutputWindow (it outputs as whole only once the code is stopped) but if I increase the value let's say to those 300 it starts work nicely. And as I need quite simple endlessly running DOS one-line progressbar just to let user know something is going on and that the app is not frozen while it is doing its stuff, it suits my needs pretty well.

So I made it like this:

package jthndemo;

import java.io.PrintStream;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;

public class JthnDEMO {

    public static void main(final String[] args) throws InterruptedException {
        SwingUtilities.invokeLater(() -> {
            PrintStream out = System.out;
            int pause = 300;
            int progressbarLength = 15;
            boolean cond = true;
            String txt = "Extracting...please, wait ";
            String character = "█";
            String str = null;
            while (cond) {
                int i = 0;
                str = txt;
                out.print("\r" + str + character);
                try {
                    Thread.sleep(pause);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JthnDEMO.class.getName()).log(Level.SEVERE, null, ex);
                }
                while (i < progressbarLength) {
                    str = txt;
                    for (int j = 0; j < i + 1; j++) {
                        str += character;
                    }
                    out.print("\r" + str);
                    try {
                        Thread.sleep(pause);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(JthnDEMO.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    i++;
                }
            }
        });
    }
}

But to my big surprise when I compiled it and run it from command line via .bat file the output in CMD window makes just one full loop and then just kind-of flicking the whole line without updating and I do not know why.

Can anyone tell me why my progressbar code runs in NetBeans 8 output window but not in Win7 x64 system CMD window once compiled?

P.S.: the value of variable cond would be changed later (I will rewrite that single line of code so that the variable is defined somewhere else outside) in my code once I want my endless progressbar to end, so no worries about that (just saying I know).

qraqatit
  • 492
  • 4
  • 14
  • Your try/catch blocks are not needed, since your `main` method is declared to throw InterruptedException (which is a good practice). The try/catch is just visual noise. – VGR Jan 14 '20 at 12:50
  • Go tell it to NetBans 8 as it does take it as error unless I add it there... – qraqatit Jan 16 '20 at 14:36

3 Answers3

0

It works on my Windows 10. I changed the String character = "-"; as it was displaying â??, but this might just be due to my Windows standard CharacterSet. It was a little tricky to see that the cursor restarts at the beginning and prints the same thing again and again, so I also included this:

if (character.equals("-")) {
  character = " "; 
} else {
  character = "-";
}
while (i < progressbarLength) { ..snip..

In my CMD (Command Prompt) it start with this:

Extracting...please, wait

Then a few seconds later it starts to print the first - (updating the line, there is ONLY one line, not 3 like below. I'm just trying to show the progress):

Extracting...please, wait -
Extracting...please, wait --
Extracting...please, wait ---

then it keeps adding -'s about 3 per second until there are 15 of them and it looks like this

Extracting...please, wait ---------------

Then (due to my change) it starts to look like this

Extracting...please, wait  --------------
Extracting...please, wait   -------------
Extracting...please, wait    ------------
Extracting...please, wait     -----------

When all the - are overwritten, it just starts over with writing -'s

I'm sorry that my addition isn't working in your NetBeans. I only did it to see that it really keeps updating, and I didn't like the â??. Back before all the graphics, I noticed some installations using - \ | / - to make it look like the line was spinning, sort of like this:

---------------
\--------------
-|-------------
--/------------
---------------
----\----------

I think your program is a really neat waiting feature. I was impressed.

(I don't have NetBeans or Eclipse or any other IDE on my computer at the moment, so I'm not confused about that :)

Scratte
  • 3,056
  • 6
  • 19
  • 26
  • that is strange, so you are saying it works for you once compiled and output in CMD window (that is outside NetBeans)? BTW your addition made the code less responsive and it introduced long periods of gap in NetBeans output window = not good (that is no progressbar for a long period, just text), as for the character - it is just a full filled square :D – qraqatit Jan 13 '20 at 22:50
  • Yes. That's what I'm saying. I've updated my answer. – Scratte Jan 14 '20 at 13:24
0

I couldn't reproduce this, but the issue could very well be that you are flushing the stream with \r and then print the progressbar, in other words this should be reversed:

E.g. this part from:

out.print("\r" + str);

to:

out.print(str + "\r");

See here: Command line progress bar in Java

The IDE might use a different PrintStream when your command line, therefore might always call out.flush on every call to print.

Dennis K
  • 113
  • 7
  • `out.print(str + "\r");` - no no, definitely not: it completely messed progressbar output (just try it yourself), besides maybe you did not read my post carefully where I said progressbar that **WORKS INSIDE NETBEANS OUTPUTWINDOW** which the one you gave link for does not, of course + how should I interpret your sentence "I couldn't reproduce this"? Does it mean that when you compiled my code it worked for you in CMD window? – qraqatit Jan 14 '20 at 00:17
  • There is another erronous `\r` in your code. As for couldn't reproduce: simply it works on my machine when I call it in IntelliJ and through the console. I won't install Netbeans just to test this there if it works already in the console (W10). – Dennis K Jan 14 '20 at 00:54
  • sorry but then this is of no help at all as one of the main reasons for my code was exactly the fact it works in NetBeans output window too, that been said I really do not understand why did you post your solution then? Nevermind as I already find out myself... – qraqatit Jan 14 '20 at 01:02
0

So, I found solution myself (solution was to add last output in a loop as completely blank line in the length of the last "normal" output string) - this updated code now works both in NetBeans 8 output window (so one can test it right from the IDE without need of perpetual compiling with every change to code) and also as expected in CMD window too, I hope this may help anyone who might run into same "problems" as I did:

package jthndemo;

import java.io.PrintStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.SwingUtilities;

public class JthnDEMO {

    public static void main(final String[] args) throws InterruptedException {
        SwingUtilities.invokeLater(() -> {
            PrintStream out = System.out;
            int pause = 300;
            int progressbarLength = 15;
            boolean cond = true;
            String txt = "Extracting...please, wait ";
            String character = "█";
            String str = null;
            while (cond) {
                int i = 0;
                str = txt;
                out.print("\r" + str + character);
                try {
                    Thread.sleep(pause);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JthnDEMO.class.getName()).log(Level.SEVERE, null, ex);
                }
                while (i < progressbarLength) {
                    str = txt;
                    for (int j = 0; j < i + 1; j++) {
                        str += character;
                    }
                    out.print("\r" + str);
                    try {
                        Thread.sleep(pause);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(JthnDEMO.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    i++;
                }
                String blank = "";
                for (int k = 0; k < str.length(); k++) {
                    blank += " ";
                }
                out.print("\r" + blank);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JthnDEMO.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
}
qraqatit
  • 492
  • 4
  • 14
  • 2
    I think this is a better solution than my edition. +1 on your Question for posting something that compiles. – Scratte Jan 14 '20 at 13:41