Is there a way to close a JDialog through code such that the Window event listeners will still be notified? I've tried just setting visible to false and disposing, but neither seem to do it.
thanks, Jeff
Is there a way to close a JDialog through code such that the Window event listeners will still be notified? I've tried just setting visible to false and disposing, but neither seem to do it.
thanks, Jeff
Untested suggestion:
Have you tried getWindowListeners() and then iterating around to fire windowClosed() to each of the WindowListeners?
EDIT: the above suggestion is wrong. Keeping it for posterity.
I'm afraid calling dialog.dispose() works fine for me in my simple example.
Dispatch a windowClosing event to the Window. Check out the ExitAction example from the Closing an Application entry.
I don't seem to have your problem. When I use the code below windowDeactivated() is called for either setVisible( false ) or dispose() and windowClosed() is also called for dispose().
ClosingDialog.java:
public class ClosingDialog extends JDialog {
public ClosingDialog(Frame owner, String title, boolean modal) {
super(owner, title, modal);
JPanel contentPanel = (JPanel) this.getContentPane();
JButton setVisButton = new JButton("setVisible( false )");
setVisButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ClosingDialog.this.setVisible(false);
}
});
JButton disposeButton = new JButton("dispose()");
disposeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ClosingDialog.this.dispose();
}
});
contentPanel.setLayout(new FlowLayout());
contentPanel.add(setVisButton);
contentPanel.add(disposeButton);
this.addWindowListener(new WindowListener() {
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated");
}
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed");
}
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing");
}
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated");
}
public void windowDeiconified(WindowEvent e) {
System.out.println("windowDeiconified");
}
public void windowIconified(WindowEvent e) {
System.out.println("windowIconified");
}
public void windowOpened(WindowEvent e) {
System.out.println("windowOpened");
}
});
this.setSize(300, 300);
}
}
Closing a window (with dispose()
) and hiding it (with setVisible(false)
) are different operations, and produce different events -- and closing it from the operating system is yet another different operation that produces yet a different event.
All three will produce windowDeactivated
to tell you the window's lost focus, but dispose()
will then produce windowClosed
, while closing from the OS will first produce windowClosing
. If you want to handle both of these the same way, you can set the window to be disposed when closed:
window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
In general, setVisible(false)
implies that you might want to use the window again, so it doesn't post any window events (apart from windowDeactivated
). If you want to detect the hiding of a window, you need to use a ComponentListener
;
window.addComponentListener(new ComponentAdapter() {
@Override
public void componentHidden() {
System.out.println("componentHidden()");
}
})
Note though that this will pretty much only work for explicit setVisible()
calls. If you need to detect hiding more generally, you can use a HierarchyListener
, but it's probably more trouble than it's worth.
window.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
System.out.println("valid: " + window.isValid());
System.out.println("showing: " + window.isShowing());
}
});
Note that when you dispose a window you'll get a couple of HierarchyEvent
s, first for hiding and then for invalidation, but when you hide it with setVisible()
it's still valid, so you won't get the invalidation.