Kenster
Kenster

Reputation: 25458

Action event not firing for JMenuItem accelerator keystroke?

I have a simple java swing application. It's mostly used on Macos, so I'm trying to add a default menu bar to it through Desktop.getDesktop().setDefaultMenuBar(...). I defined a menu bar with a "File" menu and a "New" menu item with an action listener. Using the mouse to click on File->New calls the listener's actionPerformed() event as expected.

I tried to attach the standard accelerator to the menu item (Command-N on a mac). Clicking on the "File" menu now displays "New" with the expected accelerator next to it. However, when I actually type Command-N, the action listener isn't called. The only visible effect of typing Command-N is that the "File" menu item briefly flickers.

Edit: This seems to be related to the fact the menu is being set through Desktop.setDefaultMenuBar(). If I attach the menu to the JFrame, then accelerators work correctly. However, I'm using Desktop.setDefaultMenuBar() to define a menu that appears even when no other windows are open.

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

The call to Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() is based on this blog entry.

Can anyone see what I'm doing wrong?

I'm testing with Amazon coretto 11 if it matters.

Upvotes: 4

Views: 338

Answers (0)

Related Questions