On OS X, it makes sense to remove the JMenuBar
from your main JFrame
and use the screen menu bar instead.
I was under the impression that in recent versions of the Apple JDK this is done using the
Application.getApplication().setDefaultMenuBar( JMenuBar );
call.
When using this, it seems like the accelerator keys are no longer working.
The following program illustrates the problem on OS X:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.apple.eawt.Application;
public class MacMenuBarShortcutTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
showUI();
}
});
}
private static void showUI(){
JFrame testFrame = new JFrame("TestFrame");
JLabel content = new JLabel("Press cmd-t to test whether the action is triggered");
testFrame.getContentPane().add(content);
JMenuBar menuBar = new JMenuBar();
Action action = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "It works!");
}
};
action.putValue(Action.NAME, "Test action");
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
JMenu menu = new JMenu("Menu");
menu.add(new JMenuItem(action));
menuBar.add(menu);
Application.getApplication().setDefaultMenuBar(menuBar);
testFrame.setVisible(true);
testFrame.pack();
testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
The program should allow you to press cmd+t and a dialog will pop up, confirming the shortcut for the action works.
This is however not working. The menu item gets highlighted when pressing the short cut, but the action is not executed.
I did not found any relevant methods on the com.apple.eawt.Application
class that I forgot to call. Going over the code in a rather outdated article on the Apple website suggested that shortcuts should be working though.
Note that when using
System.setProperty("apple.laf.useScreenMenuBar", "true")
instead of the Application#setDefaultMenuBar
method, it works as expected. Does this mean the system property is still the recommended way, and I shouldn't be using the method on the Application
class ?