2

Example code:

public class FrameMenuTextFieldTest {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final JFrame frame = new JFrame();
                frame.getContentPane().add(new JTextField());
                JMenuBar menubar = new JMenuBar();
                JMenu menu = new JMenu("Menu");
                JMenuItem item = new JMenuItem("Item1");
                item.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(frame, "Menu Item clicked");
                    }
                });
                item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_5, 0));
                menu.add(item);
                menubar.add(menu);
                frame.setJMenuBar(menubar);
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

}

The problem here is if I type 5 into the textfield, not only the textfield gets this event, but the menu item as well, and its action is performed; message shown.

What is the simplest way to disable the key event propagation to the menu bar?

I my real application, I have a lot of menu items to disable for a few textfields.

kavai77
  • 6,282
  • 7
  • 33
  • 48
  • I think its not possible without using any modifier. Can you specify in your post that you **don't want to use any modifier**. So that you can get the corrected answer. – Braj Jun 12 '14 at 15:31
  • Even if you specify a modifier, e.g. **SHIFT+5**, and type **SHIFT+5** inside the textfield, the menu item's action will be preformed. – kavai77 Jun 12 '14 at 15:37

1 Answers1

4

Bind the JMenuItem with some modifiers such as Ctrl, Alt, Shift etc. if possible as mentioned here KeyStroke#getKeyStroke().

Try something like as shown below to bind it with Ctrl+5.

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_5, InputEvent.CTRL_DOWN_MASK));

EDIT

It might help you if you don't want to use any modifier.

If the current focusable component is not JTextField then perform action on JMenuItem.

Sample code:

JMenuItem item = new JMenuItem("Item1");
item.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        Component component = frame.getFocusOwner();
        if (!(component instanceof JTextField)) {
            JOptionPane.showMessageDialog(frame, "Menu Item clicked");
        }
    }
});

Read more here on In Swing, how can I find out what object currently has focus?

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • It there any serious issue with post. Please leave comments so that I can learn it. – Braj Jun 12 '14 at 15:29
  • Sorry, this is not a solution: I don't want CTRL, I want only the 5 as an accelerator. Also if I press CTRL+5 inside the textfield, the message is also shown. – kavai77 Jun 12 '14 at 15:30
  • OK let me try if possible. – Braj Jun 12 '14 at 15:30
  • 1
    Thanks, good idea! I am still waiting for a little bit maybe to have a global solution for all the menu items in a menu or menu bar, because I have a lot of items and doing this one by one would be awful. – kavai77 Jun 12 '14 at 15:43
  • Awesome! your fix worked for me after I had been banging my head against the wall for the past hour! – Jman Oct 08 '21 at 17:29