将数据从GUI传递到Swing中的事件派发线程

时间:2009-08-18 20:14:43

标签: java swing events

我正在开发一个Swing / Java应用程序,但是很难将数据从initiliaser线程传递到其中一个GUI。

通过在initComponents()方法中调用事件派发线程上的run()方法来初始化GUI:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {

            ChatSession ed = new ChatSession(client);

            ed.initComponents();

            ed.setVisible(true);

        }
    });

在ChatSession.java中,我有一个方法initComponents(),其中包含以下行:

conversation = new javax.swing.JTextArea();

然后我需要从ChatSession.java对象中的另一个方法更新GUI,该对象正在侦听TCP数据包。我需要将通过TCP套接字输入的新文本追加到GUI上的“对话”JTextArea。

我该怎么做?我已经尝试使用invokeLater在事件派发线程上运行一个方法,但是我得到一个NullPointerException错误...... ???

java.awt.EventQueue.invokeLater(
    new Runnable() {
        public void run()
        {
            //conversation.append(text);
            ChatSession.this.conversation.append("text to append to chatbox");
        }
    });

我也尝试了注释掉的线,仍然得到NPE。

我还需要在点击按钮时将事件调度线程中的数据传递给ChatSession对象(以便通过网络将其发送到另一个客户端)。

我在ChatSession.java中有一个方法,该方法被指定为使用在事件派发线程上初始化的ActionListener响应按钮的点击次数:

ChatSession.java中的方法:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
{                                         
     // add to toSend buffer
    toSend.append(sendtext.getText());
}  

....被分配给initComponents()中的ActionListener,它是ChatSession.java的一部分(在事件派发线程上运行,见前文):

jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

那么如何将数据从事件派发线程传递到'initialiser'对象,然后如何将数据从初始化器传递回事件派发?

2 个答案:

答案 0 :(得分:1)

使用SwingUtilities.invokeLater(),您已经有了正确的方法将数据推送到事件派发线程。 NPE表明你还有别的错误。

鉴于这一行:

conversation.append(text)

生产NPE,有三种选择:

  • 对话为空。你是否在ChatSession的构造函数中初始化对话?
  • 您的ChatSession中的其他内容在append()内部被调用为
  • 传入的文本为null,append()无法正确处理。

您应该能够查看异常的堆栈跟踪,以确定它是否是第一个问题(.append()行将是跟踪中的最后一行)。如果是这种情况,请确保新的对话。对于另外两个,查看堆栈跟踪中的第一行,看看那里有什么坏了。

有几种方法可以将数据从EDT上移到后台线程上;您想要哪种方法取决于“初始化”对象的许多方面。

答案 1 :(得分:0)

我对你的所有问题都不是很清楚,但我认为你可能会错误地构建你的程序并为自己创造问题。您的ChatSession类应该更改自己的文本。如果你的主程序必须捕获数据包(而不是ChatSession),你应该在ChatSession上有文本字段的setter。

查看有关Swing MVC版本的this文章。