JOptionPane#showMessageDialog(…) does not block on the EDT

五迷三道 提交于 2021-02-11 04:30:36

问题


Upon reading this question, I decided to execute the code that displays a message dialog in my application on the Event Dispatch Thread (EDT).

To do this, I modified my method that shows a message dialog from:

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.");
}

to:

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.");
        }
    });
}

However, I was surprised to find that the behavior changed significantly after this change. Before I modified the above method to run on the EDT, it would print "Before dialog", followed by displaying the dialog - blocking until it was closed - and then printing "After dialog". This is the expected behavior. Once the method was modified, I found that "Before dialog" is printed, the dialog briefly appears (basically flickers on and off), and then "After dialog" is printed.

It almost appears that the JOptionPane.showMessageDialog(...) call stops blocking when executed on the EDT. What gives?

I suspect it may have something to do with my application shutdown code. I display a message before the application begins to shut down to inform the user about the critical error. However, in my shutdown method, I ensure that it is also executed on the 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...");
    // ...
}

If my understanding of the event queue is correct, because I call showMessage before shutdown, the shutdown call that is on the EDT should be executed after the message dialog closes (since it should block until the dialog closes), so the code in shutdown should not affect the behavior of showMessage.

来源:https://stackoverflow.com/questions/36370584/joptionpaneshowmessagedialog-does-not-block-on-the-edt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!