2014-12-30 55 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