【问题标题】:Java SwingUtilities.invokeLater update TextAreaJava SwingUtilities.invokeLater 更新 TextArea
【发布时间】:2025-12-06 02:20:07
【问题描述】:

我有以下课程:

  • 主服务器
  • TCP 服务器
  • UDP 服务器

我从 MainServer 类创建 TCPServer 和 UDPServer 类的新实例(开始),我的 GUI 在该类中初始化。 在这个 GUI 中,我有一个 textArea,TCP 或 UDP 类需要更新它以显示日志信息(错误、状态等)。我做了一些搜索,我知道我可能需要在 MainServer 中使用 EDT,但不知道如何从 TCPServer 或 UDPServer 访问 MainServer 类中的这个对象。现在我只能打印到控制台,这是不可取的。 如何从 TCPServer 访问 MainServer.printlog?或 Mainserver.textArea 对象? 如果我从 TCPServer 或 UDPServer 创建一个新的 MainServer 实例,这似乎不起作用。

这是我在 MainServer 类中的函数:

public void printLog (final String log, final int level) {

    SwingUtilities.invokeLater(
    new Runnable() 
    {
        public void run() 
        {
        if (level == 1) 
            textArea.append("INFO\t" + log);
        if (level == 2)
            textArea.append("WARN\t" + log);
        if (level == 3)
            textArea.append("ERROR\t" + log);
        }
    }
    );
}

编辑:我尝试创建 MainServer 的新实例并访问 printLog 但我得到:

线程“AWT-EventQueue-0”中的异常 java.lang.NullPointerException 在 MultithreadedBarcodeReader.MultithreadedBarcodeReaderServer$2.run( 多线程BarcodeReaderServer.java:68) 在 java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) 在 java.awt.EventQueue.dispatchEventImpl(EventQueue.java:682) 在 java.awt.EventQueue.access$000(EventQueue.java:85) 在 java.awt.EventQueue$1.run(EventQueue.java:643) 在 java.awt.EventQueue$1.run(EventQueue.java:641)

【问题讨论】:

  • 这部分看起来不错;作为参考,有一个工作示例here
  • 当您说“这似乎不起作用”时,请更准确地说明什么您正在观察的实际问题 .
  • 嗨 MvG,我有 6 个不同的类文件:*MainServerInit、* MainServer、*TCPServer *UPDServer *Decode *Result。在解码和结果中,我处理从客户那里获得的任何东西。但是 MainServerInit 类初始化了 MainServer,它启动了 GUI 并包含 printLog 方法。在这个阶段,当我初始化一个也启动 TCP 和 UDP 服务器的 MainServer 实例时,我不确定访问 MainServer server = new MainServer; 的方法或 sintaxis; server.printLog("TCP Server() 错误",2);来自 TCP、UDP、Decode 等
  • 请不要将代码或异常输出放入代码cmets。将其编辑到问题中(正如@trashgod 已经完成的那样)。
  • 你确定你的“textArea”变量已经初始化了吗?

标签: java multithreading swing event-dispatch-thread invokelater


【解决方案1】:

NullPointerException 出现在第 68 行的匿名类中,嵌套在 MultithreadedBarcodeReaderServer 中,大概是引用的 Runnable。有人可能会猜测textAreanull,因为log 没有被取消引用而level 是原始的。您需要在调试器中的该行附近中断才能确定。还要验证您的 GUI 组件是否event dispatch thread 上构建和操作。

【讨论】:

    【解决方案2】:

    考虑使用一个单独的日志框架,或者至少一个带有静态方法的单独的日志类(或者一个带有静态方法的日志工厂)。对于您的应用程序,它们是否登录到控制台、JTextArea... 都无关紧要,而且您当然不想仅出于记录目的而传递 MainServer 实例。

    然后您的应用程序可以简单地“记录”这些消息,如果您想在某个JTextArea 上显示这些消息,您可以简单地添加一个处理程序来执行此操作。然后可以在与您创建实际JTextArea 的位置相同的位置创建此处理程序,当然也可以append 事件调度线程上的日志消息。

    使用一个不错的日志框架的其他优点是,您可以在每个类的基础上激活日志记录,在每个类的基础上配置日志记录级别,......以及所有这些,而无需对您的代码进行任何更改。因此,这允许从已部署的应用程序中收集“调试信息”(甚至可能是您不想出现在 JTextArea 中但您想知道以诊断问题的信息)。

    【讨论】: