在OS X上,从主JMenuBar
中删除JFrame
并使用屏幕菜单栏是有意义的。
我的印象是,在Apple JDK的最新版本中,这是使用
完成的Application.getApplication().setDefaultMenuBar( JMenuBar );
呼叫。
使用此功能时,似乎加速键不再有效。
以下程序说明了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);
}
}
程序应该允许你按 cmd + t 并弹出一个对话框,确认动作的快捷方式有效。
然而这不起作用。按下快捷键时,菜单项会突出显示,但不会执行操作。
我没有在com.apple.eawt.Application
课程上找到任何我忘记打电话的相关方法。在rather outdated article on the Apple website中查看代码表明快捷方式应该正常工作。
请注意,使用时
System.setProperty("apple.laf.useScreenMenuBar", "true")
而不是Application#setDefaultMenuBar
方法,它按预期工作。这是否意味着系统属性仍然是推荐的方式,我不应该在Application
类上使用该方法?
答案 0 :(得分:1)
我混合了两件不同的东西:
系统属性
null
确定Aqua外观是否使用顶级窗口的菜单栏(例如System.setProperty("apple.laf.useScreenMenuBar", "true")
)作为应用程序菜单栏。
将此设置为JFrame
将确保您致电时提供例如。
true
当框架具有焦点时,菜单栏将用作应用程序菜单栏,并且菜单栏永远不会被绘制为JFrame frame = ...;
JMenuBar menu = ...;
frame.setJMenuBar(menu);
的一部分。
当另一个帧(或顶级组件)获得焦点时,应用程序菜单栏将更新以显示该组件的菜单栏。
例如,当您使用JFrame
方法之一显示模式对话框时,应用程序菜单栏将尝试显示该模式对话框的菜单栏。由于这是JOptionPane.showXXX
,只要该模式对话框未关闭,应用程序菜单栏就会变为空。
这是null
方法发挥作用的地方。如果您使用非Application.setDefaultMenuBar
菜单栏调用此方法,则当没有菜单栏的顶级组件获得焦点时,该菜单栏将显示为应用程序菜单栏。
因此,问题中的片段有两个问题:
null
上设置菜单栏。由于JFrame
本身没有菜单栏,因此会显示默认菜单栏,这样会给人的印象是JFrame
方法是系统属性的替代方法。但事实显然并非如此。结果是快捷方式无效,因为setDefaultMenuBar
中未包含JMenuBar
。