Событие действия не запускается при нажатии клавиши акселератора JMenuItem? - PullRequest
2 голосов
/ 27 сентября 2019

У меня есть простое приложение Java Swing.Он в основном используется на Macos, поэтому я пытаюсь добавить к нему строку меню по умолчанию через Desktop.getDesktop().setDefaultMenuBar(...).Я определил строку меню с меню «Файл» и «Новый» пункт меню с прослушивателем действий.Используя мышь, чтобы щелкнуть File-> New, вызывается событие слушателя actionPerformed(), как и ожидалось.

Я попытался прикрепить стандартный ускоритель к пункту меню (Command-N на Mac).При нажатии на меню «Файл» теперь отображается «Новый» с ожидаемым ускорителем рядом с ним.Однако, когда я на самом деле набираю Command-N, слушатель действия не вызывается.Единственным видимым эффектом ввода Command-N является кратковременное мигание пункта меню «Файл».

Редактировать: Это, похоже, связано с тем, что меню настраивается через Desktop.setDefaultMenuBar().Если я присоединяю меню к JFrame, то ускорители работают правильно.Однако я использую Desktop.setDefaultMenuBar() для определения меню, которое появляется, даже когда другие окна не открыты.

import java.awt.Desktop;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Scratch {
    static class MainMenu extends JMenuBar implements ActionListener {

        public MainMenu() {
            JMenu fileMenu = new JMenu("File");
            fileMenu.setMnemonic(KeyEvent.VK_F);

            int keyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();

            JMenuItem item = new JMenuItem("New");
            item.setMnemonic(KeyEvent.VK_N);
            item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, keyMask));
            item.addActionListener(this);
            fileMenu.add(item);

            this.add(fileMenu);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            System.err.println("actionPerformed " + e);
        }
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Hello Stackoverflow!");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel("Hello Stackoverflow!");
        frame.getContentPane().add(label);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Desktop.getDesktop().setDefaultMenuBar(new MainMenu());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Звонок на Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() основан на этой записи в блоге .

Кто-нибудь может увидеть, что я делаю неправильно?

Я тестирую с Amazon coretto 11 , если это имеет значение.

...