2011-10-29 76 views
50

Quiero imprimir una barra de progreso de esta manera:¿Cómo puedo imprimir en la misma línea?

[#     ] 1% 
[##     ] 10% 
[##########   ] 50% 

pero éstos deben ser impresas todas a la misma línea en la terminal en lugar de uno nuevo. Lo que quiero decir es que cada nueva línea debe reemplazar a la anterior, no se trata de usar print() en lugar de println().

¿Cómo puedo hacer eso en Java?

Respuesta

72

Formato de la cadena de este modo:

[#     ] 1%\r 

nota el carácter \r. Es el llamado retorno de carro que moverá el cursor al principio de la línea.

Por último, asegúrese de usar

System.out.print() 

y no

System.out.println() 
+13

La secuencia de escape de retorno de carro '\ r' no funciona en Eclipse debido a un [error antiguo] (https://bugs.eclipse.org/bugs/show_bug.cgi?id=76936) informado en 2004 y no corregido sin embargo, en la última versión de Eclipse (4.3.2 Kepler) –

+0

¿Esto solo funciona para una línea? –

+0

@Sortofabeginner: en una palabra, sí. – NPE

2

Puede imprimir el carácter de retroceso '\ b' tantas veces como sea necesario para eliminar la línea antes de imprimir la barra de progreso actualizada.

+2

no elimina la línea antes, simplemente mueve el cursor un carácter. – Amndeep7

13

En Linux, hay diferentes secuencias de escape para la terminal de control. Por ejemplo, hay una secuencia de escape especial para borrar toda la línea: \33[2K y para mover el cursor a la línea anterior: \33[1A. Entonces, todo lo que necesita es imprimir esto cada vez que necesite actualizar la línea. Aquí está el código que imprime Line 1 (second variant):

System.out.println("Line 1 (first variant)"); 
System.out.print("\33[1A\33[2K"); 
System.out.println("Line 1 (second variant)"); 

hay códigos para la navegación del cursor, la pantalla de compensación y así sucesivamente.

Creo que hay algunas bibliotecas que ayudan con eso (ncurses?).

+2

He escrito un par de clases de utilidad para automatizar esta tarea para usted; incluyen colorizar la salida también: http://bitbucket.org/dainkaplan/tempura-utils –

10

En primer lugar, me gustaría disculparme por hacer una copia de seguridad de esta pregunta, pero sentí que podría usar otra respuesta.

Derek Schultz es un poco correcto. El carácter '\ b' mueve el cursor de impresión un carácter hacia atrás, lo que le permite sobrescribir el carácter que se imprimió allí (no elimina toda la línea o incluso el carácter que estaba allí a menos que imprima nueva información en la parte superior). El siguiente es un ejemplo de una barra de progreso que usa Java aunque no sigue su formato, sino que muestra cómo resolver el problema central de sobrescribir caracteres (esto solo se ha probado en Ubuntu 12.04 con Oracle 7 de Java en una máquina de 32 bits, pero debería funcionar en todos los sistemas de Java):

public class BackSpaceCharacterTest 
{ 
    // the exception comes from the use of accessing the main thread 
    public static void main(String[] args) throws InterruptedException 
    { 
     /* 
      Notice the user of print as opposed to println: 
      the '\b' char cannot go over the new line char. 
     */ 
     System.out.print("Start[   ]"); 
     System.out.flush(); // the flush method prints it to the screen 

     // 11 '\b' chars: 1 for the ']', the rest are for the spaces 
     System.out.print("\b\b\b\b\b\b\b\b\b\b\b"); 
     System.out.flush(); 
     Thread.sleep(500); // just to make it easy to see the changes 

     for(int i = 0; i < 10; i++) 
     { 
      System.out.print("."); //overwrites a space 
      System.out.flush(); 
      Thread.sleep(100); 
     } 

     System.out.print("] Done\n"); //overwrites the ']' + adds chars 
     System.out.flush(); 
    } 
} 
0
package org.surthi.tutorial.concurrency; 

public class IncrementalPrintingSystem { 
    public static void main(String...args) { 
     new Thread(()-> { 
      int i = 0; 
      while(i++ < 100) { 
       System.out.print("["); 
       int j=0; 
       while(j++<i){ 
        System.out.print("#"); 
       } 
       while(j++<100){ 
        System.out.print(" "); 
       } 
       System.out.print("] : "+ i+"%"); 
       try { 
        Thread.sleep(1000l); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.print("\r"); 
      } 
     }).start(); 
    } 
} 
Cuestiones relacionadas