Search code examples
javaswingactionkey-bindings

Change modifier of mnemonic in Java


The code below is part of a method that creates a JPopupMenu (not shown) which has a few options like undo, redo, cut, copy, paste, etc...

JMenuItem redoItem = new JMenuItem(new PrintAction());
redoItem.setText("Redo");
redoItem.setMnemonic(KeyEvent.VK_Y);
popupMenu.add(redoItem);
    
JMenuItem cutItem = new JMenuItem(new DefaultEditorKit.CutAction());
cutItem.setText("Cut");
cutItem.setMnemonic(KeyEvent.VK_X);
popupMenu.add(cutItem);

The PrintAction class is only used for debugging purposes, but this is where I'd normally put the RedoAction class

public class PrintAction extends AbstractAction {
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        System.out.println("Yay it worked!");
    }
}

As you can see, I've set the mnemonic for the "Redo" action as Y, and the "Cut" action as X.

I'm using the built-in method CutAction from the DefaultEditorKit, which automatically sets my modifier to control, and cuts the text exactly when I want it. (CTRL + X)

Here's the issue: since my redoItem does NOT use DefaultEditorKit, it defaults the modifier to ALT, and only redos the text when the popupMenu is showing. (ALT + Y)

cutItem works exactly the way I want it. How should I make the redoItem with the same features? I want (CTRL + Y) instead of (ALT + Y) and to use the action without having popupMenu open.

I have read the forum with a similar title here, but it does not have a proper answer.


Solution

  • Text components have a default key bindings for the basic cut, copy, paste Actions, which is why CTRL + X works.

    See: Key Bindings for a program to display the default key bindings for all Swing components.

    You are confusing a mnemonic with an accelerator.

    The mnemonic is how you invoke the Action when the menu item is visible. It will be the underlined character in the menu item text. This is why you only specify the character for the mnemonic. The key used to invoke the mnemonic is OS dependent. In the case of Windows you use the Alt key.

    The accelerator allows you to invoke the Action when the menu is closed, so it saves the user from first displaying the menu. It will be the KeyStroke displayed on the right of the menu item text. You can specify any KeyStroke combination, but typically in Windows you would use Ctrl + "some other key".

    If you want your Redo Action to be invoked with CTRL + Y then you need to add an accelerator to the menu item using one of the following approaches:

    1. Add the accelerator directly to the component. Read the section from the Swing tutorial on How to Use Menus for more information.

    2. You can also add an "accelerator" to the Action. Read the tutorial on How to Use Actions. This would be the preferred approach as the properties of the Action should default to the component. So you can use the Action to create a JMenuItem or a JButton and the relevant properties of the Action will be applied to the component.