Pet*_*erg 6 java swing jframe jdialog componentlistener
我看到的区别是(在JDK 1.7上运行):
setVisible(false),调用componentHidden但不 调用windowClosed(API仅表示dispose()如此,即使它激怒了我也没关系)
但
dispose(),调用windowClosed但不是componentHidden
短期运行的示例代码(MCVE):
public class JDialogTest extends JDialog {
private static final long serialVersionUID = 1L;
public JDialogTest(JFrame owner){
super(owner,ModalityType.APPLICATION_MODAL);
init();
}
private void init() {
this.getContentPane().setLayout(new GridLayout(1,2));
JButton btnVisible = new JButton("Set visible false");
btnVisible.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JDialogTest.this.setVisible(false);
}
});
JButton btnDispose = new JButton("Dispose");
btnDispose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JDialogTest.this.dispose();
}
});
this.getContentPane().add(btnVisible);
this.getContentPane().add(btnDispose);
this.pack();
}
public static void main(String[] args) {
//A fake frame to test JDialog
JFrame fakeFrame = new JFrame("Fake Frame");
fakeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fakeFrame.getContentPane().setLayout(new BorderLayout());
JButton btnOpen = new JButton("Open Dialog");
fakeFrame.getContentPane().add(btnOpen,BorderLayout.CENTER);
fakeFrame.pack();
fakeFrame.setLocationRelativeTo(null);
//Generate the test dialog
final JDialogTest dialog = new JDialogTest(fakeFrame);
dialog.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
System.out.println("Component Shown");
}
@Override
public void componentHidden(ComponentEvent e) {
System.out.println("Component Hidden");
}
});
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("Window open");
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("Window closed");
}
});
dialog.setLocationRelativeTo(null);
btnOpen.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
});
fakeFrame.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:该示例具有a JDialog,但我看到相同的行为JFrame,测试简单地将侦听器附加到fakeFrame,并添加类似的按钮.(在MVCE中避免使其保持M inimal)).
我考虑过这篇文章:
JDialog setVisible(false)vs dispose()
dispose()...API文档:
Window.setVisible(boolean b),Window.dispose(),ComponentListener.componentHidden(ComponentEvent e),WindowListener.windowClosed(WindowEvent e)
我为什么要关心:当然是出于好奇,而且因为我使用按钮来关闭窗口(调用dispose()),界面也可以通过顶部/右侧窗口关闭图标和alt+ F4(调用setVisible(false)!?)来关闭.因此,不能使用上述监听器中的任何一个.只有HierarchyListener会抓住他们两个,这似乎反直觉.
编辑:这个问题的范围是"为什么会这样"?目的是什么?".我预计dispose()用于调用!我找不到为什么不API文档中的任何线索.
界面也可以通过顶部/右侧窗口关闭图标alt+关闭F4(调用 setVisible(false)!?)
这是由默认的关闭操作决定的。您可以使用 进行设置setDefaultCloseOperation。默认值为HIDE_ON_CLOSE,这就是您收到调用的原因componentHidden。如果您将其设置为,DISPOSE_ON_CLOSE那么您将收到一个windowClosed调用。设置为后者将允许您仅注册这些事件类型。
无论如何,隐藏和处置会产生不同的效果。处理会释放所使用的资源,而隐藏则不会。此外,隐藏最后一个窗口不会退出 JVM,而处理它则会退出。
至于事件调度的技术方面,有很多复杂的地方。虽然处理窗口确实会调用其隐藏方法,但事件的调度是在操作完成后完成的。这意味着 EDT 可以“事后”调度事件。由于窗口已关闭,因此它不会调度隐藏事件。