【问题标题】:JTextArea not working in multithreading - javaJTextArea 在多线程中不起作用 - java
【发布时间】:2013-08-22 16:22:06
【问题描述】:

我有一个代码可以更新run() 方法中的JTextArea

但是当run方法执行时append()方法没有被执行。

它打印incomingMessage 变量的当前值,但不附加到JTextArea

public void run()
{

    while (true)
    {
        try
        {
            if(serverSocketMessage==null)
            {
                serverSocketMessage = new ServerSocket(Constants.INCOMING_MESSAGE_PORT);
            }
            System.out.println("Listening to incoming messages");

            ObjectInputStream objectInputSender;
            String incomingMessage = null;

            serverMessage = serverSocketMessage.accept();
            objectInputSender = new ObjectInputStream(serverMessage.getInputStream());
            Object objectMessage = objectInputSender.readObject();
            if (objectMessage instanceof String)
            {
                incomingMessage = objectMessage.toString();
                System.out.println("\nMessage\n"+incomingMessage);
                if(incomingMessage!= null)
                {
                    chatingJTextArea.append(incomingMessage);
                    System.out.println("Not null");
                }

                chatingJTextArea.append("\n");
                chatingJTextArea.append(incomingMessage);



            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }

【问题讨论】:

  • JTextArea 的 append 方法是 Swing 中线程安全规则的一个例外。 docs.oracle.com/javase/6/docs/api/javax/swing/… 根据文档,您可以从其他线程追加到 JTextArea。
  • @Bill 他们在 JDK7 javadoc 中删除了该评论。根据我自己的经验,早期的 JDK 中的线程也不是安全的
  • 有趣。感谢您的信息!

标签: java multithreading swing jtextarea


【解决方案1】:

尝试在EDT 中调用追加

private void addMessage(final String message) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            chatingJTextArea.append(message);

        }
    });
}

【讨论】:

  • +1 - 因为有更多的地方,最好把它包装成一个自定义方法。您可能必须使方法参数incomingMessage final 编译...
  • @Reimeus 我尝试在 if 条件下调用 addMessage(incomingMessage) 但它不起作用
  • @Kundan 你确定正在调用 addMessage 吗? IE。 readObject 返回的类型实际上是字符串吗? readObject 通常用于读取二进制数据...
  • @Reimeus 是的,是它的调用。我尝试将 addMessage 的数据打印到该方法中,而 readObject 是一个字符串。
  • @Kundan 将代码发布为SSCCE,以便我们看到完整的图片
【解决方案2】:

一种解决方案是使用 SwingWorker 实现处理。 doInBackground 方法将实现处理,您将调用 publish 方法,并将字符串作为参数附加。然后,您的 SwingWorker 将覆盖 process 方法以获取 String 参数并将其附加到文本区域。

我没有足够的权限对​​此发表评论,但我删除了你所说的错误。

【讨论】:

  • if(incomingMessage!= null) { //chatingJTextArea.append(incomingMessage); System.out.println("in 函数值"+incomingMessage); addMessage(incomingMessage); System.out.println("非空"); }
  • -1 用于更新(jTextArea.getGraphics())。当属性改变时,Swing 组件会自动重绘自己。如果由于某种原因您需要重新绘制组件,那么您将使用 repaint() 方法。
猜你喜欢
  • 1970-01-01
  • 2013-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多