--- title: Action System --- ## Introduction The actions system is an extension point that allows plugins to add their items to IntelliJ Platform-based IDE menus and toolbars. For example, one of the action classes is responsible for the **File \| Open File...** menu item and for the **Open File** toolbar button. Actions in the IntelliJ Platform require a [code implementation](#action-implementation) and must be [registered](#registering-actions) with the IntelliJ Platform. The action implementation determines the contexts in which an action is available, and its functionality when it is selected in the UI. Registration determines where an action appears in the IDE UI. Once implemented and registered, an action receives callbacks from the IntelliJ Platform in response to user gestures. The [Creating Actions](/tutorials/action_system/working_with_custom_actions.md) tutorial describes the process of adding a custom action to a plugin. The [Grouping Actions](/tutorials/action_system/grouping_action.md) tutorial demonstrates three types of groups that can contain actions. The rest of this page is an overview of actions as an extension point. * bullet list {:toc} ## Action Implementation An action is a class derived from the abstract class [`AnAction`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java). The IntelliJ Platform calls methods of an action when a user interacts with a menu item or toolbar button. > **Warning** Classes based on `AnAction` do not have class fields of any kind. This is because an instance of `AnAction` class exists for the entire lifetime of the application. If `AnAction` class uses a field to store data that has a shorter lifetime, and doesn't clear this data promptly, the data will be leaked. For example, any `AnAction` data that exists only within the context of a `Project` will cause the `Project` to be kept in memory after the user has closed it. ### Principal Implementation Overrides Every IntelliJ Platform action should override `AnAction.update()` and must override `AnAction.actionPerformed()`. * An action's method `AnAction.update()` is called by the IntelliJ Platform framework to update the state of an action. The state (enabled, visible) of an action determines whether the action is available in the UI of an IDE. An object of type [`AnActionEvent`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) is passed to this method, and it contains the information about the current context for the action. Actions are made available by changing state in the [Presentation](upsource:///platform/platform-api/src/com/intellij/ide/presentation/Presentation.java) object associated with the event context. As explained in [Overriding the `AnAction.update()` Method](#overriding-the-anactionupdate-method), it is vital `update()` methods _execute quickly_ and return execution to the IntelliJ Platform. * An action's method `AnAction.actionPerformed()` is called by the IntelliJ Platform if it is available and selected by the user. This method does the heavy lifting for the action - it contains the code to be executed when the action is invoked. The `actionPerformed()` method also receives `AnActionEvent` as a parameter, which can be used to access projects, files, selection, etc. See [Overriding the `AnAction.actionPerformed()` Method](#overriding-the-anactionactionperformed-method) for more information. There are other methods to override in the `AnAction` class, such as for changing the default `Presentation` object for the action. There is also a use case for overriding action constructors when registering them with dynamic action groups, which is demonstrated in the [Grouping Actions](/tutorials/action_system/grouping_action.md#adding-child-actions-to-the-dynamic-group) tutorial. However, the `update()` and `actionPerformed()` methods are essential to basic operation. ### Overriding the AnAction.update Method The method `AnAction.update()` is periodically called by the IntelliJ Platform in response to user gestures. The `update()` method gives an action to evaluate the current context and enable or disable its functionality. > **Warning** The `AnAction.update()` method can be called frequently, and on a UI thread. This method needs to _execute very quickly_; no real work should be performed in this method. For example, checking selection in a tree or a list is considered valid, but working with the file system is not. > **Tip** If the new state of an action cannot be determined quickly, then evaluation should be performed in the `AnAction.actionPerformed()` method, and notify the user that the action cannot be executed if the context isn't suitable. #### Determining the Action Context The `AnActionEvent` object passed to `update()` carries information about the current context for the action. Context information is available from the methods of `AnActionEvent`, providing information such as the Presentation, and whether the action is triggered from a Toolbar. Additional context information is available using the method `AnActionEvent.getData()`. Keys defined in [`CommonDataKeys`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CommonDataKeys.java) are passed to the `getData()` method to retrieve objects such as `Project`, `Editor`, `PsiFile`, and other information. Accessing this information is relatively light-weight and is suited for `AnAction.update()`. #### Enabling and Setting Visibility for an Action Based on information about the action context, the `AnAction.update()` method can enable, disable, or hide an action. An action's enable/disable state and visibility are set using methods of the `Presentation` object, which is accessed using `AnActionEvent.getPresentation()`. The default `Presentation` object is a set of descriptive information about a menu or toolbar action. Every context for an action - it might appear in multiple menu or toolbar locations - has a unique presentation. Attributes such as an action's text, description, and icons, as well as visibility and enable/disable state, are stored in the presentation. The attributes in a presentation get initialized from the [action registration](#registering-actions). However, some can be changed at runtime using the methods of the `Presentation` object associated with an action. The enabled/disabled state of an action is set using `Presentation.setEnabled()`. The visibility state of an action is set using `Presentation.setVisible()` If an action is enabled, the `AnAction.actionPerformed()` can be called if an action is selected in the IDE by a user. A menu action will be shown in the UI location specified in the registration. A toolbar action will display its enabled (or selected) icon, depending on the user interaction. When an action is disabled `AnAction.actionPerformed()` will not be called. Toolbar actions will display their respective icons for the disabled state. The visibility of a disabled action in a menu depends on whether the host menu (e.g. "ToolsMenu") containing the action has the `compact` attribute set. See [Grouping Actions](#grouping-actions) for more information about the `compact` attribute, and the visibility of menu actions. > **Note** If an action is added to a toolbar, its `update()` can be called if there was any user activity or focus transfer. If the action's availability changes in the absence of these events, then call [`ActivityTracker.getInstance().inc()`](upsource:///platform/platform-api/src/com/intellij/ide/ActivityTracker.java) to notify the action subsystem to update all toolbar actions. An example of enabling a menu action based on whether a project is open is demonstrated in [`PopupDialogAction.update()`](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java) method. ### Overriding the AnAction.actionPerformed Method When the user selects an enabled action, be it from a menu or toolbar, the action's `AnAction.actionPerformed()` method is called. This method contains the code to be executed to perform the action, and it is here that the real work gets done. Using the `AnActionEvent` methods and `CommonDataKeys`, objects such as the `Project`, `Editor`, `PsiFile`, and other information is available. For example, the `actionPerformed()` method can modify, remove, or add PSI elements to a file open in the editor. The code that executes in the `AnAction.actionPerformed()` method should execute efficiently, but it does not have to meet the same stringent requirements as the `update()` method. An example of inspecting PSI elements is demonstrated in the SDK code sample `action_basics` [`PopupDialogAction.actionPerformed()`](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/action_basics/src/main/java/org/intellij/sdk/action/PopupDialogAction.java) method. ### Action IDs Every action and action group has a unique identifier. Basing the identifier for a custom action on the FQN of the implementation is the best practice, assuming the package incorporates the `` of the plugin. An action must have a unique identifier for each place it is used in the IDE UI, even though the FQN of the implementation is the same. Definitions of identifiers for the standard IntelliJ Platform actions are in [`IdeActions`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java). ### Grouping Actions Groups organize actions into logical UI structures, which in turn can contain other groups. A group of actions can form a toolbar or a menu. Subgroups of a group can form submenus of a menu. Actions can be included in multiple groups, and thus appear in multiple places within the IDE UI. An action must have a unique identifier for each place it appears in the IDE UI. The places where actions can appear are defined by constants in [`ActionPlaces`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java). Group IDs for the IntelliJ Platform are defined in [PlatformActions](upsource:///platform/platform-resources/src/idea/PlatformActions.xml). For every place where the action appears, a new [`Presentation`](upsource:///platform/platform-api/src/com/intellij/ide/presentation/Presentation.java) is created. Therefore the same action can have different text or icons when it appears in different places of the user interface. Different presentations for the action are created by copying the Presentation returned by the `AnAction.getTemplatePresentation()` method. A group's "compact" attribute specifies whether an action within that group is visible when disabled. See [Registering Actions in plugin.xml](#registering-actions-in-pluginxml) for an explanation of how the `compact` attribute is set for a group. If the `compact` attribute is `true` for a menu group, an action in the menu will only appear if its state is both enabled and visible. In contrast, if the `compact` attribute is `false`, an action in the menu will appear if its state is disabled but visible. Some menus like **Tools** have the `compact` attribute set, so there isn't a way to show an action on the tools menu if it is not enabled. | Host Menu
`compact` Setting | Action Enabled | Visibility Enabled | Menu Item Visible? | Menu Item Appears Gray? | | :-----: | :------------: | :----------------: | :----------------: | :---------------------: | | F | T | T | T | F | | F | T | F | F | x | | ***F*** | F | T | ***T*** | ***T*** | | F | F | F | F | x | | T | T | T | T | F | | T | T | F | F | x | | ***T*** | F | T | ***F*** | x | | T | F | F | F | x | See the [Grouping Actions](/tutorials/action_system/grouping_action.md) tutorial for examples of creating action groups. ## Registering Actions There are two main ways to register an action: either by listing it in the `` section of a plugin's `plugin.xml` file, or through code. ### Registering Actions in plugin.xml Registering actions in `plugin.xml` is demonstrated in the following example, which documents all elements and attributes that can be used in the `` section, and describes the meaning of each element. This information can also be found by using the [Code Completion](https://www.jetbrains.com/help/idea/auto-completing-code.html#invoke-basic-completion), [Quick Definition](https://www.jetbrains.com/help/idea/viewing-reference-information.html#view-definition-symbols) and [Quick Documentation](https://www.jetbrains.com/help/idea/viewing-reference-information.html#inline-quick-documentation) features. ```xml ``` ### Registering Actions from Code Two steps are required to register an action from code: * First, an instance of the class derived from `AnAction` must be passed to the `registerAction()` method of [`ActionManager`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java), to associate the action with an ID. * Second, the action needs to be added to one or more groups. To get an instance of an action group by ID, it is necessary to call `ActionManager.getAction()` and cast the returned value to [`DefaultActionGroup`](upsource:///platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java). ## Building UI from Actions If a plugin needs to include a toolbar or popup menu built from a group of actions in its user interface, that is accomplished through [`ActionPopupMenu`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionPopupMenu.java) and [`ActionToolbar`](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionToolbar.java). These objects can be created through calls to the `ActionManager.createActionPopupMenu()` and `createActionToolbar()` methods. To get a Swing component from such an object, call the respective `getComponent()` method. If an action toolbar is attached to a specific component (for example, a panel in a tool window), call `ActionToolbar.setTargetComponent()` and pass the instance of the related component as a parameter. Setting the target ensures that the state of the toolbar buttons depends on the state of the related component, and not on the current focus location within the IDE frame.