2

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

4

2 回答 2

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);
    }
}
于 2009-12-18T01:24:19.903 回答
2

以供参考:

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

这就是为什么您的 done() 方法从未被调用(doInBackground() 无法完成并且 done() 仅在此之后被调用)。

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

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

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

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

于 2011-03-03T14:46:13.547 回答