2012-02-02 83 views
3

請考慮下面的代碼:創建和Swing線程上執行這是不好的編程習慣

public class MyClass extends javax.swing.JFrame { 

    private JTree jTree; 
    //Code ommited for clarity 

    public void methodCalledByAnotherThread(){ 

     final DefaultTreeModel t = new DefaultTreeModel(); 
     //Do some thing with t 

     SwingUtilities.invokeLater(new Runnable(){ 
      public void Run(){ 
       jTree.setModel(t); 
      } 
     }); 
    } 
} 

MyClass。在執行過程中有一段時間會啓動第二個線程,最終會調用methodCalledByAnotherThread()。不會在Swing線程上調用此方法。

methodCalledByAnotherThread()創建(本地)DefaultTreeModel對象,並做了一些工作,但它因爲這不是在Swing線程不能將該模型設置爲jTree因此呼籲SwingUtilities.invokeLater()。在Swing線程上執行的Runnable對象中,它將LOCAL DefaultTreeModel t設置爲JTree

我的問題是(而且我還沒有真正編譯和運行這段代碼,所以它可能無法正常工作)..是上述不良的編程習慣?如果是這樣,我怎樣才能將一個在非Swing線程上創建的TreeModel設置爲一個Swing對象?

回答

3

看起來很好(事實上它是最好的方法)。只要//Do some thing with t不包含任何已經顯示在UI上的元素。

+0

感謝您的快速回復。您是否有任何參考資料表示這是一種正確的方式? – Kerry 2012-02-02 19:36:37

+0

我發現在這個問題發佈:http://stackoverflow.com/questions/5895481/update-jlabel-from-another-thread – 2012-02-02 19:38:45

3

1)不要extends javax.swing.JFrame更多在Composition versus Inheritance,e.i.

2)更好的方式是getModel從currnet JTree例如Rathen市的比重新DefaultTreeModel上運行,並可能與un_know生命週期

3)正確的是你通過包裝將modelinvokeLater,sugestion最簡單的方法是從Runnable#Thread,更好從SwingWorker,

+0

關於你的#2 TreeModel是不是線程安全的,據我所知。因此,從另一個線程修改現有的線程應該被認爲是一種糟糕的編程習慣。 – 2012-02-02 19:44:18

+0

@ʘleg您的'考慮糟糕的編程習慣'可能是默認的方式如何添加/更新DefaultXxxModel從後臺任務到其他Swing GUI – mKorbel 2012-02-02 19:47:24

+0

修改不是線程安全對象從其他線程作爲默認方式不是我的問題:) – 2012-02-02 19:53:46