原文链接:
http://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html
执行和更新操作
操作体系允许插件向IDEA添加自己的菜单项和工具栏按钮。一个操作就是一个派生自AnAction
类的类,当选择菜单项或点击工具栏按钮时,它的actionPerformed
方法就会被调用。例如,其中一个操作类就是负责文件|打开文件...菜单项和打开文件 工具栏按钮的。
操作被组织成组,其又可以包含其他组。 一组操作可以形成工具栏或菜单。
组的子组可以形成菜单的子菜单。
每个操作和操作组都有一个唯一的标识符。标准IDEA操作的标识符在IdeActions类中定义。
每个操作都可以包含在多个组中,因此一个操作会出现在IDEA用户界面中的多个位置。操作可以出现的位置由ActionPlaces
接口中的常量定义。 操作出现的每个地方都会新建一个Presentation
。因此相同的操作在不同位置可以有不同的文本和图标。 操作的不同presentation可以通过复制AnAction.getTemplatePresentation()
方法返回的presentation创建。
IDEA通过定期调用AnAction.update()
方法更新操作的状态。传递给此方法的AnActionEvent
对象携带了操作当前上下文的信息,特别是需要更新的指定presentation。
使用AnActionEvent.getData()
方法可以获取当前IDE的信息,包括活动项目、所选文件、编辑器中的选择等。可以传递给此方法的数据键在CommonDataKeys
类中定义。
AnActionEvent
实例也会传递给actionPerformed
方法。
注册操作
目前有两种注册操作的方法:在plugin.xml
文件的<actions>
部分列出或通过Java代码。
在plugin.xml文件中注册操作
以下是在plugin.xml
中注册操作的方法,其演示了所有可以在<actions>
部分使用的元素,并描述了每个元素的含义。
<!-- Actions -->
<actions>
<!-- <action>定义要注册的操作
"id"属性指定操作的唯一标识符
"class"属性指定操作实现类的完全限定名
"text"属性指定操作的文本(工具栏按钮提示或菜单项文本)
"use-shortcut-of"属性(可选)指定此操作将要使用的快捷键的操作的ID
"description"属性(可选)指定焦点在操作上时显示在状态栏的描述
"icon" 属性(可选)指定显示在工具栏按钮或菜单项旁边的图标-->
<action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector" icon="icons/garbage.png">
<!-- <add-to-group>节点指定此操作要添加到的组,一个操作可以添加到多个组
"group-id"属性指定此操作要添加到的组的ID,这个组必须被DefaultActionGroup类的实例实现
"anchor"属性指定操作相对于组里其它操作的位置,它的只可以为"first",、"last",、"before"和"after"
如果"anchor"的值设置为"before"和"after","relative-to-action"属性是必须的,
它指定当前操作要插入在那个操作之前或之后 -->
<add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/>
<!-- <keyboard-shortcut>节点指定操作的快捷键,一个操作可以有多个快捷键
"first-keystroke"属性指定操作的首选快捷键,键位由常规Swing规则指定
"second-keystroke"属性(可选)指定操作的备选快捷键
"keymap"属性指定快捷方式所属的键位映射方案,标准键位映射方案的ID
在com.intellij.openapi.keymap.KeymapManager类中的常量定义 -->
<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
<!-- <mouse-shortcut>节点指定操作的鼠标快捷方式,一个操作可以有多个鼠标快捷方式
"keystroke"属性指定操作的点击方式
它可以定义为以空格分隔的单词序列:
鼠标按钮:"button1", "button2", "button3"
键位修饰:"shift", "control", "meta", "alt", "altGraph"
如果操作需要键位双击激活使用"doubleClick"
"keymap"属性指定快捷方式所属的键位映射方案,标准键位映射方案的ID
在com.intellij.openapi.keymap.KeymapManager类中的常量定义 -->
<mouse-shortcut keystroke="control button3 doubleClick" keymap="$default"/>
</action>
<!-- <group>定义一个操作组,其中定义的<action>、<group>和<separator>元素会自动包括在组里
"id"属性指定操作组的唯一标识符
"class"属性(可选)指定实现操作组类的完全限定名
如果未指定,则默认使用com.intellij.openapi.actionSystem.DefaultActionGroup
"text"属性(可选)指定操作组的文本(显示子菜单的菜单项的文本)
"description"属性(可选)指定焦点在操作组上时显示在状态栏的描述
"icon"属性(可选)指定显示在工具栏按钮或操作组旁边的图标
"popup"属性(可选)指定如何在菜单中显示操作组
如果值为"true",操作显示在子菜单中
如果值为"false",操作显示在由分隔符定界的同一菜单上 -->
<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"/>
<!-- <separator>元素定义操作之间的分隔符
它也可以有<add-to-group>子元素 -->
<separator/>
<group id="TestActionSubGroup"/>
<!-- <reference>元素允许添加现存的操作
"ref"属性指定操作的ID -->
<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
,它注册了一个由TextBoxes
类定义的操作并将其添加到主菜单的Window菜单组:
public class MyPluginRegistration implements ApplicationComponent {
// 返回组件名称(唯一字符串)
@NotNull public String getComponentName() {
return "MyPlugin";
}
// 如果你在plugin.xml文件的<application-components>部分注册了MyPluginRegistration类,
// 这个方法将在IDEA启动时被调用
public void initComponent() {
ActionManager am = ActionManager.getInstance();
TextBoxes action = new TextBoxes();
// 将TextBoxes类的实例传入ActionManager类的registerAction方法
am.registerAction("MyPluginAction", action);
// 获取WindowMenu操作组的实例
DefaultActionGroup windowM = (DefaultActionGroup) am.getAction("WindowMenu");
// 添加一个分隔符和操作到主菜单的WindowMenu操作组
windowM.addSeparator();
windowM.add(action);
}
// Disposes system resources.
public void disposeComponent() {
}
}
注意:
TextBoxes
类的实现可以查看创建操作.
在plugin.xml
文件的<application-components>
部分做以下更改确保你的插件在IDEA启动时被初始化:
<application-components>
<!-- 添加应用组件 -->
<component>
<implementation-class>MypackageName.MyPluginRegistration</implementation-class>
</component>
</application-components>
从操作中构建UI
如果插件需要包括一个工具栏或弹出菜单,它是在自己的UI上从操作组中构建的,可以使用ActionPopupMenu
和ActionToolbar
类实现。这些对象可以通过调用ActionManager.createActionPopupMenu
和ActionManager.createActionToolbar
方法创建。要从这样的对象上获取Swing组件可以简单调用getComponent()方法。
如果你对操作工具栏要附加到指定组件上(例如,工具窗口的面板),你通常需要调用ActionToolbar.setTargetComponent()
方法,并将相关组件的实例作为参数传入。这样可以确保工具栏按钮的状态依赖于相关组件而不是IDE框架内当前焦点位置的状态。