How do I close a JDialog and have the Window Event Listeners be notified?

java, jdialog, swing

Solution

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(ComponentEvent e) {
    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.

Problem

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.

Original source