如何打印到同一行?

时间:2021-07-06 21:00:16

I want to print a progress bar like so:

我想打印一个进度条:

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

But these should all be printed to the same line in the terminal instead of a new one. What I mean by that is that each new line should replace the previous, it's not about using print() instead of println().

但这些都应该打印到终端的同一行,而不是一个新的。我的意思是,每个新行都应该替换前一行,而不是使用print()而不是println()。

How can I do that in Java?

在Java中我怎么做呢?

5 个解决方案

#1


74  

Format your string like so:

将字符串格式化如下:

[#                    ] 1%\r

Note the \r character. It is the so-called carriage return that will move the cursor back to the beginning of the line.

注意\ r字符。所谓的“回车”将光标移回行首。

Finally, make sure you use

最后,确保使用。

System.out.print()

and not

而不是

System.out.println()

#2


13  

In Linux, there is different escape sequences for control terminal. For example, there is special escape sequence for erase whole line: \33[2K and for move cursor to previous line: \33[1A. So all you need is to print this every time you need to refresh the line. Here is the code which prints Line 1 (second variant):

在Linux中,控制终端有不同的转义序列。例如,有一个特殊的转义序列用于擦除整行:\33[2K]和将光标移到前一行:\33[1A]。所以你只需要在每次需要刷新行时打印出来。这是打印第1行(第二种变体)的代码:

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

There are codes for cursor navigation, clearing screen and so on.

有游标导航、清除屏幕等代码。

I think there are some libraries which helps with it (ncurses?).

我认为有一些图书馆可以帮助它(ncurses?)

#3


10  

First, I'd like to apologize for bringing this question back up, but I felt that it could use another answer.

首先,我很抱歉把这个问题提出来了,但是我觉得它可以用另一个答案。

Derek Schultz is kind of correct. The '\b' character moves the printing cursor one character backwards, allowing you to overwrite the character that was printed there (it does not delete the entire line or even the character that was there unless you print new information on top). The following is an example of a progress bar using Java though it does not follow your format, it shows how to solve the core problem of overwriting characters (this has only been tested in Ubuntu 12.04 with Oracle's Java 7 on a 32-bit machine, but it should work on all Java systems):

德里克·舒尔茨是对的。“\b”字符将打印光标的一个字符向后移动,允许您覆盖打印在那里的字符(除非您在上面打印新的信息,否则它不会删除整个行,甚至是那里的字符)。下面是一个例子,一个进度条使用Java虽然不跟随你的格式,它显示了如何解决核心问题覆盖字符(只有经过测试与甲骨文的Ubuntu 12.04 Java 7在32位机器上,但它应该工作在所有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();
    }
}

#4


2  

You could print the backspace character '\b' as many times as necessary to delete the line before printing the updated progress bar.

在打印更新的进度条之前,您可以根据需要多次打印回发字符“\b”,以删除行。

#5


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

#1


74  

Format your string like so:

将字符串格式化如下:

[#                    ] 1%\r

Note the \r character. It is the so-called carriage return that will move the cursor back to the beginning of the line.

注意\ r字符。所谓的“回车”将光标移回行首。

Finally, make sure you use

最后,确保使用。

System.out.print()

and not

而不是

System.out.println()

#2


13  

In Linux, there is different escape sequences for control terminal. For example, there is special escape sequence for erase whole line: \33[2K and for move cursor to previous line: \33[1A. So all you need is to print this every time you need to refresh the line. Here is the code which prints Line 1 (second variant):

在Linux中,控制终端有不同的转义序列。例如,有一个特殊的转义序列用于擦除整行:\33[2K]和将光标移到前一行:\33[1A]。所以你只需要在每次需要刷新行时打印出来。这是打印第1行(第二种变体)的代码:

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

There are codes for cursor navigation, clearing screen and so on.

有游标导航、清除屏幕等代码。

I think there are some libraries which helps with it (ncurses?).

我认为有一些图书馆可以帮助它(ncurses?)

#3


10  

First, I'd like to apologize for bringing this question back up, but I felt that it could use another answer.

首先,我很抱歉把这个问题提出来了,但是我觉得它可以用另一个答案。

Derek Schultz is kind of correct. The '\b' character moves the printing cursor one character backwards, allowing you to overwrite the character that was printed there (it does not delete the entire line or even the character that was there unless you print new information on top). The following is an example of a progress bar using Java though it does not follow your format, it shows how to solve the core problem of overwriting characters (this has only been tested in Ubuntu 12.04 with Oracle's Java 7 on a 32-bit machine, but it should work on all Java systems):

德里克·舒尔茨是对的。“\b”字符将打印光标的一个字符向后移动,允许您覆盖打印在那里的字符(除非您在上面打印新的信息,否则它不会删除整个行,甚至是那里的字符)。下面是一个例子,一个进度条使用Java虽然不跟随你的格式,它显示了如何解决核心问题覆盖字符(只有经过测试与甲骨文的Ubuntu 12.04 Java 7在32位机器上,但它应该工作在所有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();
    }
}

#4


2  

You could print the backspace character '\b' as many times as necessary to delete the line before printing the updated progress bar.

在打印更新的进度条之前,您可以根据需要多次打印回发字符“\b”,以删除行。

#5


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