немедленно получить системный вывод во время выполнения (обновление ProgressBar) Java

Я запускаю команду через runtime.exec, что занимает некоторое время. При этом я хочу обновить свой ProgressBar.
Я уже получаю желаемый системный вывод, но проблема в том, что я получаю все сразу, когда процесс завершен. А не пошагово обновлять свой ProgressBar...

Вот код

public Runtime rt = Runtime.getRuntime();
public Process pp;

  public doit() {
      try {
          pp = rt.exec(a_long_timed_process);
          InputStream is = pp.getErrorStream();
          InputStreamReader isr = new InputStreamReader(is);
          BufferedReader br = new BufferedReader(isr);
          String line = null;
          while ((line = br.readLine()) != null) {
              if (line.contains("In:")) {
                  int a = line.indexOf("In:");              //get a string
                  int b = line.lastIndexOf("%");            //between 
                  String lineout = line.substring(a + 3, b);//"0.00" and "99.99"
                  double nr = Double.parseDouble(lineout);  //make it a double
                  int round = (int) nr;                     //make it a usable int
                  System.out.println(round);
                  myProgressBar.setValue(round);            //UPDATE Progressbar
              }
          }
          pp.waitFor();
      } catch (IOException ex) {
          Logger.getLogger(Sox.class.getName()).log(Level.SEVERE, null, ex);
      } catch (InterruptedException ex) {
          Logger.getLogger(Sox.class.getName()).log(Level.SEVERE, null, ex);
      }
  }

приветствуется любая помощь
Заранее спасибо


person user2145494    schedule 07.03.2013    source источник
comment
Не блокируйте EDT (поток отправки событий) — когда это произойдет, графический интерфейс «зависнет». Вместо вызова Thread.sleep(n) реализуйте Swing Timer для повторяющихся задач или SwingWorker для длительных задач. Дополнительные сведения см. в разделе Параллелизм в Swing.   -  person Andrew Thompson    schedule 08.03.2013


Ответы (2)


Вы должны запустить процесс в другом потоке, если хотите иметь возможность обрабатывать его выходные данные одновременно. Хороший способ сделать это — использовать ProcessBuilder< /а>.

Из документации:

Этот класс используется для создания процессов операционной системы.

[...]

Запустить новый процесс, который использует рабочий каталог и среду по умолчанию, очень просто:

Process p = new ProcessBuilder("myCommand", "myArg").start();

Вот пример, который запускает процесс с измененным рабочим каталогом и средой и перенаправляет стандартный вывод и ошибку для добавления в файл журнала:

ProcessBuilder pb =
  new ProcessBuilder("myCommand", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory(new File("myDir"));
File log = new File("log");
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Process p = pb.start();
assert pb.redirectInput() == Redirect.PIPE;
assert pb.redirectOutput().file() == log;
assert p.getInputStream().read() == -1;

См. также здесь другой пример кода, который можно адаптировать к своим потребностям.

person Thomas    schedule 07.03.2013

Вы видите эффект буферизации вывода в запущенном процессе. Вы ничего не можете с этим поделать в коде Java.

person user207421    schedule 08.03.2013