A world without com.apple.eawt.*
You need to look towards java.awt.Desktop
instead.
For example...
Desktop.getDesktop().setQuitHandler(new QuitHandler() {
@Override
public void handleQuitRequestWith(QuitEvent e, QuitResponse response) {
// Do some stuff
//response.cancelQuit();
//response.performQuit();
}
});
Desktop.getDesktop().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
Original Answer
Welcome to the wonderful world of "Apple does everything differently"
Basically what's happening is, when you "Quit" the program, Apple is calling System.exit(0)
, basically the same thing that would occur if your used CMD+Q
Now, Apple provides an API which provides functionality which you can use to "configure" your App with MacOS and perform some functionality which is unique to Apple, the problem is, it's a complete pain in the ... code to find useful information about and use.
What you're looking for is com.apple.eawt.ApplictionsetQuitStrategy
. This defaults to calling System.exit(0)
, but you can change it to "close all windows" instead.
In this case, it would allow you to trap the WindowEvent
and do what ever it is you want to do
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("Closing");
System.exit(0);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
try {
Class quitStrategies = Class.forName("com.apple.eawt.QuitStrategy");
Object quitStrategy = null;
for (Object o : quitStrategies.getEnumConstants()) {
if ("CLOSE_ALL_WINDOWS".equals(o.toString())) {
quitStrategy = o;
}
}
if (quitStrategy != null) {
Class appClass = Class.forName("com.apple.eawt.Application");
Class params[] = new Class[]{};
Method getApplication = appClass.getMethod("getApplication", params);
Object application = getApplication.invoke(appClass);
Method setQuitStrategy = application.getClass().getMethod("setQuitStrategy", quitStrategies);
setQuitStrategy.invoke(application, quitStrategy);
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
}
}
My general advice is, build a nice "Mac" utilities class which encapsulates the functionality you want to play with and call that.
Also beware, this functionality may disappear suddenly in future releases.
It should be noted that if you intend to have a "one for all" application, you will need to use reflection, as the required API is not available in the standard API, but if you wanted to make a "Apple" only release, you should have a look at this for more information about how you can compile the code on MacOS, because using...
Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
is hell of a lot easier to write and understand