使用JOptionPane API的自定义对话框不会被处置

我一直在玩JOptionPane API以显示自定义对话框,我发现了一个奇怪的情况:当我选择“ 确定”或“ 取消”选项或按Esc键时,此对话框将不会按预期处理。

问题是,而不是使用这一行来显示modal dialog:

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

我想使用API​​,逐个设置所有参数并显示文档中显示的对话框(请参阅直接使用部分):

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

但是,当我关闭对话框时,即使我将默认关闭操作设置为DISPOSE_ON_CLOSE ,我的应用程序仍会继续运行,这让我怀疑对话框没有正确处理。

以下是MCVE :

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

好吧,检查JOptionPane #createDialog(字符串标题)源代码,结果是对话框没有关闭也没有处理但是隐藏了,当设置了选项窗格的值时,它就在PropertyChangeEvent上完成(我猜是CANCEL_OPTIONNO_OPTIONCLOSED_OPTION ) :

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

尽管注释声明“否则,关闭对话框” ,甚至没有关闭对话框的WindowEvent 。 因此,除非我们明确地这样做,否则对话框将无法正确处理:

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

请注意,在WINDOW_CLOSING事件中,在initDialog(...)方法中附加到对话框的WindowListener只会将选项窗格的值设置为null但仍然不会释放该对话框。 这就是我们仍然需要将默认关闭操作设置为DISPOSE_ON_CLOSE