2014-12-30 31 views
1

我正在使用Java創建一個UDP對等聊天程序。在while循環中更新我的textArea

沒有這個while循環我的textarea

while(true) 
    { 
     DatagramPacket incoming = new DatagramPacket(buffer, buffer.length); 
     try { 
      serverSocket.receive(incoming); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


     String incomingMessage = new String (incoming.getData()); 
     textArea.setText("Client: " + incomingMessage); 
     System.out.println(incomingMessage); 
     textArea.setText("Client: " + incomingMessage); 
    } 

隨着while循環我的textarea母鹿不更新,我已經用在那裏的調用嘗試:

    java.awt.EventQueue.invokeLater(new Runnable() { public void run() { 
        try { 
          textArea.append(msg); 

但它似乎並沒有繼續工作。

我使用Eclipse月神窗口的核心建設者,它會自動做出這種自動化代碼

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       Server window = new Server(); 
       window.frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

這是一個被寫入自動化的代碼,並通過查看API,這將更新GUI幾乎每通常取決於事件。

但是,它不能在while循環中更新,因爲沒有事件。

我該如何解決這個問題,謝謝。

+0

運行一個例子, while(true)在單獨的線程中並在邏輯中包裝SwingUtilities中的textArea更改。invokeAndWait() – StanislavL

+0

「我可以看到你正在使用一個線程,並且該線程被阻塞,因爲你的進程沒有進入睡眠狀態,請嘗試睡眠一段時間或者使用多個線程。」 [@maframaran](http://stackoverflow.com/users/4405606/maframaran) – Werner

回答

3

您需要尊重Swing線程規則,這些規則太簡單地總結意味着所有正在運行的任務(例如等待和捕獲數據)應該在後臺線程中完成,並且所有Swing調用都應該在Swing事件上完成線。使用SwingWorker<Void, String>來幫助你做到這一點。

請查看Concurrency in Swing查看包含所有血腥細節的教程。

例如,

private class MySwingWorker extends SwingWorker<Void, String> { 
    private byte[] buffer = new byte[2000]; 

    @Override 
    protected Void doInBackground() throws Exception { 
    while (true) { 
     DatagramPacket incoming = new DatagramPacket(buffer, buffer.length); 
     serverSocket.receive(incoming); 

     String incomingMessage = new String(incoming.getData()); 
     publish(incomingMessage); 
    } 
    return null; 
    } 

    @Override 
    protected void process(List<String> chunks) { 
    for (String chunk : chunks) { 
     textArea.append("Client: " + chunk + "\n"); 
    } 
    } 
} 

其他建議:

  • 你在打電話的SwingWorker到​​運行它。
  • 我幾乎總是在執行之前向我的工作人員添加PropertyChangeListener。
  • 在這個監聽器中,我注意到newValue是SwingWorker.StateValue.DONE。
  • 當我遇到這個問題時,即使它返回Void,我也會在我的SwingWorker上調用get()。這是爲了幫助我捕捉並響應SwingWorker在運行時可能發生的任何異常。
+0

謝謝,對不起,我從來沒有用Java做GUI,所以從來不知道有什麼線程可以做什麼等規則。很好解釋! 要使用Swing Worker類! – Moynul

2

隨着while循環我的textarea母鹿不更新

最有可能你在EDT (Event Dispatching Thread)開始你的循環。這可以防止UI自行更新。 嘗試改爲在另一個線程中運行您的代碼。 SwingWorker可以是一種選擇,創建您自己的Thread或ThreadPool機制(Executors服務)是另一種解決方案。只要確保所有更新的UI在EDT進行(例如通過在EventQueue.invokeLater塊移動它們)

參見以下鏈接提供關於如何正確使用SwingWorker