2013-08-12 4 views
1

Я пытаюсь использовать пользовательский выходной поток для отображения вывода из исполняемого файла в области Jtext.JAVA - Внешняя блокировка exe при вызове из пусковой установки

Исполняемый вызывается с помощью кнопки с помощью

 try { 
      Process p = Runtime.getRuntime().exec("cgminer.exe" + " -o " + Infos.Address + ":" + Infos.Port + " -u " + Infos.User + " -p " + Infos.Password); 
      p.waitFor(); 

      String line; 

      BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
      while((line = error.readLine()) != null){ 
       System.out.println(line); 
      } 
      error.close(); 

      BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
      while((line=input.readLine()) != null){ 
       System.out.println(line); 
      } 

      input.close(); 

      OutputStream outputStream = p.getOutputStream(); 
      PrintStream printStream = new PrintStream(outputStream); 
      printStream.println(); 
      printStream.flush(); 
      printStream.close(); 
     } 
      catch (Exception e) { 
       // ... 
       } 
    } 

} 

, а затем выход направлен на JText с

public class CustomOutputStream extends OutputStream { 
    private JTextArea textArea; 

    public CustomOutputStream(JTextArea textArea) { 
     this.textArea = textArea; 
    } 

    @Override 
    public void write(int b) throws IOException { 
     textArea.append(String.valueOf((char) b)); 
     textArea.setCaretPosition(textArea.getDocument().getLength()); 
    } 
} 

Моя проблема заключается, когда я звоню в первый класс на кнопку блокировки и нет вывод делает его в jtext. Только когда я принудительно закрываю cgminer, появится выход.

Любая помощь действительно оценена, так как у меня мозг извращен.

ответ

3

Моя проблема в том, что я вызываю первый класс, который блокирует кнопки, и никакой выход не делает его в jtext. Только когда я принудительно закрываю cgminer, появится выход.

Это классический симптом связывания потока событий Swing. При запуске затянувшегося куска коды на резьбе Качелей событий (также известную как EDT или E вентиляционного D ispatch T hread), можно предотвратить нить от выполнения своих хозяйственных работ, включая покраску GUI и взаимодействуя с пользователем, эффективно «замораживая» графический интерфейс.

Решение не должно комментировать waitFor() в качестве другого предлагаемого, а скорее для запуска его и любого другого кода блокировки в фоновом потоке, таком как SwingWorker. Когда вы это сделаете, обязательно позаботите только обновить свой графический интерфейс Swing в потоке событий. SwingWorker имеет встроенный способ сделать это с помощью своих методов публикации и обработки.

Для получения дополнительной информации по этому вопросу, пожалуйста, ознакомьтесь с Concurrency in Swing

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

+1

Не работает внешний процесс по определению во внешнем, ну, процессе? Не нужно создавать его в отдельном потоке, 'exec()' должен немедленно возвращаться. (Чтение всего его результата, однако, должно исчезнуть с EDT. Я также не имею в виду, что поток 'write()' работает при выводе подпроцесса в пользовательский 'OutputStream'.) – millimoose

+0

@millimoose: извините, Конечно, конечно. Сам процесс не будет блокироваться, но 'waitFor()' и 'while (...)' loops будут. Исправление ... ... и спасибо! –

+1

+1 для обновления; также рассмотрим «ProcessBuilder»; для удобства, [* начальная нить *] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html) доступна для дренирования потоков ввода-вывода, если графический интерфейс обновлен на ПО ВОСТОЧНОМУ ВРЕМЕНИ. – trashgod

Смежные вопросы