JOptionPane#showMessageDialog(...)不会在EDT上阻塞

时间:2016-04-02 07:40:42

标签: java swing event-dispatch-thread

在阅读this question后,我决定执行在我的应用程序中在事件调度线程(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"

在EDT上执行时,JOptionPane.showMessageDialog(...)调用似乎停止阻止。是什么给予​​了什么?

我怀疑它可能与我的应用程序关闭代码有关。我在应用程序开始关闭之前显示一条消息,通知用户有关严重错误的信息。但是,在我的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,那么EDT上的shutdown调用应该在之后执行 >消息对话框关闭(因为它应该在对话框关闭之前阻止),因此shutdown中的代码不应该影响showMessage的行为。

0 个答案:

没有答案