应用程序菜单加速器和 OpenFileHandler 在 Swing 应用程序中不起作用



我正在尝试在我的Java 8 Swing应用程序中添加对OS X的适当支持。为此,我使用了来自maven的com.apple:AppleJavaExtensions:1.4软件包。

我使用以下代码初始化菜单栏:

Application application = Application.getApplication();
JMenu fileMenu = new JMenu("File");
JMenuItem openMenuItem = new JMenuItem("Open...");
openMenuItem.addActionListener(action -> openFileDialog());
openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.META_MASK));
fileMenu.add(openMenuItem);
JMenuBar mainMenuBar = new JMenuBar();
mainMenuBar.add(fileMenu);
application.setDefaultMenuBar(mainMenuBar);

这在第一次工作得很好,没有打开任何 Swing 窗口。但是,当打开一个文件(并创建 Swing 窗口(时,快捷方式将停止工作。按 CMD+O 仍会突出显示菜单项,但不会执行该操作。使用鼠标选择"打开..."菜单项确实有效。我猜 Swing 窗口以某种方式窃取了事件(但按下组合键时菜单仍然突出显示......很奇怪(。

当文件打开对话框(openFileDialog(( 显示(被取消时,菜单加速器将继续工作。因此,它肯定与打开文件时打开的 Swing 窗口有关。

使用 OS X 打开文件的另一个问题是以下代码从不显示"foo":

application.setOpenFileHandler(e -> System.out.println("foo"));

这段代码在 main(( 中执行(在创建我前面提到的菜单栏后,它几乎立即返回(。永远不会调用文件处理程序;将文件拖放到 Dock 图标上时,以及双击文件并使用我的应用程序打开它时,都不是。

我做错了什么?

如果你的应用没有很多框架,那么这可能是一种解决方法。

setJMenuBar(menuBar);
final Dimension invisible = new Dimension(0, 0);
menuBar.setSize(invisible);
menuBar.setMaximumSize(invisible);
menuBar.setPreferredSize(invisible);
menuBar.setMinimumSize(invisible);

显然,OpenFileHandler 什么都不做,除非你的 Java 应用程序是从带有指定适当 CFBundleDocumentType 的 Info.plist 的应用程序捆绑包运行的。下面是它应该是什么样子的示例:

http://www.qtcentre.org/wiki/index.php?title=Opening_documents_in_the_Mac_OS_X_Finder

我通过简单地在每个 Swing 窗口上将 KeyEventDispatcher 注册到 KeyboardFocusManager,并在捕获正确的 KeyEvent 时手动调用相应的 ActionListeners,来解决菜单加速器不起作用的问题。非常非常丑陋,但它有效。我仍然想知道为什么这是必要的。

最新更新