但是这样做后,我遇到了空指针访问问题。当我在main_application中检查JTextArea对象时,它不是null,但是在传递给线程后,我检查它时发现它是null。我不知道这是如何发生的......如果有任何技术大牛可以帮助我,我将非常感激。
谢谢, Surjya
如另一个回答所提到的,您只能在Swing线程本身上更改Swing组件的内容。确保所有其他线程都这样做的好方法是不公开实际的JTextArea,而是为其他对象提供从main_application安全添加文本到文本区域的方法,如下所示:
public class main_application {
private JTextArea txtArea;
public void addText(final String txt) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
txtArea.setText(txtArea.getText() + txt);
}
});
}
这是一个简单的例子,但您可以根据需要进行扩展。由于它附加了两个不可变字符串,因此这也使用了更昂贵的添加文本方式。您可以使用JTextArea.getDocument()检索模型,然后使用文档中的变异方法更有效地更新文本。但是,通过提供像这样的方法,您可以在不影响其他线程或对象的情况下将其实现更改。
请注意,参数txt是final的,这是必需的,以便可以直接在匿名内部类中引用它。
您可能希望将此与主应用程序类分离,并为您想要从其他线程操作文本区域的方法/方式创建一个接口或类,然后将包装此文本区域的对象交给它们。
在线程之间共享对象可能会变得非常混乱,您可能想阅读有关Actor模型的内容以获得不同的方法。特别是在GUI领域,Model-View-Controller方法可以帮助解决问题。
但回到问题上来,您可以通过将JTextArea设置为静态变量并允许所有不同的线程随意修改静态实例来快速进行破解:
public static JTextArea TXTAREA
void main_application(){
//set up app
...
TXTAREA = new JTextArea()
...
}
然后在您的串行读取线程中,为TXTAREA
设置文本。这个解决方案并不理想,我认为更好的方法是使用MVC方法,并有一个控制器接受要放入文本区域的值。
TXTAREA
应该是易失性的吗?(免责声明:我还没有阅读《Java并发实践》,但这在我的待办事项列表中 :)) - wds看一下SynchronousQueue:
http://java.sun.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue.html
它将允许您将对象存储到队列中,然后等待直到其被移除。因此,您应该执行以下操作:每当您有新数据要显示时,提交新的JTextArea内容更新任务以从EDT执行。您可以通过SwingUtilities.invokeLater()实现这一点。