2011-12-31 63 views
10

我讀的地方,對於影響使用SwingUtilities.invokeAndWait/invokeLater的當使用SwingUtilies.invokeAndWait/invokeLater的

對於一個基本的GUI圖形用戶界面應該在EDT跑出的視覺效果的任何線索,是否有必要使用invokeAndWait將類似new SwingGUI().setVisible(true);的東西放在EDT行中?只是爲了顯示?

這算什麼?

回答

3

是的,如果你觸摸一個Swing對象,你必須在EDT上做它。在大多數情況下,您已經在那裏,但如果沒有,請使用SwingUtilities類。原因是Swing類不是多線程的,所以如果你在其他線程上訪問它,你很可能會引起討厭的問題。這可能是因爲setVisible()在封面上做了很多事情來顯示某些內容(如重新佈局)。最好保證安全。

+0

我什麼時候不在EDT下運行?那麼你的意思是,如果我改變了一些東西,我應該使用這些方法之一來運行它。但是我沒有創建另一個線程,我只是在默認線程上運行?所以不會在invokeAndWait中做setVisible是不必要的? – 2011-12-31 10:44:02

+2

如果您在「默認」(主)線程上運行它,那麼您在EDT上不*。 – Darkhogg 2011-12-31 10:47:58

+0

看看@ Robin的答案中的鏈接。主線程與EDT線程不同,但通常使用Swing運行的代碼是處理事件的代碼,因此也是EDT中的代碼。 – 2011-12-31 10:48:35

9

您的問題的簡短答案是:是的,即使是在美國東部時間撥號setVisible。要找出當前線程是否是EDT,可以使用EventQueue#isDispatchThread方法

一些參考鏈接:

編輯: 後閱讀我提供的鏈接,似乎Oracle網站上的一些文章已過時在他們仍然在文檔中可以在另一個線程上創建Swing組件。有一個stackoverflow question在這包含一些不錯的答案和鏈接到博客帖子和關於'新'政策的文章(幾年前新)

-1

訪問Swing對象應該通過事件調度線程美東時間)。這有一個小例外(我稍後會提到)。 EDT的目的是處理由於IO(鼠標和鍵盤事件)而可能發生的任何事件。很多時候這可能意味着改變GUI的佈局。 Swing沒有被開發爲線程安全的,這意味着如果兩個線程試圖同時修改相同的組件,那麼最終可能會導致一個損壞的GUI。由於已經有一個已知線程可以訪問Swing組件(EDT),所以其他線程不應嘗試修改它們或者甚至讀取它們的狀態。

現在,您可以在EDT之外操作Swing對象的例外情況。在任何組件變得可見之前,IO不可能觸發事件。因此,主線程可以設置Swing GUI,然後將單個JFrame設置爲可見。由於現在有可見的IO事件可以發生,主線程不應該嘗試修改更多的Swing組件。應該只使用這個選項來啓動一個圖形用戶界面,而且只能用於玩具問題。

我在說的是,以下是好的,如果你只是玩弄東西,不會造成問題。

public static void main(String[] args) { 
    // create components 
    JFrame f = new JFrame(); 
    ... 

    // do layout and other bits of setup 


    // show gui to user 
    f.setVisible(true); 
} 
+3

-1:Swing線程規則已更新。您應該訪問EDT上的所有組件,即使它們不可見。請參閱http://stackoverflow.com/questions/491323/is-it-safe-to-construct-swing-awt-widgets-not-on-the-event-dispatch-thread/491377#491377 – Robin 2011-12-31 11:36:55

0

凡是從您的

public static void main(String[] agrs) { 

直接調用(不產卵另一個線程或使用的invokeLater)是主線程上運行。

EDT(由用戶輸入觸發)(同時)訪問GUI主體時,可能會導致線程問題。調用invokeLater會導致任務(runnables)在EDT上運行,從而阻止其他EDT任務同時訪問,即。按鈕按等

如果您可以確定EDT不忙(在第一個窗口setVisible(true)之前),您可以從主線程訪問GUI。如果您可以確定EDT沒有提及您正在使用的組件(它不在EDT的範圍內),即。在它被添加到任何容器之前,您可以從主線程訪問它,而不需要EDT同時訪問它,因爲EDT無法訪問它。

+0

不可以。即使不是可見的是,必須從EDT訪問一個窗口。請參閱羅賓對沙丘答案的評論。 – 2011-12-31 15:33:07