Java 在OSX上使用屏幕菜单栏时如何使菜单项快捷键工作
在OSX上,从主Java 在OSX上使用屏幕菜单栏时如何使菜单项快捷键工作,java,macos,swing,jmenubar,Java,Macos,Swing,Jmenubar,在OSX上,从主JFrame中删除JMenuBar并使用屏幕菜单栏是有意义的 我的印象是,在苹果JDK的最新版本中,这是使用 Application.getApplication().setDefaultMenuBar( JMenuBar ); 打电话 使用此功能时,油门键似乎不再工作 以下程序说明了OS X上的问题: import java.awt.*; import java.awt.event.*; import javax.swing.*; import com.apple.eawt.
JFrame
中删除JMenuBar
并使用屏幕菜单栏是有意义的
我的印象是,在苹果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
类中找到我忘记调用的任何相关方法。但是,在一个简单的例子中检查代码时,建议使用快捷方式
请注意,当使用
System.setProperty("apple.laf.useScreenMenuBar", "true")
它不像
应用程序#setDefaultMenuBar
方法那样工作。这是否意味着系统属性仍然是推荐的方法,我不应该在应用程序上使用该方法?我混合了两种不同的东西:
系统属性
System.setProperty("apple.laf.useScreenMenuBar", "true")
确定Aqua外观是否使用顶级窗口的菜单栏(例如JFrame
)作为应用程序菜单栏
将此设置为true
将确保当您调用
JFrame frame = ...;
JMenuBar menu = ...;
frame.setJMenuBar(menu);
当框架具有焦点时,菜单栏将用作应用程序菜单栏,并且菜单栏永远不会作为JFrame
的一部分绘制。
当另一帧(或顶级组件)获得焦点时,应用程序菜单栏将更新以显示该组件的菜单栏
例如,当您使用JOptionPane.showXXX
方法之一显示模式对话框时,应用程序菜单栏将尝试显示该模式对话框的菜单栏。由于这是null
,只要该模式对话框未关闭,应用程序菜单栏将变为空
这就是应用程序.setDefaultMenuBar
方法发挥作用的地方。如果使用非null
菜单栏调用此方法,则当没有菜单栏的顶级组件获得焦点时,该菜单栏将显示为应用程序菜单栏
因此,问题中的片段有两个问题:
- 它不会将系统属性设置为true
- 它只设置默认菜单栏,而忘记在
JFrame
上设置菜单栏。由于JFrame
本身没有菜单栏,因此会显示默认菜单栏,这给人的印象是setDefaultMenuBar
方法是系统属性的替代方法。但情况显然并非如此
结果是快捷键不起作用,因为JMenuBar
不包含在JFrame
中。我建议这是Apple扩展中的一个缺陷,一个“解决办法”是将操作
的键绑定到框架上itself@MadProgrammer我确实可以找到解决办法(就像只使用系统属性一样)。我打开这个问题主要是想看看我是否以错误的方式使用API,或者是否有一个好的API替代品(与脆弱的系统属性相比).@MadProgrammer进一步的调查显示我做了错事,这毕竟不是一个bug。除非你想把缺少文档称为bug。