在我的主应用程序类中,我有一个JTextArea的对象(比如txtArea)。我在main_application程序中创建了另外两个线程。我创建的两个线程是用于在串行端口中读写。现在我想将串口读缓冲区数据放入JTextArea对象。所以我需要将在main_application中创建的JTextArea对象传递给read-thread,以便read-thread可以将读取输出放到JTextArea。
但是这样做后我面临空指针访问问题。当我检查main_application中的JTextArea对象时它不是null但是在传递给线程后我检查了它的null。我不知道它是怎么发生的......如果有任何极客可以帮助我,我会很高兴....
谢谢, Surjya
答案 0 :(得分:2)
如另一个响应中所述,您只能在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);
}
});
}
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,这是必需的,因此可以在匿名内部类中直接引用它。
您可能希望将其与主应用程序类分离,并为要从其他线程操作文本区域的方法/方法创建接口或类,然后将它们包装为包装的对象这个文本区域。
答案 1 :(得分:1)
在线程之间共享对象可能会非常混乱,您可能希望阅读有关Actor model的不同方法。特别是在GUI领域,Model-View-Controller方法代码可以提供帮助。
但回到这个问题,你可以通过让你的JTextArea成为一个静态变量并让所有不同的线程随意修改静态实例来快速破解它:
public static JTextArea TXTAREA
void main_application(){
//set up app
...
TXTAREA = new JTextArea()
...
}
然后在您的序列阅读主题中,设置TXTAREA
的文本。这个解决方案并不理想,我认为更好的方法是使用MVC方法,并有一个控制器接受放入文本区域的值。
答案 2 :(得分:0)
看看SynchronousQueue:
http://java.sun.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue.html
它允许您将对象存储到队列中,然后等待它被删除。
答案 3 :(得分:0)
因此,您应该执行以下操作:每次有新数据显示时,都要提交要从EDT执行的 JTextArea 内容更新的新任务。您可以通过SwingUtilities.invokeLater()
实现这一目标