욱'S 노트

IntelliJ 플러그인 개발 - Action 정의하기 본문

Tool/IntelliJ

IntelliJ 플러그인 개발 - Action 정의하기

devsun 2015. 1. 12. 14:35

IntelliJ 플러그인을 구동하기 위해서는 특정 메뉴를 클릭을 해야 한다. 이러한 행위 자체를 IntelliJ에서는 Action이라고 정의를 하는 것 같다.

아래는 WIKI에서 정의한 내용이다.


액션시스템 개요 


액션 시스템이란 플러그인을 IDEA 메뉴와 툴바에서 접근가능하도록 하는것을 의미한다. 액션은 클래스이며 AnAction 클래스를 상속받아 구현한다. 메뉴의 아이템이나 툴바 버튼이 선택되었을때, actionPerformed 메소드를 호출한다. 액션은 그룹으로 구성될 수 있으며, 다른 그룹에 포함될 수 있다. 액션 그룹은 툴바나 메뉴를 형성할 수 있으며 서브그룹은 메뉴의 서브메뉴로 구성될 수 있다.모든 액션과 액션 그룹은 유일한 식별자를 가진다.


모든 액션은 하나 이상의 그룹에 포함될 수 있으므로, IDEA의 다양한 UI에서 나타날 수 있다. 액션이 나타날 수 있는 위치는 ActionPlaces 인터페이스에 상수로 정의되어 있다. 똑같은 액션은 UI의 다른 위치에서 나타날 때, 다른 문자와 아이콘을 가질 수 있다. AnAction.getTemplatePresentation() 메소드에 의한 리턴된 프리젠테이션을 카피함으로써 액션의 다른 프리젠테이션을 생성할 수 있다.


액션의 상태를 업데이트하기 위에 IDEA에 의해 주기적으로 AnAction.update() 메소드가 호출된다. 액션의 현재 context에 대한 정보를 전달하기 위해 AnActionEvent 객체가 전달된다. 


IDE의 현재 상태에 대한 정보를 조회하기 위해, (현재 프로젝트, 선택된 파일, 에디터의 선택요소 등) AnActionEvent.getData()를 사용한다. 메소드에 전달하기 위한 data 키들은 DataKeys 클래스에 정의되어 있다. 


AnActionEvent 객체는 actionPerformed 메소드로 전달된다.


액션 등록하기

발번역을 뒤로 하고, 액션을 등록해보자.
액션을 등록하는 방법은 크게 두가지로 나뉜다.

하나는 xml을 통해서 등록하기, 다른 하나는 소스 코드를 통해서 등록하는 방법이다.
다음은 xml로 액션을 등록한 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
<!-- Actions -->
    <actions>
        <!-- 필수요소 "id" 액션의 유일한 식별자
             필수요소 "class" 액션을 구현한 클래스의 full-qualified 이름
             필수요소 "text" 액션을 명시한 문자열 (툴바 버튼 툴팁 / 메뉴아이템명).
             선택요소 "use-shortcut-of" 액션을 사용하기 위한 단축키를 사용할 지 여부 
             선택요소 "description" 액션에 포커스 되었을 때 status bar에 나타나는 메시지
             선택요소 "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" 액션이 추가될 그룹은 유일한 식별자                    
                    필수요소 "anchor" 그룹의 다른 액션에 대한 상대적인 위치 : "first", "last", "before" and "after".
                    필수요소 "relative-to-action" anchor "before", "after" 사용시 대상이 되는 액션ID -->
            <add-to-group group-id="ToolsMenu" relative-to-action="GenerateJavadoc" anchor="after"/>
             <!-- <keyboard-shortcut>은 키보드 단축키.
                    필수요소 "first-keystroke" 첫번째 keystroke, Swing 규칙을 따른다.
                    선택요소 "second-keystroke" 두번째 keystroke
                    필수요소 "keymap" 액션이 활성화되는 키맵. 키맵의 ID는 com.intellij.openapi.keymap.KeymapManager 클래스의 상수로 정의 -->
            <keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
        </action>
        <!-- <group> 액션 그룹을 정의 <action>, <group> and <separator> element는 그룹내에 자동적으로 정의되어진다.
               필수요소 "id" 액션 그룹에 대한 유일한 식별자.
               선택요소 "class" 그룹을 구현한 클래스의 full-qualified 이름. 명시되지 않으면 com.intellij.openapi.actionSystem.DefaultActionGroup 사용됨
               선택요소 "text" 그룹의 문자열 (서브메뉴의 메뉴아이템명).
               선택요소 "description" 그룹에 focus되었을때 status bar에 나타나는 설명
               선택요소" icon" 툴바 버튼이미지나 그룹 옆에 나타나는 이미지
               선택요소 "popup" 메뉴에 그룹이 어떻게 표현될지. popup="true"면 submenu에 커서가 위치했을때 action들이 나타나고, popup="false"일 경우, separator로 구분하여 액션들이 미리 나타남 -->
        <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/>
            <group id="TestActionSubGroup"/>
             <!-- <reference> 기존의 액션을 그룹에 추가한다.
                   필수요소"ref" 추가될 액션의 id. -->
            <reference ref="EditorCopy"/>
            <add-to-group group-id="MainMenu" relative-to-action="HelpMenu" anchor="before"/>
        </group>
    </actions>
 
