Search code examples
intellij-ideaintellij-plugin

Change action group with modifier key


I have an action group with a number of actions inside it. Similar to the list of run configurations that appears when you press Ctrl + Shift + F10, I want a different action (or a variation of the action) to be executed when the user holds Shift while selecting an action.

Sadly, neither the documentation nor the code examples were able to help me much. I wasn't able to find the source code of the above-mentioned run configurations action group either.

Of course, I've tried the obvious solutions:

  • Checking the value of event.getModifiers() inside actionPerformed(ActionEvent).
  • Adding a KeyListener to the popup that contains the list of actions.

While the first solution works when the action is clicked on in the menu, it doesn't work when selecting it with Shift + Enter. In fact, I can't even catch any key events because they seem to be caught by the speed search instead.

How do I change an action group's behaviour based on modifier keys?


Solution

  • Thanks to Meo I've found an answer.

    I had the following code to create a popup containing a list of actions:

    final ListPopup popup = JBPopupFactory.getInstance()
            .createActionGroupPopup(...); // some parameters here
    

    By changing that code to the following, pressing Shift + Enter will select the currently highlighted option and pass the correct modifiers to the action's actionPerformed method:

    final ListPopupImpl popup = (ListPopupImpl) JBPopupFactory.getInstance()
            .createActionGroupPopup(...); // some parameters here
    
    popup.registerAction("invokeAction", KeyStroke.getKeyStroke("shift ENTER"),
            new AbstractAction() {
                @Override
                public void actionPerformed(final ActionEvent event) {
                    final KeyEvent keyEvent
                            = new KeyEvent(popup.getComponent(), event.getID(),
                                           event.getWhen(), event.getModifiers(),
                                           KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED,
                                           KeyEvent.KEY_LOCATION_UNKNOWN);
                    popup.handleSelect(true, keyEvent);
                }
            });
    

    Additionally, to change the title of the menu based on whether the key is being held:

    popup.registerAction("shiftReleased", KeyStroke.getKeyStroke("released SHIFT"), new AbstractAction() {
        public void actionPerformed(final ActionEvent event) {
            popup.setCaption("Normal title");
        }
    });
    popup.registerAction("shiftPressed", KeyStroke.getKeyStroke("shift pressed SHIFT"), new AbstractAction() {
        public void actionPerformed(final ActionEvent event) {
            popup.setCaption("Shift is pressed title");
        }
    });