我正在开发一个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'对象,然后如何将数据从初始化器传递回事件派发?
答案 0 :(得分:1)
使用SwingUtilities.invokeLater(),您已经有了正确的方法将数据推送到事件派发线程。 NPE表明你还有别的错误。
鉴于这一行:
conversation.append(text)
生产NPE,有三种选择:
您应该能够查看异常的堆栈跟踪,以确定它是否是第一个问题(.append()行将是跟踪中的最后一行)。如果是这种情况,请确保新的对话。对于另外两个,查看堆栈跟踪中的第一行,看看那里有什么坏了。
有几种方法可以将数据从EDT上移到后台线程上;您想要哪种方法取决于“初始化”对象的许多方面。
答案 1 :(得分:0)
我对你的所有问题都不是很清楚,但我认为你可能会错误地构建你的程序并为自己创造问题。您的ChatSession类应该更改自己的文本。如果你的主程序必须捕获数据包(而不是ChatSession),你应该在ChatSession上有文本字段的setter。
查看有关Swing MVC版本的this文章。