cs

그리고 다음은 액션을 소스로 등록한 예제이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
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() {        
    }
}
cs


마지막으로 IDEA에서 쉽게 액션을 등록하는 방법을 알아보자.

아래와 같이 마우스를 오른쪽 클릭하여 Action을 선택한다.

Action Id와 어떤 그룹에 추가할지를 선택하자.



확인을 눌러보면 다음과 plugin.xml에 내용이 추가되었으며, 클래스가 생성된 것을 알 수 있다.


<idea-plugin version="2">
<id>com.yourcompany.unique.plugin.id</id>
<name>Plugin display name here</name>
<version>1.0</version>
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>

<description><![CDATA[
Enter short description for your plugin here.<br>
<em>most HTML tags may be used</em>
]]></description>

<change-notes><![CDATA[
Add change notes here.<br>
<em>most HTML tags may be used</em>
]]>
</change-notes>

<!-- please see http://confluence.jetbrains.com/display/IDEADEV/Build+Number+Ranges for description -->
<idea-version since-build="131"/>

<!-- please see http://confluence.jetbrains.com/display/IDEADEV/Plugin+Compatibility+with+IntelliJ+Platform+Products
on how to target different products -->
<!-- uncomment to enable plugin in all products
<depends>com.intellij.modules.lang</depends>
-->

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
</extensions>

<application-components>
<!-- Add your application components here -->
</application-components>

<project-components>
<!-- Add your project components here -->
</project-components>

<actions>
<!-- Add your actions here -->
<action id="SamplePlugin.Hello" class="HelloAction" text="Hello">
<add-to-group group-id="ToolsMenu" anchor="last"/>
</action>
</actions>

</idea-plugin>


HelloAction 클래스를 고쳐서 다이얼로그를 하나 뛰워보자.

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;

/**
* Created by devsun on 15. 1. 12..
*/
public class HelloAction extends AnAction {
public void actionPerformed(AnActionEvent e) {
SampleDialog dialog = new SampleDialog();
dialog.pack();
dialog.setVisible(true);
}
}


최종결과이다. Tools 메뉴에 메뉴가 추가되었고, 클릭시 새로운 다이얼로그가 뜨는 것을 확인할 수 있을 것이다.





그러나 아쉽게도 group을 만든다거나 했을 경우에는 정확한 IDE의 지원을 받을 수 없다. 그러므로, xml을 편집하는 것이 가장 좋은 방법으로 추천한다.

또한 현재 존재하는 그룹 및 action을 확인하는 방법이 IDE를 통해서 밖에 확인이 안되므로, 이 점이 너무 불편했다.



출처 : IntelliJ WIKI


'Tool > IntelliJ' 카테고리의 다른 글

IntelliJ 플러그인 개발 - UI 만들기  (3) 2015.01.09
IntelliJ 플러그인 개발 - 시작하기  (0) 2015.01.08
인텔리J 단축키 정리 (Mac)  (1) 2015.01.05
Comments