2009-11-25 74 views
5

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

但做完这样的事情后,我面临着空指针访问问题。当我检查main_application中的JTextArea对象时,它不为null,但在传递给线程后,我检查了它的null。我不知道是怎么回事了....如果任何怪胎能帮助我,我会很高兴....

感谢, Surjya线程之间

+0

你是如何通过对象?你能提供十几行代码来证明你的问题吗? – Suppressingfire 2009-11-25 04:02:05

回答

1

共享对象可能会变得非常杂乱,你可能需要阅读关于Actor model的不同方法。特别是在GUI领域,Model-View-Controller方法代码有帮助。

但是后面的问题,你可以很快使你的JTextArea一个静态变量,只是让所有不同的线程修改静态实例随意本事:

public static JTextArea TXTAREA 

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

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

+0

不应该'TXTAREA'是不稳定的? (免责声明:我还没有在实践中阅读过java的并发,但是这是在我的列表中:)) – wds 2009-11-25 12:40:19

0
  1. 发布JTextArea引用到另一个线程是不正确的,因为Swing组件是基于MVC的(实际上是model-ui)。所以,你使用swing组件的一般方法是更新模型并让view(ui)显示更改;
  2. 另一点是,大多数swing组件都不是线程安全的,即如果您使用的线程中的swing组件超过EDT,则无法确保您的应用程序正常工作;

所以,你应该做到以下几点:每次有新的数据显示提交JTextArea中的新任务,从EDT执行内容更新。您可以通过SwingUtilities.invokeLater()

2

正如在另一个回复中提到的,您只能更改摆动线程本身上的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是必需的,因此它可以在匿名内部类中直接引用。

您可能希望将其从主应用程序类中分离出来,并为要从其他线程处理文本区域的方法/方法创建一个接口或类,然后向它们传递一个对象,包装这个文本区域。

相关问题