2009-06-16 39 views
31

¿Hay alguna manera fácil de implementar un porcentaje variable para un proceso en Java, que se mostrará en la consola? Tengo un tipo de datos porcentuales (doble) que generé durante un proceso en particular, pero ¿puedo forzarlo a la ventana de la consola y hacer que se actualice, en lugar de simplemente imprimir una nueva línea para cada nueva actualización del porcentaje? Estaba pensando en presionar un cls y actualizar, porque estoy trabajando en un entorno Windows, pero esperaba que Java tuviera algún tipo de capacidad incorporada. ¡Todas las sugerencias fueron bienvenidas! ¡Gracias!Progreso basado en la consola en Java

+1

Para el registro, una pregunta más antigua estrechamente relacionados: http://stackoverflow.com/questions/852665/command-line-progress-bar-in-java – Jonik

Respuesta

51

Puede imprimir un retorno de carro \r para poner el cursor hasta el principio de la línea.

Ejemplo:

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

Sólo traté de que . No funciona (Probado en Eclipse.) –

+0

@David Johnstone: El ejemplo anterior funciona al menos en las ventanas de consola tradicionales. – laalto

+0

@laalto: Sí, lo probé en una ventana de consola normal y funcionó para mí. – Michael

6

No creo que haya una capacidad incorporada para hacer lo que estás buscando.

Hay una biblioteca que lo hará (JLine).

ver este tutorial

4

Estoy bastante seguro de que no hay manera de cambiar cualquier cosa que la consola ya ha impreso porque Java considera la consola (salida estándar) a ser un PrintStream.

2

No sé nada de nada incorporado en Java, pero puede usar los códigos de control de terminal para hacer cosas como reposicionar el cursor. Algunos detalles aquí: http://www.termsys.demon.co.uk/vtansi.htm

0

Borrar la consola ejecutando el comando específico del sistema operativo y luego imprimir el nuevo porcentaje

8

utilizo siguiente código:

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

El resultado: enter image description here

+2

¡Guau! ¡Gracias! Para mí, trabajar realmente bien y mejor que una respuesta marcada. –

+0

Solo una nota para otros, si comienzas tu ciclo for con 'i = 0', entonces puedes obtener una IllegalArgumentException de este código. De lo contrario funciona un encanto. –

+1

Esto no pareció funcionar correctamente para mí.Lo copié exactamente, y en lugar de que la barra de progreso permanezca en la misma línea, imprimió nuevas líneas para cada uno. – 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

esto se muestra en la línea SINGLE en la consola java – Elphara77

+0

y en la consola eclipse – Elphara77

0

tarde a la fiesta, pero aquí hay una respuesta:

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

recuerde utilizar System.out.print() en lugar de System.out.println()

Cuestiones relacionadas