Модальное диалоговое окно Swing Worker не закрывается

У меня есть поток SwingWorker, который запускает модальное диалоговое окно (из прослушивателя изменения свойства, который прослушивает StateValue из start), и рабочий процесс приступает к выполнению своей работы. Однако похоже, что метод done не вызывается, потому что он вызывается в EDT, но модальное диалоговое окно Swing Worker блокирует EDT. Итак, я не могу закрыть диалог из EDT (или из метода done). Прямо сейчас я просто закрываю диалог из doInBackground в конце этого метода, но это кажется немного небезопасным из doInBackground, поскольку его нет в EDT. Как лучше всего справиться с этим? благодаря.


person Jeff Storey    schedule 18.12.2009    source источник


Ответы (2)


Цикл отправки должен продолжать отправлять события, связанные с 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);
    }
}
person Tom Hawtin - tackline    schedule 18.12.2009
comment
Я случайно показывал диалог из темы, отличной от EDT, поэтому проблемы возникали только иногда. Я предполагаю, что с этим была какая-то проблема (хотя я не могу точно понять, в чем проблема была вызвана), но теперь все хорошо, спасибо. - person Jeff Storey; 18.12.2009
comment
assert java.awt.EvenQueue.isDispatchThread(); — ваш друг (и assert !java.awt.EvenQueue.isDispatchThread();). - person Tom Hawtin - tackline; 18.12.2009

Для справки:

Когда в Swing запускается модальное диалоговое окно, выполнение этого потока останавливается до тех пор, пока диалоговое окно не будет закрыто.

Вот почему ваш метод done() никогда не вызывался (doInBackground() не мог завершиться, и done() вызывается только после этого).

Открытие модального диалога из действия, вызванного потоком EDT, немного отличается. Сам EDT продолжит обработку событий, но фактический код потока событий (код действия), который открывает модальное диалоговое окно, по-прежнему блокируется (и ожидает закрытия диалогового окна).

Естественно, в случае немодальных диалогов эта проблема никогда не возникает.

Кстати: вы никогда не должны открывать диалог из-за пределов EDT. Если решение принято в потоке, отличном от EDT, вам нужно использовать SwingUtilities.invokeLater(), чтобы фактически открыть диалоговое окно.

Звучит сложно, но на самом деле это не так, как только вы освоите концепцию EDT.

person sola    schedule 03.03.2011