After being convinced ("schooled") that Swing apps on Mac do look native, I'm trying to make mine look as native as possible. Everything looks great, but when I hit command+Q or do it from the menu, my windowStateChanged(WindowEvent e)
is not firing on my main JFrame (if I exit in any other way, it does fire). How can I respond to the real Apple quit?

- 1
- 1

- 68,471
- 58
- 283
- 421
-
3+1 for an interesting question that helped rock my naive notions of "write once, run anywhere." I guess that explains why Apple builds their own Java. – Carl Smotricz Jan 14 '10 at 00:09
-
Thanks Carl. Few problems go by without me noting that it's Joel's concept of "leaky abstractions," yet again. – Dan Rosenstark Jan 14 '10 at 02:15
-
It's a bit like Godwyn's law. – yeoman Aug 25 '17 at 09:54
6 Answers
You can implement com.apple.eawt.ApplicationListener
and respond to the Quit
event. An example may be found in the Mac OS X Reference Library example, OSXAdapter.
Addendum: See Java for Mac OS X 10.6 Update 3 and 10.5 Update 8 Release Notes for information on deprecation, the redesigned com.apple.eawt.Application
class, and the location of API documentation for the Apple Java extensions. Control-click or right-click on the .jdk
file to Show Package Contents
. You can browse the classes of com.apple.eawt
among the OpenJDK sources.
As shown in this complete example, you can specify the desired
QuitStrategy
; a WindowListener
will respond to ⌘Q:
Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
As noted here, you can set the property from the command line
java -Dapple.eawt.quitStrategy=CLOSE_ALL_WINDOWS -cp build/classes gui.QuitStrategyTest
or early in the program, before posting any GUI events:
System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
EventQueue.invokeLater(new QuitStrategyTest()::display);
Console, after ⌘Q:
java.vendor: Oracle Corporation
java.version: 1.8.0_60
os.name: Mac OS X
os.version: 10.11
apple.eawt.quitStrategy: CLOSE_ALL_WINDOWS
java.awt.event.WindowEvent[WINDOW_CLOSING,opposite=null,oldState=0,newState=0] on frame0
Code:
package gui;
import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
/**
* @see https://stackoverflow.com/a/7457102/230513
*/
public class QuitStrategyTest {
private void display() {
JFrame f = new JFrame("QuitStrategyTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println(e);
}
});
f.add(new JTextArea(getInfo()));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private String getInfo() {
String[] props = {
"java.vendor",
"java.version",
"os.name",
"os.version",
"apple.eawt.quitStrategy"
};
StringBuilder sb = new StringBuilder();
for (String prop : props) {
sb.append(prop);
sb.append(": ");
sb.append(System.getProperty(prop));
sb.append(System.getProperty("line.separator"));
}
System.out.print(sb);
return sb.toString();
}
public static void main(String[] args) {
System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
EventQueue.invokeLater(new QuitStrategyTest()::display);
}
}
-
Excellent, I found that slightly after, but what do I do if I don't have the com.apple.eawt package? Or is it available on Windows too? – Dan Rosenstark Jan 14 '10 at 00:27
-
1Awesome, it's all clear now. It calls all the classes dynamically. My code ended up being one line (plus Apple's class): OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("onClose", (Class[])null)); – Dan Rosenstark Jan 14 '10 at 01:02
-
You have it exactly; I added some additional links to Apple's example for future reference. – trashgod Jan 14 '10 at 02:48
-
2It seems that since release 1.6 the class is deprecated. See: https://developer.apple.com/library/mac/#releasenotes/Java/JavaSnowLeopardUpdate3LeopardUpdate8RN/NewandNoteworthy/NewandNoteworthy.html Redesigned eAWT – Feb 26 '12 at 22:13
The top voted answer is excellent but just to fill in the "best way":
System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
This will trigger the standard window closing callback event which should work really nicely for portable code.
As a result of the discussion below it seems that its crucial to do this really early in the app. I wrote this early in the static initializer of the main class before any UI code was executed.

- 1
- 1

- 51,749
- 5
- 35
- 65
-
isn't this the same as `Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);`? – Dan Rosenstark Oct 12 '15 at 22:21
-
3Yep. But it doesn't require access to the Application class which you wouldn't want for a portable app. Its one line of code instead of reflection. – Shai Almog Oct 13 '15 at 04:16
-
1@Yar: Sadly, they're _not_ the same with regard to `command-Q`; I've updated the [example](http://stackoverflow.com/a/30308671/230513) cited [here](http://stackoverflow.com/a/2061318/230513) to show a portable approach; elide the call to `enableOSXQuitStrategy()` to se the effect. – trashgod Oct 15 '15 at 02:04
-
Damn you are correct. This just doesn't seem to be doable in a portable way without reflection! Thanks for the code! – Shai Almog Oct 15 '15 at 03:19
-
Actually no. My test case was flawed. This worked for me both with the cmd-Q and the quit menu option. On which version of the JDK does cmd-Q not work? – Shai Almog Oct 15 '15 at 03:54
-
@ShaiAlmog: I tested various combinations of Java 1.8.0_[45,60] on Mac OS X 10.[9,10,11]; your approach works as documented to send `WINDOW_CLOSING` when clicking the red close button but not via `command-Q` or the applicaiotn menu; I'd be happy to find I'm wrong! :-) – trashgod Oct 15 '15 at 11:34
-
Odd, that's the exact version of Java I'm using too. I'm still on Yosemite maybe the OS version has something to do with that? – Shai Almog Oct 15 '15 at 12:14
-
That explains it. I set it in my static initializer code before anything else. – Shai Almog Oct 17 '15 at 14:41
This is a pretty good question, and I must admit I don't have the answer. However, a couple years ago when I was working on a Java app and faced this problem, I solved it by registering a shutdown hook with the runtime that would do what I wanted the app to do before quitting. It's a heavy-handed solution but it worked. You can take a look at my code and see if it helps.

