Java SwingUtilities.invokeLater更新TextArea

3
我有以下类:
  • MainServer
  • TCPServer
  • UDPServer
我从MainServer类创建TCPServer和UDPServer类的新实例(start),在此处初始化GUI。在这个GUI中,我有一个文本区域,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"
    at MultithreadedBarcodeReader.MultithreadedBarcodeReaderServer$2.run(
        MultithreadedBarcodeReaderServer.java:68)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:682)
    at java.awt.EventQueue.access$000(EventQueue.java:85)
    at java.awt.EventQueue$1.run(EventQueue.java:643)
    at java.awt.EventQueue$1.run(EventQueue.java:641)

注意:上述内容已经翻译,保留了HTML标记。

2
这部分看起来没问题;参考一下,这里有一个可行的例子(https://dev59.com/kHA75IYBdhLWcg3wg5js#3245805)。 - trashgod
1
由于您说“似乎无法正常工作”,请更精确地说明您所观察到的实际问题是什么。 - MvG
嗨MvG,我有6个不同的类文件:MainServerInit,MainServer,TCPServer,UPDServer,Decode和Result。在Decode和Result中,我处理从客户端获得的任何内容。但是MainServerInit类初始化了启动GUI并包含printLog方法的MainServer。在这个阶段,由于我初始化了一个MainServer实例,该实例还启动TCP和UDP服务器,我不确定从TCP、UDP、Decode等访问MainServer server = new MainServer; server.printLog("TCP Server() Error",2);的方法或句法。 - gogasca
2
请不要将代码或异常输出放入代码注释中。请将其编辑到问题中(如@trashgod已经完成的那样)。 - Andrew Thompson
你确定你的 "textArea" 变量已经被初始化了吗? - Sam YC
2个回答

2

NullPointerException 是在 MultithreadedBarcodeReaderServer 中的一个匿名类内部的第68行发生的,很可能是引用了 Runnable。可以猜测 textAreanull,因为 log 没有被解引用,而 level 是一个基本类型。你需要在调试器中靠近那一行进行断点调试以确保。还要验证你的GUI组件是否仅在事件分派线程上构建和操作。


1
考虑使用单独的日志框架,或者至少使用具有静态方法的单独的日志类(或具有静态方法的日志工厂)。对于您的应用程序,它不应该关心它们是将日志记录到控制台、JTextArea 还是其他地方,而且您肯定不希望仅出于日志目的而传递 MainServer 实例。
然后,您的应用程序可以简单地“记录”这些消息,如果您想在特定的 JTextArea 上显示这些消息,您只需添加一个处理程序来执行此操作。这个处理程序可以在创建实际的 JTextArea 的位置上创建,并且当然可以在事件分派线程上append日志消息。
使用良好的日志框架的其他优点是,您可以按类激活日志记录,按类配置日志级别等,而所有这些都不需要对代码进行任何更改。因此,这允许从部署的应用程序中收集“调试信息”(甚至可能是您不希望出现在JTextArea中但您想要了解以诊断问题的信息)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接