2013-07-17 63 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,我得到了這個結果 - 但爲什麼我工作和我如何適應我的代碼,使其正常工作?

+0

使用'invokeLater'。不要忽略異常。 –

+0

invokeLater只顯示計算過程完成後的輸出,我需要它實時 我忽略只有在這裏的例外,保存幾行 –

回答

2
  • invokeAndWait必須invokeAndWait叫出EDT,否則造成的是例外,

  • 小心,因爲可以凍結整個Swing GUI的,由異常從RepaintManager(並非在所有情況下,只有GUI創建鎖定,重新佈局,更新一些的方法),那麼所需的應用程序重新啓動,

  • invokeAndWait需要在真正的考驗if (EventQueue.isDispatchThread()) {/if (SwingUtilities.isEventDispatchThread()) {你可以setText("")/append(""),無任何毒副作用,輸出是在美國東部時間完成,但大約是好practicies裏面invokeLater

  • 使用SwingWorker,有實現的方法processpublishsetProcessdone包裹,所有提到的方法通知EDT by default

  • SwingWorker被指定爲唯一的一次時間(在某些時間段)運行,對於屢用ExecutorSwingWorkerRunnable#Thread作爲最簡單,清晰,無任何副作用的問題,影響

+0

你可以給出任何例子,你是如何用Executor表示那部分? 我不能在traditionell方式中使用SwingWorker,因爲我必須覆蓋不同JPanel中的所有System.out ....調用。 –

+0

更好地使用SwingWorker的情況下,你從Java基礎類,例如[Executor&SwingWorker](http://stackoverflow.com/search?q=user%3A714968+ [swingworker] +執行者)具有良好的知識,通知執行者是黑洞,缺少一些重要的方法,與SwingWorker相同,意味着Executor不關心被調用的對象,SWingWorker可能只能從PropertyChangeListener – mKorbel

0

您可以使用SwingUtilities.invokeLater()從任何線程,以及錯誤流很可能最好使用它,即使你已經在美國東部時間:

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

您獲得特定錯誤來自於美國東部時間外,並那麼可能會調用invokeAndWait(),以便將輸出傳送到控制檯。

+0

如果我嘗試這個,那麼我只得到輸出後,整個計算過程已完成,但我想要一個實時輸出 –

+1

你在做EDT計算嗎?不要這樣做,請使用SwingWorkers完成繁重任務,以免EDT被阻止。 – kiheru

+0

我不能,我希望ConsoleFrame對於每個System.out.println調用都是佔用的 - 所以我不能在SwingWorker中做這些事情。 –

相關問題