Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can multiple accelerators be defined for a JMenuItem?

Tags:

java

swing

I've a problem with setAccelerator(). Right now, I have the code that works for Ctrl+X for DELETE operation. I want to set the accelerator to Shift+Delete as well for same JMenuItem.

My code as follows:

JMenuItem item = new JMenuItem(menuText);
item.setAccelerator(KeyStroke.getKeyStroke(
    KeyEvent.VK_X, KeyEvent.CTRL_MASK));
item.setAccelerator(KeyStroke.getKeyStroke(
    KeyEvent.VK_DELETE, KeyEvent.SHIFT_MASK));

but this is working only for Shift+Delete operation. Seems it is overriding the Ctrl+X operation. Can we make both these keystrokes work at the same time?

Please guide.

like image 668
Santhi Avatar asked Dec 22 '09 12:12

Santhi


2 Answers

Yes it can be done. Behind the scenes the setAccelerator() is just creating a Key Binding, however as you noticed the second binding replaces the first.

So, you need to create an Action (not an ActionListener) to add the to the menu item. Read the section from the Swing tutorial on How to Use Actions for more information. Now that you have created the Action, you can share the Action with another KeyStroke by manually creating a Key Binding. You can read the section from the Swing tutorial on How to Use Key Bindings for a detailed explanation. Or you can read my blog on Key Bindings which give some simple code examples.

This second binding will not show up on the menu item itself.

like image 198
camickr Avatar answered Nov 05 '22 16:11

camickr


From: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/AWTEvent.html

The masks are also used to specify to which types of events an AWTEventListener should listen.

So you can combine the mask for two keys, but not the KeyEvents.

item.setAccelerator( 
    KeyStroke.getKeyStroke(
       KeyEvent.VK_X, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));

A workaround solution would be to catch the KeyEvent in the middle (after your component fired it, but before your listeners will act on it) and check, whether its one of the two combinations. Then fire one event, on which you programmatically agree to represent the action you wanted.

like image 20
miku Avatar answered Nov 05 '22 15:11

miku