-
Bug
-
Resolution: Unresolved
-
P4
-
8
-
x86
-
os_x
FULL PRODUCT VERSION :
Discovered: 1.8.0_51
Also happens on: 1.8.0_05
ADDITIONAL OS VERSION INFORMATION :
OS 10.10.4
A DESCRIPTION OF THE PROBLEM :
If the application has a default menu and wants to use QuitStrategy.CLOSE_ALL_WINDOWS, all windows are closed, but AWT never exits.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided program.
Select Quit from the application menu.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the application to quit.
Although in the normal situation, closing the last window *should not* close a Mac application, the default menu bar should be treated as a window for this purpose, though it does not appear in the list of windows returned from static methods on Window.
ACTUAL -
The application does not quit, although the window is closed as expected.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import com.apple.eawt.AppEvent;
import com.apple.eawt.Application;
import com.apple.eawt.QuitHandler;
import com.apple.eawt.QuitResponse;
import com.apple.eawt.QuitStrategy;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class Test implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Test());
}
@Override
public void run() {
Application application = Application.getApplication();
JMenuBar menuBar = new JMenuBar();
menuBar.add(new JMenu("File"));
application.setDefaultMenuBar(menuBar);
application.setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
application.setQuitHandler(new QuitHandler() {
public void handleQuitRequestWith(AppEvent.QuitEvent event, QuitResponse response) {
// would normally ask the user if it's OK
response.performQuit();
}
});
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The workarounds:
(a) avoid CLOSE_ALL_WINDOWS
Unfortunately, using QuitStrategy.SYSTEM_EXIT_0 results in other problems - now the EDT will be forcibly killed, despite important tasks being submitted to it which should be executed before shutting down.
(b) avoid setting a default menu bar
Not using the default menu bar is not really a good idea either, as this reduces native integration.
I will probably have to try some kind of workaround where we use SYSTEM_EXIT_0 but delay the call to performQuit() by calling that from another invokeLater. Piling up multiple calls to invokeLater has a habit of working and then breaking in a later release, however.
Discovered: 1.8.0_51
Also happens on: 1.8.0_05
ADDITIONAL OS VERSION INFORMATION :
OS 10.10.4
A DESCRIPTION OF THE PROBLEM :
If the application has a default menu and wants to use QuitStrategy.CLOSE_ALL_WINDOWS, all windows are closed, but AWT never exits.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided program.
Select Quit from the application menu.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the application to quit.
Although in the normal situation, closing the last window *should not* close a Mac application, the default menu bar should be treated as a window for this purpose, though it does not appear in the list of windows returned from static methods on Window.
ACTUAL -
The application does not quit, although the window is closed as expected.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import com.apple.eawt.AppEvent;
import com.apple.eawt.Application;
import com.apple.eawt.QuitHandler;
import com.apple.eawt.QuitResponse;
import com.apple.eawt.QuitStrategy;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class Test implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Test());
}
@Override
public void run() {
Application application = Application.getApplication();
JMenuBar menuBar = new JMenuBar();
menuBar.add(new JMenu("File"));
application.setDefaultMenuBar(menuBar);
application.setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
application.setQuitHandler(new QuitHandler() {
public void handleQuitRequestWith(AppEvent.QuitEvent event, QuitResponse response) {
// would normally ask the user if it's OK
response.performQuit();
}
});
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The workarounds:
(a) avoid CLOSE_ALL_WINDOWS
Unfortunately, using QuitStrategy.SYSTEM_EXIT_0 results in other problems - now the EDT will be forcibly killed, despite important tasks being submitted to it which should be executed before shutting down.
(b) avoid setting a default menu bar
Not using the default menu bar is not really a good idea either, as this reduces native integration.
I will probably have to try some kind of workaround where we use SYSTEM_EXIT_0 but delay the call to performQuit() by calling that from another invokeLater. Piling up multiple calls to invokeLater has a habit of working and then breaking in a later release, however.