IntelliJ IDEAのプラグインを作ろう！(アクションの追加, 通知, ダイアログ)

# まえがき
この記事シリーズのソースコードは以下のリポジトリで管理されています。
[Qiita Artifact Plugin](https://github.com/syuchan1005/QiitaArtifactPlugin)

# 目次
1. [プロジェクト作成と設定まで](https://qiita.com/syu_chan_1005/items/74a834bb353f6b7df4de)
2. アクションの追加, 通知, ダイアログ(ここ)
3. [拡張ポイント](https://qiita.com/syu_chan_1005/items/7dcb4c68c26aa0594e4e)

# はじめに
前回の記事で独自言語作るとか言いましたがまずは基礎から行きましょう。

# アクション
## アクションとは
プラグインはメニューやツールバーに新しい項目を追加しUIをカスタマイズできます。
`AnAction`クラスが用意され`actionPerformed`がクリックするたびに呼び出されます。

独自のアクションを作成するには
1. `AnAction`を継承したクラスを作り`actionPerformed`を実装
1. `plugin.xml`にアクションを定義
という2つの手順が必要です。

## アクションの定義
1. まずは例として`TestAction`クラスを作成します。
`New -> JavaClass`より作成してください。

> 標準で`Plugin DevKit -> Action`という便利なものがありますが最初のうちはわかりづらいので無視

下のように実装してください

```java:TestAction.java
public class TestAction extends AnAction {
	public TestAction() {
		super("Test Action");
	}
	
	@Override
	public void actionPerformed(AnActionEvent event) {
		Messages.showMessageDialog(event.getProject(), "Clicked!", "Fire Action", Messages.getInformationIcon());
	}
}
```

### ちょっとした解説
`AnAction`クラスには`String text, String description, Icon icon`の3つを指定できます。
今回は`String title`のみ指定しています。

## アクションの登録
`plugin.xml`内の`<actions>`タグに書くことで登録できます。
今回はIDEの上部のメニューに登録します。
`<action>`内を以下のように記述してください。

```xml:plugin.xml
<idea-plugin>
  ...
  <actions>
    <group id="<プラグイン名>.Menu" text="<表示名>">
      <add-to-group group-id="MainMenu" anchor="last" />
      <action class="<パッケージ名>.TestAction" id="<プラグイン名>.TestAction" />
    </group>
  </actions>
</idea-plugin>
```

## アクション追加のまとめ
1. `AnAction`実装
1. `plugin.xml`登録でOK

でも....
**めんどくさくない？**
今回はIDE上部のメニューに登録したが他の場所にはどうやって登録するのか，キーボードショートカットとかどうするとかわからないことだらけです。

**ので**
`New -> Plugin DevKit -> Action`の出番です。
これを選択するとウィンドウが出てくるので簡単に設定できます。

- Action ID: さっきの`"<プラグイン名>.TestAction"`
- Class Name: さっきの`"<パッケージ名>.TestAction"`
- Name: メニューに表示される名前(`さっきの"Test Action"`)
- Description: 説明
- Add to Group
    - Groups: どこに追加するかです，他のプラグインが利用している`group`も表示されます。
    - Actions: どのプルダウンの中に属するか
- Keyboard Shortcuts: TextBoxにフォーカスして入力すれば自動で`Shift, Ctrl`など書いてくれる

のように簡単に設定できます。

(次に通知の説明するので)試しに新しいActionを追加しましょう
- Action ID: <プラグイン名>.NotificationAction
- Class Name: <パッケージ名>.NotificationAction
を「アクションの登録」内で作成したgroup内に作成してください。
また、Class Nameに対応する`AnAction`を実装したクラスも作成してください。

```xml:plugin.xml
<actions>
  <group ...>
    <add-to-group ... />

    <action class="<パッケージ名>.NotificationAction" id="<プラグイン名>.NotificationAction"
              text="Notification" icon="AllIcons.General.Balloon"/>
  </group>
</actions>
```

> `<action>`二行目は`super("title")`などで記述していたものを`plugin.xml`で記述した場合の例です

こんな感じになりましたか？


# 通知
~~ここまで長過ぎたから端折る~~

## 通知とは
右下に出てくるのみたことありますか？あれです。
右下，`Event Log`からも確認できます。

## 通知の実装
通知は`Notifications.Bus.notify(Notification notification)`メソッドを用いて発行します。
`Notification`クラスには

- String groupDisplayId:<プラグイン名>など
- String title: 通知のタイトル
- String content: 内容
- NotificationType type: 
    - INFORMATION
    - WARNING
    - ERROR
- NotificationListener listener: (よくわからなかった)

が指定できます。
Actionと組み合わせて発行してみましょう。
先ほど作成した`NotificationAction`に下のように記述してください。

```java:NotificationAction.java
	@Override
	public void actionPerformed(AnActionEvent event) {
		Notifications.Bus.notify(new Notification("<プラグイン名>", "Title", "Content", NotificationType.INFORMATION));
	}
```

実行し，`Notification Action`を実行すると通知が発行されます。

# ダイアログ
## ダイアログとは
メッセージを表示したり，OK, Cancelなどの選択, 文字入力などいろいろなことができます。

## ダイアログの実装
ダイアログは`Messages.show(.*)Dialog`メソッドで表示できます。

まず以下のActionを「アクションの登録」内で作成したgroup内に追加してください。

```xml:plugin.xml
<action class="<パッケージ名>.DialogAction" id="<プラグイン名>.DialogAction"
              text="Dialog" icon="AllIcons.Debugger.Console" />
```

`DialogAction`クラス内に下のように記述してください。

```java:DialogAction.java
@Override
	public void actionPerformed(AnActionEvent event) {
		String name = Messages.showInputDialog("What's your name?", "Ask Name", AllIcons.General.QuestionDialog);
		Messages.showMessageDialog("Hello, " + name + ". I'll help you.", "Greeting", Messages.getInformationIcon());
	}
```

このように特定の値を取得できるDialogからなにもないものもあります。
補完時に返り値を確認することで簡単にわかりますね。
~~JavascriptみたいにCallback地獄じゃなくてよかった~~

# おわりに
ちょっと量が多くなりました。そして後半端折り過ぎました。
わからない部分はこの記事のコメント欄で聞いていただけると返信できるかと思います。

さて、そろそろこんな~~クソみたいな~~導入を終えて独自言語はよと思うかもしれませんがまだです。
次はIDEがいろいろな動作をしたときにそれを受けて動作させられる`Extension Point`について解説します。

# 次
[ここ](https://qiita.com/syu_chan_1005/items/7dcb4c68c26aa0594e4e)