How to add an action group (com.intellij.openapi.actionSystem.ActionGroup) to a custom JBPopupMenu?

Answered

In the context of the CSV plugin, the scenario is as follow: I have an com.intellij.openapi.actionSystem.ActionGroup defined and registered for the context menu in the text-editor. Everything shows and works fine (first screenshot).

Additionally the CSV plugin comes with a table editor (custom swing component), which comes with an own custom context menu (JBPopupMenu) created by the table editor component itself (second screenshot).

Now I'd like to add the the very same ActionGroup and its functionality to this menu, which I currently struggle to do. I tried using the ActionManager.createActionPopupMenu/-.createActionToolbar/-.createButtonToolbar (http://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html?search=action#building-ui-from-actions) without success. That's what I basically tried to do (with some variants and also using ActionToolbar/ButtonToolbar components):

ActionManager actionManager = ActionManager.getInstance();
CsvChangeSeparatorActionGroup csvChangeSeparatorActionGroup = (CsvChangeSeparatorActionGroup)actionManager.getAction(CsvChangeSeparatorActionGroup.class.getName());
ActionPopupMenu actionPopupMenu = actionManager.createActionPopupMenu("My Action Group", csvChangeSeparatorActionGroup);
popupMenu.add(actionPopupMenu.getComponent());

I guess I need to provide some additional context information to the ActionGroup? How to add the ActionGroup to the `popupMenu` properly?

0
4 comments

Is the table editor popup not defined in your plugin.xml? Then you can just refer to it in other action groups in your plugin.xml without any code.

0

No, I wasn't aware that this is an option. Do you have any documentation or example regarding this? I am aware of the docu I linked in my initial thread, but I couldn't find any reference or hint regarding custom editor popup menu registration. Thanks!

0

See the sample XML on the SDK docs page linked above, you can just nest <group> of existing group to refer to it

0

*To help others understand and for later reference*

The solution is to define the whole popup menu in the plugin.xml (not only the re-used actions) as a <group>

<group id="CsvTableEditorRowContextMenu"
popup="true"
>
</group>
<action class="..."
id="MyDeleteSelectedRows"
text="Delete selected rows"
icon="/media/icons/remove-row.png"
>
<add-to-group group-id="CsvTableEditorColumnContextMenu" />
<add-to-group group-id="CsvTableEditorRowContextMenu" />
</action>

and use the ActionManager to create the popup menu:

protected JPopupMenu getRowPopupMenu() {
if (rowPopupMenu == null) {
ActionManager actionManager = ActionManager.getInstance();
ActionGroup rowContextMenu = (ActionGroup) actionManager.getAction(ROW_CONTEXT_MENU_ID);
ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ROW_CONTEXT_MENU_ID, rowContextMenu);
rowPopupMenu = popupMenu.getComponent();
}
return rowPopupMenu;
}

Actions and other groups can be configured in plugin.xml to be part of this menu as well. NOTE: Don't add (AWT) menu items programmatically (e.g. rowPopupMenu.add(new MenuItem(...))) to the created JPopupMenu.

The important part in my case: The initially defined custom actions were meant and usable for a certain Editor implementation only so I didn't mind to declare them via the IntelliJ actionSystem. However, when defining an action, the corresponding Editor can be retrieved via DataContext PlatformDataKeys.FILE_EDITOR:

@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
getTableEditor(anActionEvent).doSomeCustomAction();
}
public CsvTableEditor getTableEditor(@NotNull AnActionEvent anActionEvent) {
return (CsvTableEditor)anActionEvent.getData(PlatformDataKeys.FILE_EDITOR);
}

and the operations can be performed on the retrieved editor if necessary.

0

Please sign in to leave a comment.