簡體   English   中英

Java:GUI必須在EDT線程中初始化嗎?

[英]Java: GUIs must be initialized in the EDT thread?

我是傑森。 我在Substance外觀( https://substance.dev.java.net/ )上遇到了一些問題。

我的問題比較籠統。 我已經寫好了GUI,並且可以正常工作,但是當我使用物質外觀時,它要求所有GUI初始化都必須在EDT線程(事件調度線程等)中進行。

現在,我正在使用com.sun.java.swing.plaf.windows.WindowsLookAndFeel(不確定我是否拼寫正確),它不需要任何此類內容。

因此,我通過調用SwingUtilities.invokeLater()將主要的初始化放入EDT。 這使它起作用。 但是,該程序在執行過程中還會產生其他幾個窗口。 現在我有這樣的代碼:

SomeNewWindow window = new SomeNewWindow();
// ... some bs emitted
window.doStuff();

這段代碼可以正常工作,因為在window.doStuff()被調用時,它已經被初始化了。 但是,Substance要求我執行以下操作:

SwingUtilities.invokeLater(new Runnable(){
public void run(){
SomeNewWindow window = new SomeNewWindow();
}});
// ... bs emitted
window.doStuff();

這里有時會拋出NullPointerException,因為window尚未在window.doStuff()調用時初始化。 我不能將window.doStuff()放入EDT線程中,因為返回它通常需要幾秒鍾的時間,並且會掛起GUI。

我嘗試在調用EDT線程之后立即放置Thread.sleep(1000),因為那時它可能已初始化。 但這似乎很尷尬。 我只需要一種方法,在SomeNewWindow初始化返回后,主線程就可以“知道”,這樣它就可以繼續進行而不必擔心NullPointerException。

提前致謝。

您可以從invokeLater切換到invokeAndWait,它將等待直到創建窗口。 有點俗氣,但還不如入睡。

我認為解決此問題的標准方法是使EDT成為“基本線程”,從該“基本線程”開始其他工作線程進行處理。

另一種方法是使用volatile標志,初始化完成后即可設置該標志,以便其他線程可以在循環中對其進行檢查,並在標志設置后對新窗口進行操作。

例如,建議使用CountDownLatch 絕對可以簡化情況。


這是條件變量的工作。

基本上,在run()中,鎖定鎖,構造一些新窗口並發出條件信號(並解鎖鎖)。 在另一個線程中,“同時”執行其他“ bs”,鎖定鎖; 如果窗口為空,則對條件變量使用wait(); 解鎖鎖; window.doStuff();

為什么不能將doStuff()調用移到invokeLater回調中呢?

SwingUtilities.invokeLater(new Runnable(){
    public void run(){
         SomeNewWindow window = new SomeNewWindow();
         window.doStuff();
    }
});

如果以上操作是不可能的,那么我將使用invokeAndWait()而不是invokeLater() ,就像Paul Tomblin已經建議的那樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM