【问题标题】:Focus on first jmenubar item on "alt" key press关注“alt”按键上的第一个 jmenubar 项目
【发布时间】:2012-01-29 06:39:53
【问题描述】:

当用户按下“ALT”键时,有什么方法可以在我的 jmenubar 中自动选择一个 jmenu? (如windows软件)

问题是我的 jframe 的默认行为,当按下“ALT”键时,会显示一个包含以下操作的菜单:恢复、移动、大小、缩小……

我希望我的 java 应用程序做的是在按下“alt”时选择我的 jmenu 第一项。 (就像使用助记符一样:“alt + f”)

【问题讨论】:

  • 在我使用的 Windows 应用程序(以及我的 Java 应用程序)中,使用 Alt+Space 时会显示包含“恢复、移动、调整大小...”操作的系统菜单。在我的 Windows 应用程序中,如果我只使用 Alt,那么当 Alt 键被释放(未按下)时,菜单栏上的第一个菜单会突出显示。因此,您的行为和要求似乎都不标准。发布您的SSCCD,证明您当前使用 Alt 键的问题。

标签: java swing jmenu jmenubar alt-key


【解决方案1】:

将操作添加到您的JRootPaneActionMapInputMap。见下文:

import java.awt.event.*;
import java.util.*;
import javax.swing.*;


public class MenuExample {

    private void setupMenuKey(final JFrame frame) {
        Action menuAction = new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JRootPane rootPane = frame.getRootPane();
                JMenuBar jMenuBar = rootPane.getJMenuBar();
                JMenu menu = jMenuBar.getMenu(0);
                menu.doClick();
            }
        };

        JRootPane rootPane = frame.getRootPane();
        ActionMap actionMap = rootPane.getActionMap();

        final String MENU_ACTION_KEY = "expand_that_first_menu_please";
        actionMap.put(MENU_ACTION_KEY, menuAction);
        InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true), MENU_ACTION_KEY);
    }


    private JFrame build() {
        JFrame frame = new JFrame("Hello");
        frame.setSize(300, 300);

        JMenuBar bar = new JMenuBar();

        List<String> letters = Arrays.asList("A", "B", "C");
        for (int i = 0; i < 3; i++) {
            JMenu menu = new JMenu("Menu " + i);
            for (String string : letters) {
                menu.add(new JMenuItem(String.format("Menu %s - %s", i, string)));
            }
            bar.add(menu);
        }
        frame.setJMenuBar(bar);

        JButton b = new JButton("click");
        JPanel p = new JPanel();
        p.add(b);
        frame.add(p);
        setupMenuKey(frame);

        return frame;
    }

    public static void main(String[] args) {
        MenuExample menuExample = new MenuExample();
        JFrame frame = menuExample.build();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }


}

【讨论】:

    【解决方案2】:

    使用 JComponent 的 actionmap 和 inputmap 来完成这项工作。由于 JFrame 不是 JCompoenent 的后代,我建议您将 JPanel 添加到您的 jframe,然后,

    Action action = new AbstractAction() {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                jMenu1.doClick();
            }
        };
        jPanel1.getActionMap().put("myAction", action);
        jPanel1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, KeyEvent.ALT_DOWN_MASK), "myAction");
    

    【讨论】:

      【解决方案3】:

      我发现响应非常有用,但也有一个缺点。

      假设您正在使用 Cross Platform L&F (Metal),并且您已经为所有菜单定义了助记符;您知道这些菜单是针对按 调用的。因此,如果我们将 black panda 提供的解决方案放在按下按钮上,我们首先会看到所需的菜单已部署,但在切换到第一个菜单后立即。

      我认为最好的方法是在 ALT 上按下仅应选择第一个菜单但不显示其内容(这些内容应出现在按下键时)。有没有办法在跨平台 L&F 中做到这一点?

      另外,还有另一种无需任何额外代码即可继续进行的方法。如果我们调用 System L&F(在我的例子中是 Windows),则 ALT 键会按预期运行。有关详细信息,请参阅 stackoverflow 问题 13474555。

      【讨论】:

      • 这应该是它自己的问题,并引用回这个问题,而不是这个问题的答案。
      【解决方案4】:

      我发现只要使用frame.setJMenuBar(jmenubar);,其中frame 是您的JFrame 而jmenubar 是您的JMenuBar,它会自动执行此操作。您甚至不必将其添加到布局管理器中。

      【讨论】:

        猜你喜欢
        • 2012-09-13
        • 2016-11-18
        • 2014-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多