IntelliJ IDEA Action System

执行和更新插件

交互系统允许插件向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启动时注册交互

  1. 创建一个实现ApplicationComponent接口的类。
  2. 在这个类中,重写getComponentName、initComponent和disposeComponent方法。
  3. 在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

时间: 2024-10-20 10:26:42

IntelliJ IDEA Action System的相关文章

IntelliJ IDEA插件结构

IntelliJ IDEA插件结构 插件是扩展IDEA功能的唯一途径.一款插件使用IDEA或其他插件暴露的API实现它的功能.这篇文章关注插件系统的结构和插件的生命周期.文章中不会指出任何可能被插件使用的其他API接口. 文章中包含了以下主题: 插件内容 插件类加载器 插件组件 插件扩展和扩展点 插件交互(Action) 插件服务 插件配置文件 插件内容 有3种方式组织插件内容: 1.由插件文件夹内的一个.jar文件构成一个插件.这个压缩包内应该包含配置文件(META-INF/plugin.xm

IntelliJ IDEA - 代码辅助功能

Eclipse 和 IntelliJ IDEA 都提供了写代码的辅助功能,包括代码补全.代码生成.快速修饰和动态模板等功能. 1. 快速修复(Quick-fixes) 快捷键:Alt+Enter 所有的快速修复都是基于 Settings | Editor | Inspections 中的选项进行提示. 批量修复 如果需要一次多多个地方进行修复,如整个目录(folder).一个模块(module)或整个项目(project),可以使用下面两个功能: Analyze | Run Inspection

插件api

public class TextBoxes extends AnAction { // If you register the action from Java code, this constructor is used to set the menu item name // (optionally, you can specify the menu description and an icon to display next to the menu item). // You can

使用spring配合Junit进行单元测试的总结

最近公司的项目和自己的项目中都用到了spring集成junit进行单元测试,总结一下几种基本的用法: 1.直接对spring中注入的bean进行测试(以DAO为例): 在测试类上添加@RunWith注解指定使用springJunit的测试运行器,@ContextConfiguration注解指定测试用的spring配置文件的位置 之后我们就可以注入我们需要测试的bean进行测试,Junit在运行测试之前会先解析spring的配置文件,初始化spring中配置的bean @RunWith(Spri

HttpClient使用详解 (一)

Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性.因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入. 一.简介 HttpClient是Apache Jakarta Common下的子项目,用

设计模式13-代理模式

1. 概念 代理模式又称为委托模式 :为其他对象提供一种代理以控制对这个对象的访问. 2. 案例 package org.demo.proxy.demo01; public class Demo03 { public static void main(String[] args) { IUser user = new UserProxy(new UserImpl()) ; user.action() ; } } interface IUser{ void action() ; } class U

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle&lt;T&gt;

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T> 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子 看一它的的实现和源码 下一篇用它们做一个多语言的demo 这两个是事件的订阅和广播,很强大,但用的时候要小心发生不必要的冲突. 先看一下它的实现思想 在Caliburn.Micro里EventAggregator要以单例的形式出现这样可以

特殊广播接收者

比如操作特别频繁的广播事件 屏幕的锁屏和解锁 电池电量的变化 这样的广播接收者在清单文件里面注册无效 import android.os.Bundle; import android.app.Activity; import android.content.IntentFilter; import android.view.Menu; public class MainActivity extends Activity { private ScreenReceiver screenReceive

内部类和控制框架

//事件类 public abstract class Event {    private long eventTime;    protected final long delayTime;    public Event(long delayTime) {        this.delayTime = delayTime;        start();    }    public void start(){        eventTime = System.nanoTime() +