--- title: Grouping Actions --- If an implementation requires several actions, or there are simply too many actions that overload the menu, the actions can be placed into groups. This tutorial demonstrates adding an action to an existing group, creating a new action group, and action groups with a variable number of actions. The sample code discussed in this tutorial is from the code sample `action_basics`. * bullet list {:toc} ## Simple Action Groups In this first example, the action group will be available as a top-level menu item, and actions are represented as drop-down menu items. The group is based on a default IntelliJ Platform implementation. ### Creating Simple Groups Grouping can be registered by adding a `` element to the `` section in [plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/action_basics/src/main/resources/META-INF/plugin.xml). This example has no `class` attribute in the `` element because the IntelliJ Platform framework will supply a default implementation class for the group. This default implementation is used if a set of actions belonging to the group is static, i.e. does not change at runtime, which is the majority of cases. The `id` attribute must be unique, so incorporating the plugin ID or package name is the best practice. The `popup` attribute determines whether actions in the group are placed in a submenu. The `icon` attribute specifies the FQN of an `Icon` object to be displayed. No `compact` attribute is specified. See []() for more information about these attributes. ```xml ``` ### Binding Action Groups to UI Components The following sample shows how to use an `` element to place a custom action group relative to an entry in the **Tools** menu. The attribute `relative-to-action` references the action `id` for `PopupDialogAction`, which is not a native IntelliJ menu entry. Rather `PopupDialogAction` is defined in the same [plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/action_basics/src/main/resources/META-INF/plugin.xml) file. The group is placed after the entry for the action `PopupDialogAction` - see [Creating Actions](working_with_custom_actions.md#registering-an-action-with-the-new-action-form) for the tutorial about placing this single action at the top of the **Tools** menu. ```xml ``` ### Adding a New Action to the Static Grouped Actions The `PopupDialogAction` implementation will be reused and registered in the newly created static group. The `id` attribute for the reused `PopupDialogAction` implementation is set to a unique value, `org.intellij.sdk.action.GroupPopDialogAction`. This value differentiates this new `` entry from the `id` previously used to register this action implementation in the [Creating Actions](working_with_custom_actions.md#registering-an-action-with-the-new-action-form) tutorial. A unique `id` supports reuse of action classes in more than one menu or group. The action in this group will display the menu text "A Group Action". ```xml ``` After performing the steps described above the action group and its content will be available in the **Tools** menu: ![Simple Action Group](img/grouped_action.png){:width="550px"} ## Implementing Custom Action Group Classes In some cases, the specific behavior of a group of actions needs to depend on the context. The steps below show how to make a group of actions available and visible if certain conditions are met. In this case, the condition is having an instance of an editor is available. This condition is needed because the custom action group will be added to an IntelliJ menu that is only enabled for editing. ### Extending DefaultActionGroup [`DefaultActionGroup`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java) is an implementation of [`ActionGroup`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionGroup.java). The `DefaultActionGroup` class is used to add child actions and separators between them to a group. This class is used if a set of actions belonging to the group does not change at runtime, which is the majority of cases. As an example, extend [`DefaultActionGroup`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java) to create the `CustomDefaultActionGroup` class in the `action_basics` code sample: ```java public class CustomDefaultActionGroup extends DefaultActionGroup { @Override public void update(AnActionEvent event) { // Enable/disable depending on whether user is editing... } } ``` ### Registering the Custom Action Group As in the case with the static action group, the action `` should be declared in the *``* section of the [plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/action_basics/src/main/resources/META-INF/plugin.xml) file. Note: * The presence of the `class` attribute in the `` element, which tells the IntelliJ Platform framework to use `CustomDefaultActionGroup` rather than the default implementation. * The `` element specifies adding the group in the first position of the existing `EditorPopupMenu`. ```xml ``` ### Adding Actions to the Custom Group As in [Static Grouped Actions](#adding-a-new-action-to-the-static-grouped-actions), the `PopupDialogAction` action is added as an `` element in the `` element. Note: * The `class` attribute in the `` element has the same FQN to reuse this action implementation. * The `id` attribute is unique to distinguish it from the use of the `PopupDialogAction` class in [Static Grouped Actions](#adding-a-new-action-to-the-static-grouped-actions). ```xml ``` ### Providing Specific Behavior for the Custom Group Override the `CustomDefaultActionGroup.update()` method to make the group visible only if there's an instance of the editor available. Also, a custom icon is added to demonstrate that icons can be changed depending on the action context: ```java public class CustomDefaultActionGroup extends DefaultActionGroup { @Override public void update(AnActionEvent event) { // Enable/disable depending on whether user is editing Editor editor = event.getData(CommonDataKeys.EDITOR); event.getPresentation().setEnabled(editor != null); // Take this opportunity to set an icon for the menu entry. event.getPresentation().setIcon(ActionBasicsIcons.Sdk_default_icon); } } ``` After compiling and running the code sample above and opening a file in the editor and right-clicking, the **Editing** menu will pop up containing a new group of actions in the first position. The new group will also have an icon: ![Custom Action Group](img/editor_popup_menu.png){:width="600px"} ## Action Groups with Variable Actions Sets If a set of actions belonging to a custom group will vary depending on the context, the group must extend [`ActionGroup`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionGroup.java). The set of actions in the `ActionGroup` is dynamically defined. ### Creating Variable Action Group To create a group of actions with a variable number of actions, extend `ActionGroup.java` to create the `DynamicActionGroup` class in the `action_basics` code sample: ```java public class DynamicActionGroup extends ActionGroup { } ``` ### Registering a Variable Action Group To register the dynamic menu group, a `` attribute needs to be placed in the `` section of [plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/action_basics/src/main/resources/META-INF/plugin.xml). When enabled, this group will appear at the entry just below the [Static Grouped Actions](#binding-action-groups-to-ui-components) in the **Tools** menu: ```xml ``` > **Note** If a`` element's `class` attribute names a class derived from `ActionGroup`, then any static `` declarations in the group will throw an exception. For a statically defined group, use `DefaultActionGroup`. ### Adding Child Actions to the Dynamic Group To add actions to the `DynamicActionGroup`, a non-empty array of `AnAction` instances should be returned from the `DynamicActionGroup.getChildren()` method. Here again, reuse the `PopupDialogAction` action class as an example. ```java public class DynamicActionGroup extends ActionGroup { @NotNull @Override public AnAction[] getChildren(AnActionEvent e) { return new AnAction[]{ new PopupDialogAction("Action Added at Runtime", "Dynamic Action Demo", ActionBasicsIcons.Sdk_default_icon) }; } } ``` After providing the implementation of `DynamicActionGroup` and making it return a non-empty array of actions, the third position in the **Tools** Menu will contain a new group of actions: ![Dynamic Action Group](img/dynamic_action_group.png){:width="600px"}