JAVA 单行字符进度条在 NetBeans 输出中有效 window 但在 CMD 中无效

JAVA one-line character progressbar works in NetBeans output window but not in CMD

我想要基于 CMD 字符的单行更新进度条,它不仅可以在编译项目后在 CMD 中使用,而且可以在 NetBeans OutputWindow 中使用,基本上这里的每个人都说根本不起作用(好吧至少那些许多 post 在我自己制作下面的进度条之前,我在这里阅读了很多)。

为什么它在 NB 输出 window 中不能正常工作的真正问题是 System.out.print()\r 一起使用,纯属巧合,我注意到当 Thread.sleep()设置为低于 250/300 时它会在 NB OutputWindow 中测试时停止响应(它仅在代码停止后才输出整体)但是如果我增加值让我们说到那些 300 它开始工作得很好。由于我无休止地需要相当简单的 运行ning DOS 单行进度条,只是为了让用户知道正在发生的事情,并且该应用程序在执行其操作时不会被冻结,所以它非常适合我的需求。

所以我是这样的:

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

但令我惊讶的是,当我编译它并通过 .bat 文件从命令行 运行 它时,CMD window 中的输出只做了一个完整的循环,然后只是轻弹一下整行没有更新,我不知道为什么。

谁能告诉我为什么我的进度条代码 运行s 在 NetBeans 8 输出 window 而不是在 Win7 x64 系统 CMD window 编译后?

P.S.: 变量 cond 的值稍后会在我的代码中更改(我将重写那一行代码,以便变量在其他地方定义)在我的代码中一旦我想要我无尽的进度条结束,所以不用担心(只是说我知道)。

它适用于我的 Windows 10。我更改了 String character = "-";,因为它显示 â??,但这可能只是由于我的 Windows 标准字符集。看到光标在开头重新启动并一次又一次地打印相同的东西有点棘手,所以我也包括了这个:

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

在我的 CMD(命令提示符)中,它是这样开头的:

Extracting...please, wait

然后几秒钟后它开始打印第一个 - (更新行,只有一行,而不是下面的 3 行。我只是想显示进度):

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

然后它不断添加 - 大约每秒 3 个,直到有 15 个,看起来像这样

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

然后(由于我的改变)它开始看起来像这样

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

当所有 - 都被覆盖后,它只是从写 -

开始

很抱歉,我添加的内容在您的 NetBeans 中不起作用。我才看到它真的一直在更新,我不喜欢â??。回到所有图形之前,我注意到一些安装使用 - \ | / - 使它看起来像线在旋转,有点像这样:

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

我认为您的程序是一个非常巧妙的等待功能。我印象深刻。

(目前我的计算机上没有 NetBeans 或 Eclipse 或任何其他 IDE,所以我对此并不感到困惑 :)

我无法重现这个,但问题很可能是你用 \r 刷新流然后打印进度条,换句话说,这应该是相反的:

例如此部分来自:

out.print("\r" + str);

至:

out.print(str + "\r");

看这里:Command line progress bar in Java

IDE 可能会在您的命令行中使用不同的 PrintStream,因此每次调用 print.

时可能总是调用 out.flush

所以,我自己找到了解决方案(解决方案是在最后一个 "normal" 输出字符串的长度中将循环中的最后一个输出添加为完全空白行)- 这个更新的代码现在可以在 NetBeans 8 输出中使用window(因此可以直接从 IDE 开始测试它,而无需对代码的每次更改进行永久编译)并且也符合 CMD window 中的预期,我希望这可以帮助任何人可能 运行 变成和我一样的 "problems":

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