2013-07-17 3 views
3

У меня есть «ConsoleFrame», который должен отображать мой консольный вывод в реальном времени на JTextArea.JTextArea в другом дисплее консоли JFrame в реальном времени

Я перенаправлен выходные потоки:

private void redirectSystemStreams() { 
    OutputStream out = new OutputStream() { 
     @Override 
     public void write(int b) throws IOException { 
      updateTextArea(String.valueOf((char) b)); 
     } 

     @Override 
     public void write(byte[] b, int off, int len) throws IOException { 
      updateTextArea(new String(b, off, len)); 
     } 

     @Override 
     public void write(byte[] b) throws IOException { 
      write(b, 0, b.length); 
     } 
    }; 

    System.setOut(new PrintStream(out, true)); 
    System.setErr(new PrintStream(out, true)); 
} 

и вызовите SwingUtilities.invokeAndWait метод, чтобы добавить новый текст, который работает мелкого

private void updateTextArea(final String text) { 
    try { 
     SwingUtilities.invokeAndWait(new Runnable() { 
      @Override 
      public void run() { 
       txt_console.append(text); 
      } 
     }); 
    } catch (InterruptedException ex) { 
    } catch (InvocationTargetException ex) { 
    } 
} 

но он показывает мне в моем новом ConsoleFrame эта ошибка: java.lang.Error: Не удается вызвать invokeAndWait из потока диспетчера событий , и я получаю это из-за EDT - но почему я t и как я могу адаптировать свой код, чтобы он работал правильно?

+0

Используйте 'invokeLater'. Не игнорируйте исключения. –

+0

invokeLater просто показывает мне результат ПОСЛЕ завершения процесса вычисления, мне нужно это в реальном времени Я игнорирую исключения только здесь, чтобы сохранить несколько строк –

ответ

2
  • invokeAndWait должен быть вызван из EDT, в противном случае вызывается я исключение,

  • осторожно invokeAndWait, потому что может заморозить весь графический интерфейс Swing, запертые исключениями из RepaintManager (не во всех случаях создаются только GUI , relayout, обновились некоторые из методов), то требуется применение перезагрузки,

  • для invokeAndWait требуется проверить if (EventQueue.isDispatchThread()) {/if (SwingUtilities.isEventDispatchThread()) { по истине вы можете setText("")/append("") без каких-либо побочных эффектов, выход выполняется на EDT, но о хороших practicies, чтобы обернуть внутри invokeLater

  • использование SwingWorker, там реализуются методы process, publish, setProcess и done, все упомянутые методы уведомлен EDT by default,

  • SwingWorker предназначен для работы только один раз время для repeatly (на какой-то период) использовать Executor для SwingWorker или Runnable#Thread как наиболее простой, ясный и без каких-либо побочных проблем, эффекты

+0

Можете ли вы привести какой-нибудь пример, как y означает эту часть с Исполнителем? Я не могу использовать SwingWorker в традиционном стиле, потому что я должен покрывать все вызовы System.out .... в разных JPanels. –

+0

лучше использовать SwingWorker в случае, если у вас есть хорошие знания из Java Essential Classes, например [Executor & SwingWorker] (http://stackoverflow.com/search?q=user%3A714968+ [swingworker] + исполнитель), уведомление Исполнитель черная дыра, отсутствует несколько важных методов, то же самое с SwingWorker, означает, что Executor не заботится о вызываемом объекте, SWingWorker можно прослушивать только из PropertyChangeListener – mKorbel

0

Вы можете использовать SwingUtilities.invokeLater() из любого потока, и для ошибок поток, вероятно лучше использовать его даже тогда, когда вы уже в EDT:

private void updateTextArea(final String text) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      txt_console.append(text); 
     } 
    }); 
} 

Эта конкретная ошибка, которую вы получаете приходит из-за пределов EDT, и то можно вызвать invokeAndWait(), чтобы вы получили вывод на консоль.

+0

, если я попробую это, тогда я получаю только результат ПОСЛЕ завершения всего процесса вычисления, но я хочу выход в реальном времени –

+1

Выполняете ли вы расчет в EDT? Не делайте этого, используйте SwingWorkers для выполнения тяжелых задач, чтобы EDT не блокировался. – kiheru

+0

Я не могу, я хочу, чтобы ConsoleFrame был perminant для каждого вызова System.out.println. Поэтому я не могу делать вещи в SwingWorker. –