我一直在玩JOptionPane API来显示自定义对话框,而且我发现了一个奇怪的情况:当我选择 OK 或时取消选项或按 Esc 键,此对话框不会按预期处理。
问题是,而不是使用这一行来显示模态对话框:
JOptionPane.showConfirmDialog( null
, "The quick brown fox jumps over the lazy dog."
, "New Dialog"
, JOptionPane.OK_CANCEL_OPTION
, JOptionPane.PLAIN_MESSAGE);
我想使用API,逐个设置所有参数并显示docs中显示的对话框(请参阅 直接使用 部分) :
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);
}
});
}
}
答案 0 :(得分:2)
嗯,检查JOptionPane#createDialog(String title)源代码,结果是对话框没有关闭也没有被隐藏,而是隐藏了,当选项窗格显示时,它在PropertyChangeEvent
上完成了设置了价值(我估计为CANCEL_OPTION
或NO_OPTION
或CLOSED_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
,但仍会赢得& #39; t配置对话框。这就是为什么我们仍然需要将默认关闭操作设置为DISPOSE_ON_CLOSE
。