JOptionPane#showMessageDialog(...) не блокируется на EDT
Прочитав этот вопрос, я решил выполнить код, который отображает диалоговое окно сообщения в моем приложении в потоке диспетчеризации событий (EDT).
Чтобы сделать это, я изменил свой метод, который показывает диалог сообщения из:
private static void showMessage(final Component parent,
final String message,
final String title,
final int type) {
System.out.println("Before dialog.");
JOptionPane.showMessageDialog(parent, message, title, type);
System.out.println("After dialog.");
}
чтобы:
private static void showMessage(final Component parent,
final String message,
final String title,
final int type) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Before dialog.");
JOptionPane.showMessageDialog(parent, message, title, type);
System.out.println("After dialog.");
}
});
}
Тем не менее, я был удивлен, обнаружив, что поведение значительно изменилось после этого изменения. Прежде чем я изменил вышеупомянутый метод для запуска на EDT, он напечатал бы "Before dialog"
с последующим отображением диалогового окна - блокировка до его закрытия - и затем печать "After dialog"
, Это ожидаемое поведение. Как только метод был изменен, я обнаружил, что "Before dialog"
на короткое время появляется диалоговое окно (в основном мигает, включается и выключается), а затем "After dialog"
печатается.
Похоже, что JOptionPane.showMessageDialog(...)
вызов прекращает блокировку при выполнении на EDT. Что дает?
Я подозреваю, что это может быть связано с кодом завершения работы моего приложения. Я отображаю сообщение до того, как приложение начинает закрываться, чтобы сообщить пользователю о критической ошибке. Однако по моему shutdown
Метод, я гарантирую, что он также выполняется на EDT:
public static synchronized void shutdown() {
if (userShutdown) {
return;
}
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
shutdown();
}
});
return;
}
userShutdown = true;
System.out.println("Shutting down...");
// ...
}
Если мое понимание очереди событий верно, потому что я звоню showMessage
до shutdown
, shutdown
вызов, который находится в EDT, должен быть выполнен после закрытия диалогового окна сообщения (поскольку он должен блокироваться до закрытия диалогового окна), поэтому код в shutdown
не должно влиять на поведение showMessage
,