Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在OSX上使用屏幕菜单栏时如何使菜单项快捷键工作_Java_Macos_Swing_Jmenubar - Fatal编程技术网

Java 在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.

在OSX上,从主
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。