Swing Worker模态对话框不会关闭

时间:2009-12-18 01:04:09

标签: java swingworker event-dispatching

我有一个SwingWorker线程,它启动一个模态对话框(来自一个侦听已启动的StateValue的属性更改侦听器),并且swing工作人员继续完成它的工作。但是,看起来似乎没有调用done方法,因为在EDT上调用了它,但是swing工作者的模态对话框阻止了EDT。因此,我无法从EDT(或完成方法)关闭对话框。现在我只是在该方法结束时从doInBackground关闭对话框,但这似乎与doInBackground有点不安全,因为它不在EDT上。处理这个问题的最佳方法是什么?感谢。

2 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:2)

供参考:

在Swing中启动模式对话框时,将停止执行该线程,直到对话框关闭。

这就是你从未调用过done()方法的原因(doInBackground()无法完成,而done()仅在此之后被调用)。

从EDT线程调用的操作中打开模态对话框略有不同。 EDT本身将继续处理事件,但打开模态对话框的实际事件线程代码(操作代码)仍然被阻止(并等待对话框关闭)。

当然,在非模态对话框的情况下,这个问题永远不会出现。

顺便说一下:你永远不应该从EDT外面打开一个对话框。 如果决定是在非EDT线程上做出的,则需要使用SwingUtilities.invokeLater()来实际打开对话框。

听起来很复杂但实际上并非如此,一旦你掌握了EDT的概念。