分组操作(Grouping Actions)
分组操作(Grouping Actions)
在看这个教程内容之前,建议先熟悉 新建Actions 中的内容
如果一个操作需要多个 Action, 可以把这些 Action 放入同一个 Group 中,本教程主要包括以下内容:
- 如何创建一个新的 group
- 如果把 Action 添加入一个已存在的 group
- 创建拥有可变数量 Action 的 group
简单Action Groups
下面第一个示例中,会在idea顶级菜单栏中注册一个 Action Group 的下拉框:
创建Group
如下所示,group 需要在 <actions> 元素中进行注册,如果不指定 group 的实现类,IntelliJ Platform 将会提供一个默认的实现类。 默认实现类想要生效,必须保证,其中包含的 Action 必须是静态的,不支持在运行时修改。
<actions>
<!-- id 全局唯一-->
<!-- popup属性:决定该Group是否允许子菜单 -->
<!-- icon:图标,需要配置为全限定命名 -->
<!-- 不配置compact属性,表示该Group需要支持子菜单 -->
<group
id="org.intellij.sdk.action.GroupedActions"
text="Static Grouped Actions"
popup="true"
icon="SdkIcons.Sdk_default_icon"/>
</actions>
把Action Group绑定到UI组件中
下面的配置通过 add-to-group 标签把 group 绑定到了 Tools 菜单中,relative-to-action 表示不是IntelliJ Platform 自带的菜单,而是某个 Action 的 id , 这个 Group 的位置是 PopupDialogAction 的后面。(PopupDialogAction 详见 新建Actions)
<group
id="org.intellij.sdk.action.GroupedActions"
text="Static Grouped Actions"
popup="true"
icon="SdkIcons.Sdk_default_icon">
<add-to-group
group-id="ToolsMenu"
anchor="after"
relative-to-action="org.intellij.sdk.action.PopupDialogAction"/>
</group>
在静态Actions Group中添加新的Action
下面的示例中, PopupDialogAction 被重复使用注册入了一个新的静态 Group 中, 给 PopupDialogAction 配置了一个新的唯一 id : org.intellij.sdk.action.GroupPopDialogAction . 由于Action的id需要是唯一的,所以需要和 新建Actions 中 PopupDialogAction 中的 id 区分开来。
提示
同一个 Action 实现类可以注册在不同的菜单中,但是需要设置不同的id
<group
id="org.intellij.sdk.action.GroupedActions"
text="Static Grouped Actions"
popup="true"
icon="SdkIcons.Sdk_default_icon">
<add-to-group
group-id="ToolsMenu"
anchor="after"
relative-to-action="org.intellij.sdk.action.PopupDialogAction"/>
<action
class="org.intellij.sdk.action.PopupDialogAction"
id="org.intellij.sdk.action.GroupPopDialogAction"
text="A Group Action"
description="SDK static grouped action example"
icon="SdkIcons.Sdk_default_icon">
</action>
</group>
如下图所示,PopupDialogAction 被注册入了2个菜单中:
Tools | Pop Dialog Action 是在新建Actions 注册的,Action 的 id 是 org.intellij.sdk.action.PopupDialogAction
Tools | Static Grouped Actions | A Group Action 是在上面的示例中注册的, Action 的 id 是 org.intellij.sdk.action.GroupPopDialogAction
自定义Action Group实现类
当默认 Action Group 实现类不满足需求的时候,例如某些操作需要依赖于上下文,那么需要自定义Action Group 实现类。
以下步骤描述了如何实现根据需求修改Group 的可用性和可见性。在下面的示例中,当存在一个可用的编辑器时,Action Group 才会被加入菜单栏。
继承DefaultActionGroup
DefaultActionGroup 是 ActionGroup 的实现类。
DefaultActionGroup 可以在 Group 中添加Action 和分隔符。DefaultActionGroup 中的子Action 在运行期不能被修改;
action_basics 示例中创建了 CustomDefaultActionGroup,代码如下:
public class CustomDefaultActionGroup extends DefaultActionGroup {
@Override
public void update(AnActionEvent event) {
// 根据是否存在编辑器来启用/禁用该group
}
}
注册Action Group
action_basics 示例中注册了group,在示例中也演示了如何国际化。
<idea-plugin>
<!-- 国际化配置文件-->
<resource-bundle>messages.BasicActionsBundle</resource-bundle>
<actions>
<!-- class 属性,表示不使用默认实现类了,使用CustomDefaultActionGroup -->
<!-- popup属性:决定该Group是否允许子菜单 -->
<!-- text 和 description 使用 国际化配置文件中对应的key配置 (key格式: [id].text , [id].description ) -->
<!-- 没有配置icon属性,因为 CustomDefaultActionGroup类中 设置了icon -->
<!-- add-to-group 表示 把该group配置到了 EditorPopupMenu 菜单栏的第一个 -->
<group
id="org.intellij.sdk.action.CustomDefaultActionGroup"
class="org.intellij.sdk.action.CustomDefaultActionGroup"
popup="true">
<add-to-group group-id="EditorPopupMenu" anchor="first"/>
</group>
</actions>
</idea-plugin>
自定义Action Group中添加Actions
<!-- id:唯一性 -->
<!-- class 属性,表示不使用默认实现类了,使用CustomDefaultActionGroup -->
<group
id="org.intellij.sdk.action.CustomDefaultActionGroup"
class="org.intellij.sdk.action.CustomDefaultActionGroup"
popup="true"
icon="SdkIcons.Sdk_default_icon">
<add-to-group group-id="EditorPopupMenu" anchor="first"/>
<!-- text 和 description 使用 国际化配置文件中( BasicActionsBundle.properties)对应的key配置 (key格式 [id].text , [id].description ) -->
<action
id="org.intellij.sdk.action.CustomGroupedAction"
class="org.intellij.sdk.action.PopupDialogAction"
icon="SdkIcons.Sdk_default_icon"/>
</group>
自定义Group业务逻辑
重写 CustomDefaultActionGroup.update() 方法,使只有在拥有可用编辑器的时候,该group才可见。并根据当前环境设置Icon
public class CustomDefaultActionGroup extends DefaultActionGroup {
@Override
public void update(AnActionEvent event) {
// 根据是否存在编辑器来启用/禁用该group
Editor editor = event.getData(CommonDataKeys.EDITOR);
event.getPresentation().setEnabled(editor != null);
// 给group设置图标
event.getPresentation().setIcon(SdkIcons.Sdk_default_icon);
}
}
运行该插件,打开一个文件,并右键,编辑器中会弹出一个菜单,菜单中包含上面配置的Group , 注意,由于配置了文本的国际化,所以会显示 [en] 后缀,如下图
拥有动态Action的Group
创建拥有动态Action的Group,需要实现 ActionGroup 类
创建动态action group
见示例action_basics 中的 DynamicActionGroup 类
public class DynamicActionGroup extends ActionGroup {
}
注册
通过如下配置注册后,该group将会出现在 Tools 菜单中:
<group
id="org.intellij.sdk.action.DynamicActionGroup"
class="org.intellij.sdk.action.DynamicActionGroup"
popup="true"
text="Dynamically Grouped Actions"
description="SDK dynamically grouped action example"
icon="SdkIcons.Sdk_default_icon">
<add-to-group
group-id="ToolsMenu"
anchor="after"
relative-to-action="org.intellij.sdk.action.GroupedActions"/>
</group>
注意
如果group 标签中 class属性配置的是 ActionGroup 的子类,那么它的子 Action 都需要用代码来配置(见下文),在该 group 中直接配置任何静态 <action>元素都会报错。如果需要使 Group 静态化,应该使用上文中的 DefaultActionGroup 。
动态group中添加子Action
DynamicActionGroup 中增加子 Action ,需要重写 getChildren() 方法并返回 AnAction 的数组,这个地方又重复使用了 PopupDialogAction (这就是 PopupDialogAction 重写构造器的原因)
public class DynamicActionGroup extends ActionGroup {
@NotNull
@Override
public AnAction[] getChildren(AnActionEvent event) {
return new AnAction[]{
new PopupDialogAction(
"Action Added at Runtime",
"Dynamic Action Demo",
SdkIcons.Sdk_default_icon)
};
}
}
运行插件,如下图: