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,

0 ответов

Другие вопросы по тегам