tags:

views:

322

answers:

3

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  A: 

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.

Carl Smotricz
won't work, because you can trip the menu item with your mouse too.
Yar
So 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
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"...
Yar
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.
Yar
Sure. 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
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.
Yar
Great, 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
Cool, I'll upvote you so you'll have to live with this answer forever :)
Yar
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....
Yar
Thank 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
+5  A: 

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.

trashgod
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?
Yar
Awesome, 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));
Yar
You have it exactly; I added some additional links to Apple's example for future reference.
trashgod
+1  A: 

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.

mipadi
interesting solution, it's not bad since I am writing the main method myself.
Yar