执行和更新插件
交互系统允许插件向IDEA的菜单和工具栏插入它们自己的元素。一个交互是一个继承了AnAction类的子类型,其actionPerformed方法将在(插入的)菜单项或工具栏按钮被点选时调用。例如,一个交互类负责”File | Open File…”菜单项和”Open File”工具栏按钮。
交互被按组(group)管理,一个组也可以包含其他的组。一组交互可以构成一个工具栏或一组菜单。子组可对应构成菜单的子菜单。
每个交互和交互组都拥有唯一的标识符。IdeActions类中定义了许多标准IDEA交互的标识符。
一个交互可以包含在多个组中,所以可以出现在IDEA用户界面的多个位置。交互可以出现的不同的位置在接口ActionPlaces中以常量的形式定义。在交互出现的每一个位置,都会创建一个新的Presentation对象。因此,同一个交互在用户界面的不同位置出现时可以有不同的文本或图标。交互通过复制AnAction.getTemplatePresentation()返回的Presentationc对象来创建不同的presentation。
IDEA定期调用AnAction.update()方法来更新交互的状态。传递给此方法的AnActionEvent类型对象携带了交互的当前上下文信息,尤其是需要更新的指定的presentation信息。
要检索活动project、选中的文件、编辑器中选中状态等IDE的当前状态信息,可以使用AnActionEvent.getData()方法。DataKeys类中定义了可以传递给此方法的不同数据键值。
AnActionEvent实例也会传递到actionPerformed方法。
注册交互
有两种方式注册一个交互:要么在plugin.xml文件的<actions>小节列出,或者通过Java代码。
在plugin.xml中注册交互
在plugin.xml中注册交互在如下的示例中示范。此plugin.xml示例片段展示了所有在<actions>小节中可用的元素并描述了各元素的意义。
<!-- Actions --> <actions> <!-- The <action> element defines an action to register. The mandatory "id" attribute specifies an unique identifier for the action. The mandatory "class" attribute specifies the full-qualified name of the class implementing the action. The mandatory "text" attribute specifies the text of the action (tooltip for toolbar button or text for menu item). The optional "use-shortcut-of" attribute specifies the ID of the action whose keyboard shortcut this action will use. The optional "description" attribute specifies the text which is displayed in the status bar when the action is focused. The optional "icon" attribute specifies the icon which is displayed on the toolbar button or next to the menu item. --> <action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector" icon="icons/garbage.png"> <!-- The <add-to-group> node specifies that the action should be added to an existing group. An action can be added to several groups. The mandatory "group-id" attribute specifies the ID of the group to which the action is added. The group must be implemented by an instance of the DefaultActionGroup class. The mandatory "anchor" attribute specifies the position of the action in the group relative to other actions. It can have the values "first", "last", "before" and "after". The "relative-to-action" attribute is mandatory if the anchor is set to "before" and "after", and specifies the action before or after which the current action is inserted. --> <add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/> <!-- The <keyboard-shortcut> node specifies the keyboard shortcut for the action. An action can have several keyboard shortcuts. The mandatory "first-keystroke" attribute specifies the first keystroke of the action. The key strokes are specified according to the regular Swing rules. The optional "second-keystroke" attribute specifies the second keystroke of the action. The mandatory "keymap" attribute specifies the keymap for which the action is active. IDs of the standard keymaps are defined as constants in the com.intellij.openapi.keymap.KeymapManager class. --> <keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/> <!-- The <mouse-shortcut> node specifies the mouse shortcut for the action. An action can have several mouse shortcuts. The mandatory "keystroke" attribute specifies the clicks and modifiers for the action. It is defined as a sequence of words separated by spaces: "button1", "button2", "button3" for the mouse buttons; "shift", "control", "meta", "alt", "altGraph" for the modifier keys; "doubleClick" if the action is activated by a double-click of the button. The mandatory "keymap" attribute specifies the keymap for which the action is active. IDs of the standard keymaps are defined as constants in the com.intellij.openapi.keymap.KeymapManager class. --> <mouse-shortcut keystroke="control button3 doubleClick" keymap="$default"/> </action> <!-- The <group> element defines an action group. <action>, <group> and <separator> elements defined within it are automatically included in the group. The mandatory "id" attribute specifies an unique identifier for the action. The optional "class" attribute specifies the full-qualified name of the class implementing the group. If not specified, com.intellij.openapi.actionSystem.DefaultActionGroup is used. The optional "text" attribute specifies the text of the group (text for the menu item showing the submenu). The optional "description" attribute specifies the text which is displayed in the status bar when the group is focused. The optional "icon" attribute specifies the icon which is displayed on the toolbar button or next to the group. The optional "popup" attribute specifies how the group is presented in the menu. If a group has popup="true", actions in it are placed in a submenu; for popup="false", actions are displayed as a section of the same menu delimited by separators. --> <group class="com.foo.impl.MyActionGroup" id="TestActionGroup" text="Test Group" description="Group with test actions" icon="icons/testgroup.png" popup="true"> <action id="VssIntegration.TestAction" class="com.foo.impl.TestAction" text="My Test Action" description="My test action"/> <!-- The <separator> element defines a separator between actions. It can also have an <add-to-group> child element. --> <separator/> <group id="TestActionSubGroup"/> <!-- The <reference> element allows to add an existing action to the group. The mandatory "ref" attribute specifies the ID of the action to add. --> <reference ref="EditorCopy"/> <add-to-group group-id="MainMenu" relative-to-action="HelpMenu" anchor="before"/> </group> </actions>
在代码中注册交互
在代码中注册交互需要两步。第一步,必须向ActionManager类的registerAction方法传递一个继承AnAction类的类的实例来关联交互和其ID。第二步,交互需要必添加到一个或更多交互组中。要通过ID获取一个交互组的实例,必须调用ActionManager.getAction()方法并将返回值转换为DefaultActionGroup类型。
你可以通过如下过程创建一个在IDEA启动时注册其交互的插件。
IDEA启动时注册交互
- 创建一个实现ApplicationComponent接口的类。
- 在这个类中,重写getComponentName、initComponent和disposeComponent方法。
- 在plugin.xml文件的<application-components>小节注册这个类。
为详述上述过程,参考如下的示例Java类MyPluginRegistration,其注册了一个定义了一个自定义TextBox的交互并向主菜单的Window菜单组添加了一个新的菜单命令:
public class MyPluginRegistration implements ApplicationComponent { // Returns the component name (any unique string value). @NotNull public String getComponentName() { return "MyPlugin"; } // If you register the MyPluginRegistration class in the <application-components> section of // the plugin.xml file, this method is called on IDEA start-up. public void initComponent() { ActionManager am = ActionManager.getInstance(); TextBoxes action = new TextBoxes(); // Passes an instance of your custom TextBoxes class to the registerAction method of the ActionManager class. am.registerAction("MyPluginAction", action); // Gets an instance of the WindowMenu action group. DefaultActionGroup windowM = (DefaultActionGroup) am.getAction("WindowMenu"); // Adds a separator and a new menu command to the WindowMenu group on the main menu. windowM.addSeparator(); windowM.add(action); } // Disposes system resources. public void disposeComponent() { } }
注意,示例的TextBoxes类在此处给出。
为了保证你的插件在IDEA启动时被初始化,在plugin.xml文件的<application-components>小节做如下修改:
<application-components> <!-- Add your application components here --> <component> <implementation-class>MypackageName.MyPluginRegistration</implementation-class> </component> </application-components>
打造交互用户界面
如果一个插件需要在它自己的用户界面中包含由一组交互构成的一个工具栏或一组弹出菜单,可以通过ActionPopupMenu和ActionToolbar类完成。这些对象可以通过调用ActionManager.createActionPopupMenu和ActionManager.createActionToolbar方法创建。要从这样一个对象中获取一个Swing组件,只要简单的调用getComponent()方法。
如果你的交互工具栏附加在一个指定的组件上(例如,一个ToolWindow里的一个面板),你通常需要调用ActionToolbar.setTargetComponent()方法并将要关联的组件实例作为参数。这将保证工具栏按钮的状态依赖于相关联的组件状态,而不是当前IDE窗体中焦点的位置(的组件状态)。
原文链接:IntelliJ IDEA Action System