- 398,885
- 90
- 523
- 479
-
interesting solution, it's not bad since I am writing the main method myself. – Dan Rosenstark Jan 14 '10 at 00:26
I was originally seeing a 'access restriction' violation when trying to access the com.apple.eawt.Application and com.apple.eawt.* subclasses.
(Note: I'm programming on a MAC, using Eclipse, with Java 1.6 using Swing)
So I needed to modify my java build path to allow access to the apple subclasses by adding "com/apple/eawt/**" access rule. After that this code below was able to compile and work for me:
//NOTE: This code only works for MAC OS. If you run this on Windows
//the application never starts (so you literally need to remove this block of code)
import com.apple.eawt.*;
import com.apple.eawt.QuitHandler;
Application a = Application.getApplication();
a.setQuitHandler(new QuitHandler() {
@Override
public void handleQuitRequestWith(com.apple.eawt.AppEvent.QuitEvent qe, com.apple.eawt.QuitResponse qr) {
// TODO Auto-generated method stub
int res = JOptionPane.showConfirmDialog(frame, "Are you sure you want to exit the program?", "Quit ?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (res == JOptionPane.YES_OPTION)
qr.performQuit();
else
qr.cancelQuit();
}
});

- 31
- 1
Have you tried setting up command-Q as an accelerator in your menu? Can you make your app respond to it?
I'm not positive, but I think this works in Linux and probably Windows with the equivalent Alt-F4. My app responds to the "killing" keystroke, I process some cleanup code and then I do a programmatic System.exit()
.
If you're "just" after graceful exit handling, you may also want to catch the WindowEvent
WINDOW_CLOSING
, where traditionally "are you sure?" stuff gets done.

- 101
- 1
- 10

- 66,391
- 18
- 125
- 167
-
won't work, because you can trip the menu item with your mouse too. – Dan Rosenstark Jan 13 '10 at 23:51
-
1So what's wrong with that? It makes sense for your app to respond to the keystroke as well as the "Quit" menu item, and identically so. – Carl Smotricz Jan 13 '10 at 23:53
-
Thanks for this first round. I do catch the WindowEvent. Works if I press the little red dot to close, but NOT if I use the "Quit MyApp cmd-Q"... – Dan Rosenstark Jan 13 '10 at 23:54
-
Sorry, I'm not being clear. On OSX, one doesn't put the Quit menu item under file. It's part of the OS. All apps have it, like it or not. – Dan Rosenstark Jan 13 '10 at 23:55
-
1Sure. The red dot closes the window but not the app - that's the Apple way. I really suggest you try putting cmd-Q in your menu before rejecting my answer out of hand. – Carl Smotricz Jan 13 '10 at 23:57
-
Okay, you're right. But also I just found this "Apple provides functionality for this in the com.apple.eawt.* Java classes. The Application and ApplicationAdaptor classes provide a way to handle the Preferences, About, and Quit items."... don't know if that's right either. Easier to try your suggestion first. – Dan Rosenstark Jan 13 '10 at 23:58
-
1Great, and I hope you get it working. But I do have to face the fact that I have too little Apple-specific Java experience to help you any further, so I'm going to throw in the towel with what grace I can muster. Good luck! – Carl Smotricz Jan 14 '10 at 00:08
-
Cool, I'll upvote you so you'll have to live with this answer forever :) – Dan Rosenstark Jan 14 '10 at 00:26
-
I would comment on the QUESTION above, but then you'd never see it. Just wanted to respond to your comment in the Q and say that, "yes, it's true, Apple does kind of need their own Java implementation" because they're so heavy-handed with standard app behavior. Probably same fascism as runs the Apple Store. Not sure if it's morally okay, but the results are pretty interesting (usability of OS-wise). Anyway, I can see this is a pro-Mac comment, so I'll drop it before it offends.... – Dan Rosenstark Jan 15 '10 at 00:33
-
2Thank you, that's thoughtful. My answer is of little worth but I'm leaving it up to keep the discussion visible. Yes, Apple bullies the developer but the result is a very smooth user experience. Pros and cons to everything, I guess. I'm not sure it's the same in the Apple Store; as I understand it, much of what they do there is for the bottom line, not user convenience. – Carl Smotricz Jan 15 '10 at 08:02
Looking at the link to Java for Mac OS X 10.6 Update 3 and 10.5 Update 8 Release Notes I noticed that there is a section on Default Quit Action. This describes a system property to request that all windows are closed in response to the "Quit" menu item, which sounds like exactly what is needed? I have used this in my own application (using Info.plist to set the property on OS X only), and it seems to work as described. This would presumably only work on recent Java/OS X versions, but for those platforms seems like a neat solution, and doesn't require any code changes.
-
1Thanks. @trashgod already took care of this in the addendum to his answer. – Dan Rosenstark May 15 '12 at 16:33
-
@Igor I don't know but all the regular events are called as expected. – Dan Rosenstark Mar 27 '13 at 23:04