2009-11-25 72 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是必需的,因此它可以在匿名內部類中直接引用。

您可能希望將其從主應用程序類中分離出來,併爲要從其他線程處理文本區域的方法/方法創建一個接口或類,然後向它們傳遞一個對象,包裝這個文本區域。

相關問題