Сосредоточиться на первом элементе jmenubar при нажатии клавиши «alt» - PullRequest
2 голосов
/ 28 декабря 2011

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

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

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

Ответы [ 4 ]

7 голосов
/ 28 декабря 2011

Добавьте действие к 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);
    }


}
0 голосов
/ 19 февраля 2015

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

0 голосов
/ 02 июля 2013

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

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

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

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

0 голосов
/ 28 декабря 2011

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