Custom dialog using JOptionPane API won't dispose

帅比萌擦擦* 提交于 2019-12-05 18:55:07

Well, inspecting JOptionPane#createDialog(String title) source code, it turns out the dialog is not closed nor disposed but hidden instead, and it's done on a PropertyChangeEvent when the option pane's value is set (to CANCEL_OPTION or NO_OPTION or CLOSED_OPTION I guess):

public class JOptionPane extends JComponent implements Accessible {

    ...

     // The following method is called within 'createDialog(...)'
     // in order to initialize the JDialog that will be retrieved.

    private void initDialog(final JDialog dialog, int style, Component parentComponent) {
        ...
        final PropertyChangeListener listener = new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                // Let the defaultCloseOperation handle the closing
                // if the user closed the window without selecting a button
                // (newValue = null in that case).  Otherwise, close the dialog.
                if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
                        (event.getPropertyName().equals(VALUE_PROPERTY)) &&
                        event.getNewValue() != null &&
                        event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
                    dialog.setVisible(false);
                }
            }
        };

        WindowAdapter adapter = new WindowAdapter() {
            private boolean gotFocus = false;
            public void windowClosing(WindowEvent we) {
                setValue(null);
            }

            public void windowClosed(WindowEvent e) {
                removePropertyChangeListener(listener);
                dialog.getContentPane().removeAll();
            }

            public void windowGainedFocus(WindowEvent we) {
                // Once window gets focus, set initial focus
                if (!gotFocus) {
                    selectInitialValue();
                    gotFocus = true;
                }
            }
        };
        dialog.addWindowListener(adapter);
        dialog.addWindowFocusListener(adapter);
        ...
    }
}

Despite the comment that states "Otherwise, close the dialog", no WindowEvent closing the dialog is even fired. Consequently the dialog won't be disposed properly unless we explicitely do so:

    JDialog dialog = optionPane.createDialog("New Dialog");
    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    dialog.setVisible(true);
    dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING));

Please note on a WINDOW_CLOSING event the WindowListener attached to the dialog within initDialog(...) method will just set the option pane's value to null but still won't dispose the dialog. That's why we still need to set the default close operation to DISPOSE_ON_CLOSE.

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