2009-06-16 6 views
31

Y a-t-il un moyen facile d'implémenter un pourcentage de roulement pour un processus en Java, à afficher dans la console? J'ai un pourcentage de type de données (double) que j'ai généré pendant un processus particulier, mais puis-je le forcer à la fenêtre de la console et l'actualiser, au lieu de simplement imprimer une nouvelle ligne pour chaque nouvelle mise à jour? Je pensais à pousser un cls et mettre à jour, parce que je travaille dans un environnement Windows, mais j'espérais que Java avait une sorte de capacité intégrée. Toutes les suggestions accueillies! Merci!Progression basée sur la console en Java

+1

Pour mémoire, une question plus étroitement liée: http://stackoverflow.com/questions/852665/command-line-progress-bar-in-java – Jonik

Répondre

51

Vous pouvez imprimer un retour chariot \r pour mettre le curseur au début de la ligne.

Exemple:

public class ProgressDemo { 
    static void updateProgress(double progressPercentage) { 
    final int width = 50; // progress bar width in chars 

    System.out.print("\r["); 
    int i = 0; 
    for (; i <= (int)(progressPercentage*width); i++) { 
     System.out.print("."); 
    } 
    for (; i < width; i++) { 
     System.out.print(" "); 
    } 
    System.out.print("]"); 
    } 

    public static void main(String[] args) { 
    try { 
     for (double progressPercentage = 0.0; progressPercentage < 1.0; progressPercentage += 0.01) { 
     updateProgress(progressPercentage); 
     Thread.sleep(20); 
     } 
    } catch (InterruptedException e) {} 
    } 
} 
+5

Je viens essayé . Ça ne marche pas. (Testé dans Eclipse.) –

+0

@David Johnstone: L'exemple ci-dessus fonctionne au moins dans les fenêtres de console traditionnelles. – laalto

+0

@laalto: Yup, essayé dans une fenêtre de console normale et cela a fonctionné pour moi. – Michael

6

Je ne pense pas qu'il existe une fonctionnalité intégrée pour faire ce que vous cherchez.

Il existe une bibliothèque qui le fera (JLine).

Voir cette tutorial

4

Je suis tout à fait sûr qu'il n'y a pas moyen de changer quoi que ce soit que la console a déjà imprimé parce que Java considère la console (sortie standard) être un PrintStream.

2

Je ne connais rien à ce qui est intégré à java, mais vous pouvez utiliser les codes de contrôle de terminal pour faire des choses comme repositionner le curseur. Quelques détails ici: http://www.termsys.demon.co.uk/vtansi.htm

0

Effacer la console en exécutant la commande spécifique os puis imprimer le nouveau pourcentage

8

J'utilise le code suivant:

public static void main(String[] args) { 
    long total = 235; 
    long startTime = System.currentTimeMillis(); 

    for (int i = 1; i <= total; i = i + 3) { 
     try { 
      Thread.sleep(50); 
      printProgress(startTime, total, i); 
     } catch (InterruptedException e) { 
     } 
    } 
} 


private static void printProgress(long startTime, long total, long current) { 
    long eta = current == 0 ? 0 : 
     (total - current) * (System.currentTimeMillis() - startTime)/current; 

    String etaHms = current == 0 ? "N/A" : 
      String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta), 
        TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1), 
        TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1)); 

    StringBuilder string = new StringBuilder(140); 
    int percent = (int) (current * 100/total); 
    string 
     .append('\r') 
     .append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " "))) 
     .append(String.format(" %d%% [", percent)) 
     .append(String.join("", Collections.nCopies(percent, "="))) 
     .append('>') 
     .append(String.join("", Collections.nCopies(100 - percent, " "))) 
     .append(']') 
     .append(String.join("", Collections.nCopies(current == 0 ? (int) (Math.log10(total)) : (int) (Math.log10(total)) - (int) (Math.log10(current)), " "))) 
     .append(String.format(" %d/%d, ETA: %s", current, total, etaHms)); 

    System.out.print(string); 
} 

Le résultat: enter image description here

+2

Wow! Merci! Pour moi, travailler vraiment bien et mieux, que la réponse marquée. –

+0

Juste une note pour les autres, si vous lancez votre boucle for avec 'i = 0', vous obtiendrez peut-être une exception IllegalArgumentException à partir de ce code. Sinon, fonctionne un charme. –

+1

Cela ne semble pas fonctionner correctement pour moi.Je l'ai copié exactement, et au lieu que la barre de progression reste sur la même ligne, elle a imprimé de nouvelles lignes pour chacun. – jeshbreadnan

0
import java.util.Random; 

public class ConsoleProgress { 

    private static String CURSOR_STRING = "0%.......10%.......20%.......30%.......40%.......50%.......60%.......70%.......80%.......90%.....100%"; 

    private static final double MAX_STEP = CURSOR_STRING.length() - 1; 

    private double max; 
    private double step; 
    private double cursor; 
    private double lastCursor; 

    public static void main(String[] args) throws InterruptedException { 
     // --------------------------------------------------------------------------------- 
     int max = new Random().nextInt(400) + 1; 
     // --------------------------------------------------------------------------------- 
     // Example of use : 
     // --------------------------------------------------------------------------------- 
     ConsoleProgress progress = new ConsoleProgress("Progress (" + max + ") : ", max); 
     for (int i = 1; i <= max; i++, progress.nextProgress()) { 
      Thread.sleep(3L); // a task with no prints 
     } 
    } 

    public ConsoleProgress(String title, int maxCounts) { 
     cursor = 0.; 
     max = maxCounts; 
     step = MAX_STEP/max; 
     System.out.print(title); 
     printCursor(); 
     nextProgress(); 
    } 

    public void nextProgress() { 
     printCursor(); 
     cursor += step; 
    } 

    private void printCursor() { 
     int intCursor = (int) Math.round(cursor) + 1; 
     System.out.print(CURSOR_STRING.substring((int) lastCursor, intCursor)); 
     if (lastCursor != intCursor && intCursor == CURSOR_STRING.length()) 
      System.out.println(); // final print 
     lastCursor = intCursor; 
    } 
} 
+0

ceci est montré sur la ligne SIMPLE dans la console de Java – Elphara77

+0

aussi bien dans la console d'éclipse – Elphara77

0

dernière minute pour le parti, mais voici une réponse:

public static String getSingleLineProgress(double progress) { 
    String progressOutput = "Progress: |"; 
    String padding = Strings.padEnd("", (int) Math.ceil(progress/5), '='); 
    progressOutput += Strings.padEnd(padding, 0, ' ') + df.format(progress) + "%|\r"; 
    if (progress == 100.0D) { 
     progressOutput += "\n"; 
    } 
    return progressOutput; 
} 

Rappelez-vous d'utiliser System.out.print() au lieu de System.out.println()

Questions connexes