JAVA однострочный символ выполнения работает в окне вывода NetBeans, но не в CMD - PullRequest
1 голос
/ 14 января 2020

Я хотел иметь однострочный индикатор прогресса CMD, который работал бы не только в CMD после компиляции проекта, но также и в NetBeans OutputWindow, о котором все здесь говорили, просто не работает (по крайней мере, многие Я читал здесь прежде, чем сделал свой собственный индикатор прогресса ниже).

Реальная проблема, почему он не работает нормально в окне вывода NB, связана с System.out.print() вместе с использованием \r, и по чистой случайности я заметил, что когда Thread.sleep() установлен ниже, чем около 250/300, он перестает отвечать при тестировании в NB OutputWindow (он выводит как целое только после остановки кода), но если я увеличу значение, скажем, до этих 300, он начнет работать нормально. И так как мне нужен довольно простой и бесконечно запущенный однострочный индикатор выполнения 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 составляет всего один полный l oop, а затем просто что-то вроде щелчка всей строки без обновления, и я не знаю, почему.

Может кто-нибудь сказать мне, почему мой код выполнения выполняется в окне вывода NetBeans 8, а не в окне CMD системы Win7 x64 после компиляции?

PS: значение переменной cond будет изменено позже (я перепишу эту единственную строку кода, чтобы переменная была определена где-то еще снаружи) в моем коде, как только я хочу, чтобы мой бесконечный индикатор выполнения завершился, так что об этом не стоит беспокоиться (просто говорю, что знаю).

Ответы [ 3 ]

0 голосов
/ 14 января 2020

Я не мог воспроизвести это, но проблема вполне может заключаться в том, что вы очищаете поток с помощью \r, а затем печатаете индикатор выполнения, другими словами, это следует обратить вспять:

Например, эта часть от:

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

до:

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

См. здесь: Индикатор выполнения командной строки в Java

В среде IDE может использоваться отличается PrintStream, когда ваша командная строка, поэтому всегда может вызывать out.flush при каждом вызове print.

0 голосов
/ 14 января 2020

Итак, я сам нашел решение (решение было добавить последний вывод в al oop как полностью пустую строку в длину последней «нормальной» строки вывода) - этот обновленный код теперь работает как в окне вывода NetBeans 8 ( так что можно протестировать его прямо из IDE без необходимости постоянной компиляции при каждом изменении кода), а также, как и ожидалось, в окне CMD, я надеюсь, что это может помочь любому, кто может столкнуться с теми же «проблемами», что и я:

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);
                }
            }
        });
    }
}
0 голосов
/ 14 января 2020

Это работает на моем 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 на моем компьютере, поэтому я не смущен этим :)

...