JFrame Exit on close Java
I don't get how can I employ this code:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
to close the program with the x button.
You need the line
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Because the default behaviour for the JFrame when you press the X button is the equivalent to
frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
So almost all the times you'll need to add that line manually when creating your JFrame
I am currently referring to constants in WindowConstants
like WindowConstants.EXIT_ON_CLOSE
instead of the same constants declared directly in JFrame
as the prior reflect better the intent.
If you don't have it, the JFrame will just be disposed. The frame will close, but the app will continue to run.
Calling setDefaultCloseOperation(EXIT_ON_CLOSE)
does exactly this. It causes the application to exit when the application receives a close window event from the operating system. Pressing the close (X) button on your window causes the operating system to generate a close window event and send it to your Java application. The close window event is processed by the AWT event loop in your Java application which will exit the application in response to the event.
If you do not call this method the AWT event loop may not exit the application in response to the close window event but leave it running in the background.
I spent quite a bit of time spelunking through the internet for an elegant solution to this. As is usually the case, I found a lot of conflicting information.
I finally ended with:
- Do not use
EXIT_ON_CLOSE
as this can leave resources behind; -
Do use something like the following in the JFrame initialization:
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
-
The real discovery was how to actually dispatch a window message to the JFrame. As an example, as part of your JMenuItem for exiting the application, use the following, where the function
getFrame()
returns a reference to the JFrame:public class AppMenuFileExit extends JMenuItem implements ActionListener { // do your normal menu item code here @Override public void actionPerformed(ActionEvent e) { WindowEvent we; we = new WindowEvent((Window) App.getFrame(), WindowEvent.WINDOW_CLOSING); App.getFrame().dispatchEvent(we); } }
JFrame is a subclass of Window so may be cast to Window for this purpose.
-
And, have the following in your JFrame class to handle Window messages:
public class AppFrame extends JFrame implements WindowListener { // Do all the things you need to for the class @Override public void windowOpened(WindowEvent e) {} @Override public void windowClosing(WindowEvent e) {/* can do cleanup here if necessary */} @Override public void windowClosed(WindowEvent e) { dispose(); System.exit(0); } @Override public void windowActivated(WindowEvent e) {} @Override public void windowDeactivated(WindowEvent e) {} @Override public void windowDeiconified(WindowEvent e) {} @Override public void windowIconified(WindowEvent e) {} }
If you're using a Frame (Class Extends Frame) you'll not get the
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)