5

在我的主应用程序类中,我有一个 JTextArea 对象(比如 txtArea)。我在 main_application 程序中创建了另外两个线程。我创建的两个线程用于在串行端口中读取和写入。现在我想将串口读取缓冲区数据放入一个 JTextArea 对象中。所以我需要将 main_application 中创建的 JTextArea 对象传递给 read-thread,以便 read-thread 可以将读取的输出放到 JTextArea。

但是在这样做之后,我面临着空指针访问问题。当我检查 main_application 中的 JTextArea 对象时,它不为空,但在传递给线程后,我检查了它的空值。我不知道它是怎么发生的......如果有任何极客可以帮助我,我会很高兴......

谢谢,苏尔贾

4

4 回答 4

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);
        }
    });
}

}

这是一个简单的示例,但您可以根据需要对此进行扩展。这也使用了一种更昂贵的方式来添加文本,因为它附加了两个不可变的字符串。您可以使用 JTextArea.getDocument() 来检索模型,然后使用文档中的变异方法来更有效地更新文本。但是,通过提供这样的方法,您可以在将来更改实现,而不会影响您的其他线程或对象。

请注意,参数txt是必需的,以便可以在匿名内部类中直接引用它。

您可能希望将其与主应用程序类分离,并为您想要从其他线程操作文本区域的方法/方式创建一个接口或类,然后将其交给一个包装此文本区域的对象.

于 2009-11-26T23:43:14.870 回答
1

在线程之间共享对象可能会变得非常混乱,您可能需要阅读有关Actor 模型的不同方法。特别是在 GUI 领域,模型-视图-控制器方法代码提供了帮助。

但是回到这个问题,您可以通过使您的 JTextArea 成为静态变量并让所有不同的线程随意修改静态实例来快速破解它:

public static JTextArea TXTAREA

void main_application(){
    //set up app
    ...
    TXTAREA = new JTextArea()
    ...
}

然后在您的串行阅读线程中,将文本设置为TXTAREA. 这个解决方案并不理想,我认为更好的方法是使用 MVC 方法并有一个控制器来接受要放入文本区域的值。

于 2009-11-25T04:01:43.930 回答
0

看一下同步队列:

http://java.sun.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue.html

它将允许您将对象存储到队列中,然后等待它被删除。

于 2009-11-25T04:29:58.667 回答
0
  1. 将 JTextArea 引用发布到另一个线程是不正确的,因为 Swing 组件是基于 MVC 的(实际上是 model-ui)。因此,您使用 swing 组件的一般方法是更新它们的模型并让视图 (ui) 显示更改;
  2. 另一点是大多数swing组件都不是线程安全的,也就是说,如果您从线程中使用swing组件而不是EDT,您无法确定您的应用程序是否正常工作;

因此,您应该执行以下操作:每次有新数据要显示时,提交要从 EDT 执行的JTextArea内容更新的新任务。您可以通过SwingUtilities.invokeLater()来实现

于 2009-11-25T05:35:57.983 回答