Je voulais avoir une barre de progression de mise à jour en ligne basée sur des caractères CMD qui fonctionnerait non seulement dans CMD une fois le projet compilé mais aussi dans NetBeans OutputWindow qui, fondamentalement, tout le monde ici disait ne fonctionne tout simplement pas (enfin au moins les nombreux articles que j'ai lus ici avant de faire ma propre barre de progression ci-dessous).

Le vrai problème pour lequel cela ne fonctionne pas normalement dans la fenêtre de sortie NB est avec System.out.print() avec l'utilisation de \r et par pure coïncidence j'ai remarqué que lorsque Thread.sleep() est réglé plus bas que certains 250/300 il cesse de répondre lors des tests dans NB OutputWindow (il ne sort dans son ensemble qu'une fois le code arrêté) mais si j'augmente la valeur, disons à ces 300, il commence à bien fonctionner. Et comme j'ai besoin d'une barre de progression DOS d'une seule ligne assez simple pour informer l'utilisateur que quelque chose se passe et que l'application n'est pas gelée pendant qu'elle fait son travail, elle convient assez bien à mes besoins.

Je l'ai donc fait comme ceci:

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++;
                }
            }
        });
    }
}

Mais à ma grande surprise, lorsque je l'ai compilé et exécuté à partir de la ligne de commande via un fichier .bat, la sortie dans la fenêtre CMD ne fait qu'une boucle complète, puis fait simplement un petit tour de la ligne entière sans mise à jour et je ne sais pas pourquoi.

Quelqu'un peut-il me dire pourquoi mon code de barre de progression s'exécute dans la fenêtre de sortie de NetBeans 8 mais pas dans la fenêtre CMD du système Win7 x64 une fois compilé?

PS: la valeur de la variable cond serait modifiée plus tard (je réécrirai cette seule ligne de code afin que la variable soit définie ailleurs) dans mon code une fois que je veux que ma barre de progression sans fin se termine, donc pas de soucis à ce sujet (juste en disant Je sais).

1
qraqatit 14 janv. 2020 à 01:05

2 réponses

Meilleure réponse

J'ai donc trouvé la solution moi-même (la solution consistait à ajouter la dernière sortie dans une boucle en tant que ligne complètement vierge dans la longueur de la dernière chaîne de sortie "normale") - ce code mis à jour fonctionne maintenant à la fois dans la fenêtre de sortie de NetBeans 8 (donc on peut le tester directement depuis l'IDE sans avoir besoin d'une compilation perpétuelle à chaque changement de code) et aussi comme prévu dans la fenêtre CMD aussi, j'espère que cela peut aider quiconque pourrait rencontrer les mêmes "problèmes" que moi:

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);
                }
            }
        });
    }
}
0
qraqatit 14 janv. 2020 à 01:06

Cela fonctionne sur mon Windows 10. J'ai changé le String character = "-"; tel qu'il affichait â??, mais cela pourrait être dû à mon jeu de caractères standard Windows. Il était un peu difficile de voir que le curseur redémarre au début et imprime la même chose encore et encore, j'ai donc également inclus ceci:

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

Dans mon CMD (invite de commande), il commence par ceci:

Extracting...please, wait

Puis quelques secondes plus tard, il commence à imprimer le premier - (mise à jour de la ligne, il n'y a qu'une seule ligne, pas 3 comme ci-dessous. J'essaie juste de montrer la progression):

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

Puis il continue d'ajouter environ 3 par seconde jusqu'à ce qu'il y en ait 15 et il ressemble à ceci

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

Puis (à cause de mon changement) ça commence à ressembler à ça

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

Lorsque tous les - sont écrasés, tout recommence avec l'écriture de -

Je suis désolé que mon ajout ne fonctionne pas dans vos NetBeans. Je ne l'ai fait que pour voir qu'il continue de se mettre à jour et je n'ai pas aimé le â??. Avant tous les graphiques, j'ai remarqué quelques installations utilisant - \ | / - pour donner l'impression que la ligne tournait, un peu comme ceci :

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

Je pense que votre programme est une fonctionnalité d'attente vraiment soignée. Je ai été impressionné.

(Je n'ai pas NetBeans ou Eclipse ou tout autre IDE sur mon ordinateur pour le moment, donc je ne suis pas confus à ce sujet :)

0
Scratte 14 janv. 2020 à 13:52