2009-12-18 54 views
2

我有一個SwingWorker線程,它啓動一個模式對話框(來自一個屬性更改偵聽器,它偵聽已啓動的StateValue),並且swing工作者繼續執行其工作。但是,看起來done方法沒有被調用,因爲在EDT上調用了該方法,但擺動工作人員的模態對話框阻止了EDT。所以,我無法關閉EDT中的對話框(或完成的方法)。現在,我只是在該方法結束時關閉doInBackground中的對話框,但由於doInBackground不在EDT上,似乎對doInBackground有點不安全。處理這個問題的最好方法是什麼?謝謝。Swing Worker模態對話框不會關閉

回答

4

即使顯示模態對話框,調度循環仍應繼續調度與SwingWorker相關的事件。

這適用於我。

import javax.swing.*; 

public class Unions { 
    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { public void run() { 
      runEDT(); 
     }}); 
    } 
    private static void runEDT() { 
     final JDialog dialog = new JDialog((JFrame)null, true); 
     new SwingWorker<Void,Void>() { 
      @Override protected Void doInBackground() throws Exception { 
       // But this is working. 
       Thread.sleep(3000); 
       return null; 
      } 
      @Override protected void done() { 
       dialog.setVisible(false); 
      } 
     }.execute(); 
     dialog.setVisible(true); 
    } 
} 
+0

我不小心顯示了來自非EDT線程的對話框,所以有時候只會出現問題。我猜這有些問題(儘管我無法確切知道問題的原因),但現在一切都很好,謝謝。 – 2009-12-18 01:40:07

+0

'assert java.awt.EvenQueue.isDispatchThread();'是你的朋友(和'assert!java.awt.EvenQueue.isDispatchThread();')。 – 2009-12-18 02:05:30

2

參考:

當一個模式對話框在Swing推出,該線程的執行被停止,直到關閉對話框。

這就是爲什麼你的done()方法從來沒有被調用(doInBackground()不能完成,done()僅在之後被調用)。

從EDT線程調用的動作打開模態對話框稍有不同。 EDT本身將繼續處理事件,但打開模式對話框的實際事件線程代碼(動作代碼)仍然被阻塞(並等待對話框關閉)。

當然,在非模態對話的情況下,這個問題永遠不會出現。

順便說一下:你永遠不應該從美國東部時間之外打開一個對話框。 如果決定是在非EDT線程上進行的,則需要使用SwingUtilities.invokeLater()實際打開對話框。

聽起來很複雜,但事實上並非如此,一旦你掌握了EDT的概念。