Custom dialog using JOptionPane API won't

I was just playing around with the JOptionPane API to show a custom dialog and I found a strange situation: when I select either OKor Cancelor press a key Esc, that dialog will not be selected as expected.

The point is, instead of using this separate line to display the modal dialog:

JOptionPane.showConfirmDialog( null
                            , "The quick brown fox jumps over the lazy dog."
                            , "New Dialog"
                            , JOptionPane.OK_CANCEL_OPTION
                            , JOptionPane.PLAIN_MESSAGE);

      

I wanted to use the API by setting all the parameters one by one and displaying a dialog as shown in the docs (see Direct Usage ):

 JOptionPane pane = new JOptionPane(arguments);
 pane.set.Xxxx(...); // Configure
 JDialog dialog = pane.createDialog(parentComponent, title);
 dialog.show();

      

However, when I close the dialog, my application continues to run even though I set the default close operation to DISPOSE_ON_CLOSE

, which makes me suspect the dialog is not configured correctly.

Below MCVE to play with:

import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class Demo {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JOptionPane optionPane = new JOptionPane();
                optionPane.setMessage("The quick brown fox jumps over the lazy dog.");
                optionPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
                optionPane.setMessageType(JOptionPane.PLAIN_MESSAGE);

                JDialog dialog = optionPane.createDialog("New Dialog");
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                dialog.setVisible(true);
            }
        });
    }
}

      

+3


source to share


1 answer


Ok, checking the source code of JOptionPane # createDialog (String title) , it turns out that the dialog is not closed or deleted, but hidden, and this is done PropertyChangeEvent

when the value of the panel parameter is set (before CANCEL_OPTION

or NO_OPTION

or CLOSED_OPTION

, I think):

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 says "Otherwise close the dialog", no WindowEvent will even trigger the closing of the dialog. Hence, the dialog will not be configured correctly unless we do this explicitly:



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

      

Notice the WindowListenerWINDOW_CLOSING

event bound to the dialog in , will just set the parameter to a value , but still won't delete the dialog. Therefore, we still need to set the default close operation to .initDialog(...)

null

DISPOSE_ON_CLOSE

+2


source







All Articles