13

What's the programmatic equivalent of clicking the close (x) button in the upper right corner of a JFrame?

There's the dispose() method but that's not the same thing, since a JFrame can be set to do several different things upon closing (not to mention if there's a WindowListener involved)

tshepang
  • 11,360
  • 21
  • 88
  • 132
Jason S
  • 178,603
  • 161
  • 580
  • 939

3 Answers3

16

You tell the component to dispatch an event. In this case, you want it do dispatch a Window Closing event.

private void exit() {
    this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}
jjnguy
  • 133,300
  • 52
  • 294
  • 323
  • Cool, that's what I was looking for. I think you need to use Swing.invokeLater() though, to make sure it's on the event dispatch thread. – Jason S Oct 08 '10 at 18:42
  • @Jason, if this is being called from a Swing component, then it is already on the EDT. That is why you never want to do long calculations inside of a Swing component. (Because they would block the EDT) – jjnguy Oct 08 '10 at 18:53
  • Right. But I want to call it from another component. (I used `public void closeWindow()` as my signature.) – Jason S Oct 08 '10 at 19:03
2

When you hit the x on a JFrame, the system can be set to do various things. The default is that the window is simply hidden with setVisible(false) I believe.

You can set a frame to do different things on close--you can have it dispose, hide or call code based on setDefaultCloseOperation. Here are the options:

DO_NOTHING_ON_CLOSE: Don't do anything; require the program to handle the operation in the windowClosing method of a registered WindowListener object.

HIDE_ON_CLOSE: Automatically hide the frame after invoking any registered WindowListener objects.

DISPOSE_ON_CLOSE: Automatically hide and dispose the frame after invoking any registered WindowListener objects.

EXIT_ON_CLOSE: Exit the application using the System exit method. Use this only in applications.

But I think what you are after is setVisible(false).

Bill K
  • 61,188
  • 17
  • 100
  • 153
0

You have to insert the call into the AWT message queue so all the timing happens correctly, otherwise it will not dispatch the correct event sequence, especially in a multi-threaded program.

public void closeWindow()
{
    if(awtWindow_ != null) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
            }
        });
    }
}
peterk
  • 4,886
  • 5
  • 30
  • 43