在OS X上使用屏幕菜单栏时如何使菜单项加速键起作用 [英] How to get the menu item accelerator keys working when using the screen menu bar on OS X

查看:108
本文介绍了在OS X上使用屏幕菜单栏时如何使菜单项加速键起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在OS X上,有必要从主JFrame中删除JMenuBar,然后使用屏幕菜单栏.

On OS X, it makes sense to remove the JMenuBar from your main JFrame and use the screen menu bar instead.

给我的印象是,在Apple JDK的最新版本中,这是使用

I was under the impression that in recent versions of the Apple JDK this is done using the

Application.getApplication().setDefaultMenuBar( JMenuBar );

打电话.

使用此功能时,似乎加速键不再起作用.

When using this, it seems like the accelerator keys are no longer working.

以下程序说明了OS X上的问题:

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);
  }
}

该程序应允许您按 cmd + t ,然后会弹出一个对话框,确认该操作的快捷方式有效.

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.

我在我忘记调用的com.apple.eawt.Application类上没有找到任何相关方法.在有点过时的文章中浏览代码在Apple网站上建议,快捷方式应该可以正常工作.

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.

请注意,使用

System.setProperty("apple.laf.useScreenMenuBar", "true")

代替Application#setDefaultMenuBar方法,它可以按预期工作.这是否意味着系统属性仍然是推荐的方法,并且我不应该使用Application类上的方法?

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 ?

推荐答案

我正在混合两种不同的东西:

I was mixing two different things:

系统属性

System.setProperty("apple.laf.useScreenMenuBar", "true")

确定Aqua外观是否将顶级窗口的菜单栏(例如JFrame)用作应用程序菜单栏.

determines whether the Aqua look and feel uses the menubar of your top-level window (e.g. a JFrame) as application menu bar.

将此设置为true将确保您在致电例如

Setting this to true will ensure that when you call e.g.

JFrame frame = ...;
JMenuBar menu = ...;
frame.setJMenuBar(menu);

当框架具有焦点时,菜单栏将用作应用程序菜单栏,并且菜单栏永远不会被绘制为JFrame的一部分. 当另一个框架(或顶层组件)获得焦点时,应用程序菜单栏将被更新以显示该组件的菜单栏.

the menu bar will be used as application menu bar when the frame has focus, and that the menu bar will never be painted as part of the JFrame. When another frame (or top level component) gains focus, the application menu bar will be updated to show the menu bar of that component.

例如,当您使用JOptionPane.showXXX方法之一显示模式对话框时,应用程序菜单栏将尝试显示该模式对话框的菜单栏.由于这是null,因此只要未关闭模式对话框,应用程序菜单栏就会变为空白.

For example when you show a modal dialog using one of the JOptionPane.showXXX methods, the application menu bar will try to show the menu bar of that modal dialog. As this is null, the application menu bar will become empty as long as that modal dialog is not closed.

这是Application.setDefaultMenuBar方法起作用的地方.如果使用非null菜单栏调用此方法,则当没有菜单栏的顶级组件获得焦点时,该菜单栏将显示为应用程序菜单栏.

This is where the Application.setDefaultMenuBar method comes into play. If you call this method with a non-null menu bar, that menu bar will be shown as application menu bar when a top level component without menu bar gains focus.

正因如此,问题中的代码段存在两个问题:

As such, the snippet in the question has 2 problems:

  • 它没有将系统属性设置为true
  • 它仅设置默认菜单栏,而忘记在JFrame上设置菜单栏.因为JFrame本身没有菜单栏,所以显示了默认菜单栏,给人的印象是setDefaultMenuBar方法是系统属性的替代方法.但这显然不是这种情况.
  • It does not set the system property to true
  • It only sets the default menu bar, and forgets to set the menu bar on the JFrame. Because the JFrame itself has no menu bar, the default menu bar is shown which gave the impression that the setDefaultMenuBar method was an alternative for the system property. But this is clearly not the case.

结果是快捷方式不起作用,因为JFrame中不包含JMenuBar.

The result is that the shortcuts are not working because the JMenuBar is not contained in the JFrame.

这篇关于在OS X上使用屏幕菜单栏时如何使菜单项加速键起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