原文鏈接:
http://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html
執(zhí)行和更新操作
操作體系允許插件向IDEA添加自己的菜單項(xiàng)和工具欄按鈕显沈。一個(gè)操作就是一個(gè)派生自AnAction
類的類苍在,當(dāng)選擇菜單項(xiàng)或點(diǎn)擊工具欄按鈕時(shí),它的actionPerformed
方法就會被調(diào)用擎值。例如后频,其中一個(gè)操作類就是負(fù)責(zé)文件|打開文件...菜單項(xiàng)和打開文件 工具欄按鈕的锥忿。
操作被組織成組患民,其又可以包含其他組录粱。 一組操作可以形成工具欄或菜單。
組的子組可以形成菜單的子菜單平委。
每個(gè)操作和操作組都有一個(gè)唯一的標(biāo)識符奈虾。標(biāo)準(zhǔn)IDEA操作的標(biāo)識符在IdeActions類中定義。
每個(gè)操作都可以包含在多個(gè)組中廉赔,因此一個(gè)操作會出現(xiàn)在IDEA用戶界面中的多個(gè)位置肉微。操作可以出現(xiàn)的位置由ActionPlaces
接口中的常量定義。 操作出現(xiàn)的每個(gè)地方都會新建一個(gè)Presentation
蜡塌。因此相同的操作在不同位置可以有不同的文本和圖標(biāo)碉纳。 操作的不同presentation可以通過復(fù)制AnAction.getTemplatePresentation()
方法返回的presentation創(chuàng)建。
IDEA通過定期調(diào)用AnAction.update()
方法更新操作的狀態(tài)馏艾。傳遞給此方法的AnActionEvent
對象攜帶了操作當(dāng)前上下文的信息劳曹,特別是需要更新的指定presentation。
使用AnActionEvent.getData()
方法可以獲取當(dāng)前IDE的信息琅摩,包括活動項(xiàng)目铁孵、所選文件、編輯器中的選擇等房资⊥扇埃可以傳遞給此方法的數(shù)據(jù)鍵在CommonDataKeys
類中定義。
AnActionEvent
實(shí)例也會傳遞給actionPerformed
方法轰异。
注冊操作
目前有兩種注冊操作的方法:在plugin.xml
文件的<actions>
部分列出或通過Java代碼岖沛。
在plugin.xml文件中注冊操作
以下是在plugin.xml
中注冊操作的方法,其演示了所有可以在<actions>
部分使用的元素搭独,并描述了每個(gè)元素的含義宏胯。
<!-- Actions -->
<actions>
<!-- <action>定義要注冊的操作
"id"屬性指定操作的唯一標(biāo)識符
"class"屬性指定操作實(shí)現(xiàn)類的完全限定名
"text"屬性指定操作的文本(工具欄按鈕提示或菜單項(xiàng)文本)
"use-shortcut-of"屬性(可選)指定此操作將要使用的快捷鍵的操作的ID
"description"屬性(可選)指定焦點(diǎn)在操作上時(shí)顯示在狀態(tài)欄的描述
"icon" 屬性(可選)指定顯示在工具欄按鈕或菜單項(xiàng)旁邊的圖標(biāo)-->
<action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage" description="Run garbage collector" icon="icons/garbage.png">
<!-- <add-to-group>節(jié)點(diǎn)指定此操作要添加到的組甥厦,一個(gè)操作可以添加到多個(gè)組
"group-id"屬性指定此操作要添加到的組的ID档桃,這個(gè)組必須被DefaultActionGroup類的實(shí)例實(shí)現(xiàn)
"anchor"屬性指定操作相對于組里其它操作的位置贡茅,它的只可以為"first",吃靠、"last",镊尺、"before"和"after"
如果"anchor"的值設(shè)置為"before"和"after"烙样,"relative-to-action"屬性是必須的开仰,
它指定當(dāng)前操作要插入在那個(gè)操作之前或之后 -->
<add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/>
<!-- <keyboard-shortcut>節(jié)點(diǎn)指定操作的快捷鍵播赁,一個(gè)操作可以有多個(gè)快捷鍵
"first-keystroke"屬性指定操作的首選快捷鍵颂郎,鍵位由常規(guī)Swing規(guī)則指定
"second-keystroke"屬性(可選)指定操作的備選快捷鍵
"keymap"屬性指定快捷方式所屬的鍵位映射方案,標(biāo)準(zhǔn)鍵位映射方案的ID
在com.intellij.openapi.keymap.KeymapManager類中的常量定義 -->
<keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
<!-- <mouse-shortcut>節(jié)點(diǎn)指定操作的鼠標(biāo)快捷方式容为,一個(gè)操作可以有多個(gè)鼠標(biāo)快捷方式
"keystroke"屬性指定操作的點(diǎn)擊方式
它可以定義為以空格分隔的單詞序列:
鼠標(biāo)按鈕:"button1", "button2", "button3"
鍵位修飾:"shift", "control", "meta", "alt", "altGraph"
如果操作需要鍵位雙擊激活使用"doubleClick"
"keymap"屬性指定快捷方式所屬的鍵位映射方案乓序,標(biāo)準(zhǔn)鍵位映射方案的ID
在com.intellij.openapi.keymap.KeymapManager類中的常量定義 -->
<mouse-shortcut keystroke="control button3 doubleClick" keymap="$default"/>
</action>
<!-- <group>定義一個(gè)操作組寺酪,其中定義的<action>、<group>和<separator>元素會自動包括在組里
"id"屬性指定操作組的唯一標(biāo)識符
"class"屬性(可選)指定實(shí)現(xiàn)操作組類的完全限定名
如果未指定替劈,則默認(rèn)使用com.intellij.openapi.actionSystem.DefaultActionGroup
"text"屬性(可選)指定操作組的文本(顯示子菜單的菜單項(xiàng)的文本)
"description"屬性(可選)指定焦點(diǎn)在操作組上時(shí)顯示在狀態(tài)欄的描述
"icon"屬性(可選)指定顯示在工具欄按鈕或操作組旁邊的圖標(biāo)
"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>元素允許添加現(xiàn)存的操作
"ref"屬性指定操作的ID -->
<reference ref="EditorCopy"/>
<add-to-group group-id="MainMenu" relative-to-action="HelpMenu" anchor="before"/>
</group>
</actions>
從代碼中注冊操作
從代碼中注冊操作陨献,有兩個(gè)步驟:
- 首先盒犹,必須往ActionManager類的
registerAction
方法傳入一個(gè)派生自AnAction
類的實(shí)例,將操作與ID關(guān)聯(lián)眨业; - 然后急膀,操作需要添加進(jìn)一個(gè)或多個(gè)組。要通過ID獲取一個(gè)操作組的實(shí)例龄捡,需要調(diào)用
ActionManager.getAction()
并將返回值轉(zhuǎn)換為DefaultActionGroup類卓嫂。
你可以使用以下方法創(chuàng)建一個(gè)在IDEA啟動時(shí)注冊操作的插件。
在IDEA啟動時(shí)注冊操作
- 新建一個(gè)實(shí)現(xiàn)
ApplicationComponent
接口的類聘殖; - 在這個(gè)類中重寫
getComponentName
晨雳、initComponent
和disposeComponent
方法; - 在
plugin.xml
文件的<application-components>
部分注冊這個(gè)類奸腺。
要闡明以上過程餐禁,查看以下實(shí)例Java類MyPluginRegistration
,它注冊了一個(gè)由TextBoxes
類定義的操作并將其添加到主菜單的Window菜單組:
public class MyPluginRegistration implements ApplicationComponent {
// 返回組件名稱(唯一字符串)
@NotNull public String getComponentName() {
return "MyPlugin";
}
// 如果你在plugin.xml文件的<application-components>部分注冊了MyPluginRegistration類洋机,
// 這個(gè)方法將在IDEA啟動時(shí)被調(diào)用
public void initComponent() {
ActionManager am = ActionManager.getInstance();
TextBoxes action = new TextBoxes();
// 將TextBoxes類的實(shí)例傳入ActionManager類的registerAction方法
am.registerAction("MyPluginAction", action);
// 獲取WindowMenu操作組的實(shí)例
DefaultActionGroup windowM = (DefaultActionGroup) am.getAction("WindowMenu");
// 添加一個(gè)分隔符和操作到主菜單的WindowMenu操作組
windowM.addSeparator();
windowM.add(action);
}
// Disposes system resources.
public void disposeComponent() {
}
}
注意:
TextBoxes
類的實(shí)現(xiàn)可以查看創(chuàng)建操作.
在plugin.xml
文件的<application-components>
部分做以下更改確保你的插件在IDEA啟動時(shí)被初始化:
<application-components>
<!-- 添加應(yīng)用組件 -->
<component>
<implementation-class>MypackageName.MyPluginRegistration</implementation-class>
</component>
</application-components>
從操作中構(gòu)建UI
如果插件需要包括一個(gè)工具欄或彈出菜單坠宴,它是在自己的UI上從操作組中構(gòu)建的,可以使用ActionPopupMenu
和ActionToolbar
類實(shí)現(xiàn)绷旗。這些對象可以通過調(diào)用ActionManager.createActionPopupMenu
和ActionManager.createActionToolbar
方法創(chuàng)建喜鼓。要從這樣的對象上獲取Swing組件可以簡單調(diào)用getComponent()方法。
如果你對操作工具欄要附加到指定組件上(例如衔肢,工具窗口的面板)庄岖,你通常需要調(diào)用ActionToolbar.setTargetComponent()
方法,并將相關(guān)組件的實(shí)例作為參數(shù)傳入角骤。這樣可以確保工具欄按鈕的狀態(tài)依賴于相關(guān)組件而不是IDE框架內(nèi)當(dāng)前焦點(diǎn)位置的狀態(tài)隅忿。