Сосредоточиться на первом элементе jmenubar при нажатии клавиши "alt"

Есть ли способ автоматически выбрать jmenu в моем jmenubar, когда пользователь нажимает клавишу "ALT"? (Как программы для Windows)

Проблема заключается в том, что поведение моего jframe по умолчанию при нажатии клавиши "ALT" состоит в отображении меню, содержащего следующие действия: восстановление, перемещение, изменение размера, уменьшение, ...

Я хочу, чтобы мое java-приложение выбрало первый элемент jmenu при нажатии "alt". (Как и в случае с мнемоникой: "alt + f")

4 ответа

Решение

Добавьте действие к ActionMap а также InputMap вашей JRootPane, Увидеть ниже:

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


}

Я нашел только с помощью frame.setJMenuBar(jmenubar); где frame твой JFrame и jmenubar ваш JMenuBar, он автоматически сделает это. Вам даже не нужно добавлять его в свой менеджер макета.

Используйте карту действий и карту ввода JComponent, чтобы сделать эту работу. Поскольку 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");

Я нашел ответ очень полезным, но и с недостатком.

Представьте, что вы используете Cross PlatForm L&F (Metal) и вы определили мнемонику для всех меню; Вы знаете, что эти меню вызываются против нажатия. Итак, если мы поставим решение, предоставленное черной пандой, результаты при нажатии будут в первую очередь смотреть на развернутое нужное меню, но сразу после переключения на первое меню.

Я думаю, что наилучшим способом было бы нажатие ALT, при этом должно быть выбрано только первое меню, но без отображения его содержимого (это содержимое должно появляться при нажатии клавиши "вниз"). Есть ли способ сделать это в Cross Platform L&F?

В качестве альтернативы есть другой способ продолжить без какого-либо дополнительного кода. Если мы вызываем System L&F (в моем случае Windows), клавиша ALT ведет себя как нужно. См. Вопрос stackru 13474555 для деталей.

Другие вопросы по тегам