在while循环中更新我的textArea

时间:2014-12-30 13:49:34

标签: java

我正在使用Java创建UDP点对点聊天程序。

没有这个while 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 doe没有更新,我尝试在那里使用调用:

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

但它似乎仍然不起作用。

我正在使用Eclipse Luna窗口核心构建器,它会自动生成此自动代码

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循环中更新。

我该如何解决这个问题,谢谢。

2 个答案:

答案 0 :(得分:4)

您需要尊重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上调用execute()来运行它。
  • 我几乎总是在执行它之前向我的worker添加一个PropertyChangeListener。
  • 在这个监听器中,我注意到newValue是SwingWorker.StateValue.DONE。
  • 当我遇到这个时,我会在我的SwingWorker上调用get(),即使它返回Void。这是为了帮助我捕获并响应SwingWorker在运行时可能发生的任何异常。

答案 1 :(得分:2)

使用while循环,我的textArea doe不会更新

很有可能你在EDT (Event Dispatching Thread)开始了你的循环。这可以防止UI自行更新。 请尝试在另一个线程中运行您的代码。 SwingWorker可以是一个选项,创建自己的Thread或ThreadPool机制(Executors服务)是另一种解决方案。只需确保您对UI的所有更新都在EDT中执行(例如,通过在EventQueue.invokeLater块中移动它们)

另请参阅此链接,该链接提供了有关如何正确使用SwingWorker

的示例