IntelliJ Platform Pluginの開発にて、ToolWindow上で、Dialog・Balloon・StatusBarなどを使って改行ありのメッセージを表示してみた

IntelliJ Platform Pluginを作っている際、何らかの方法でメッセージをUI上に表示したくなりました。

実現方法を調べたところ、公式ドキュメントに Notification として記載がありました。
Notifications | IntelliJ Platform Plugin SDK

そこで、各Notificationにて「改行ありのメッセージ」の表示をためしてみたときのメモを残します。

なお、今回は「ボタンをクリックしたらメッセージを表示する」形で実装します。

また、記事で説明に使う部分のみソースコードを記載しています。ToolWindowの登録方法など、ソースコード全体を知りたい場合は、後述のGithubソースコードを参照してください。

 
目次

 

環境

 

Messages.showMessageDialog()を使う

OKボタンだけあるダイアログを表示したい場合は、 Messages.showMessageDialog() を使うのが便利です。
Messages | Miscellaneous Swing Components | IntelliJ Platform Plugin SDK

 
では実装してみます。

最初に、イベントハンドラを持つボタンを用意します。

row {
    button("Message Dialog") { event -> handleMessageDialog(event)}
}

 
次に、イベントハンドラにて Messages.showMessageDialog() を使います。

private fun handleMessageDialog(event: ActionEvent) {
    // showMessageDialogの場合、改行文字を使えば改行される
    Messages.showMessageDialog("Message with Message Dialog. \n Hello world", "Dialog Title", Messages.getInformationIcon())
}

 
動作確認します。ボタンをクリックすると、画面中央にメッセージが表示されました。

 

DialogWrapperによる独自ダイアログを使う

Messages.showMessageDialog() のダイアログではない、独自ダイアログにメッセージを表示したい場合は DialogWrapper を継承した独自ダイアログが使えます。

DialogWrapper については、公式ドキュメントの以下に記載があります。
Dialogs | IntelliJ Platform Plugin SDK

 
では実装してみます。

まずは、DialogWrapper を継承した独自ダイアログを用意します。

このときの独自ダイアログの実装方針は以下とします。

実際のコードです。

class CustomNotificationDialog: DialogWrapper(true) {
    init {
        title = "Custom Dialog Title"

        init()
    }

    override fun createCenterPanel(): JComponent {
        return panel {
            row {
                // https://stackoverflow.com/a/1090112
                label("<html>Dialog message <br> Hello world</html>")
            }
        }
    }
}

 
続いて、ToolWindowのcontentにボタンを用意します。

row {
    button("Custom Dialog") { event -> handleCustomDialog(event) }
}

 
あとは、イベントハンドラで独自ダイアログを使って表示します。

private fun handleCustomDialog(event: ActionEvent) {
    CustomNotificationDialog().show()
}

 
動作確認します。ボタンをクリックすると、画面中央にメッセージが表示されました。

 

JBPopupFactoryによるポップアップを使う

ToolWindowでは、Popupを表示することもできます。
Popups | IntelliJ Platform Plugin SDK

 
では実装してみます。

まず、 JBPopupFactory による表示では、ToolWindowManagerのインスタンスが必要です。

ただ、ボタンのイベントハンドラのうち ActionEvent を受け取る実装では ToolWindowManager のインスタンス取得に必要な project という値が取得できません。

そこで、以前の記事で見た通り、project を取得するためにイベントハンドラにActionを指定する形で実装します。

Actionの実装方針は以下です。

  • ToolWindowManagerのインスタンスを取得
  • JBPopupFactoryの createConfirmation + showInCenterOf を使って、ToolWindowの中央にPopupを表示
    • createConfirmationの引数には Runnable インタフェースを実装したクラスが必要なので、 MyRunnable を別途用意
class ShowPopupAction : AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project ?: return
        val manager = ToolWindowManager.getInstance(project)
        val toolWindow = manager.getToolWindow("NotificationToolWindow")
        val factory = JBPopupFactory.getInstance()

        // createConfirmation() では、改行を設定できないっぽい
        factory.createConfirmation(
            "Message with popup <br> Hello world",
            "Yes\nclick",
            "No <br> click",
            MyRun(), 0)
            .showInCenterOf(toolWindow!!.component)
    }
}

class MyRun: Runnable {
    override fun run() {
        println("hello")
    }
}

 
あとはボタンを用意して、Actionを指定します。

row {
    button("Popup", ShowPopupAction())
}

 
動作確認します。ボタンをクリックすると、ToolWindowの中央にPopupが表示されました。

 
Dialogとの挙動の違いとしては、Popupの領域外をクリックするとPopupが自動的に閉じます。

また、今回 JBPopupFactorycreateConfirmation() によるPopupの場合、メッセージの改行はできませんでした。

 

Notification.Busによるバルーンを使う

ここまではダイアログによる表示を見てきましたが、IntelliJ Platformでは他にも通知する方法はあります。

まずは Notification.Bus を使ったバルーン表示です。

公式ドキュメントによると、ダイアログに比べて以下の利点があるとのことです。

  • The user can control the way each notification type is displayed under Settings | Appearance & Behavior | Notifications

  • All displayed notifications are gathered in the Event Log tool window and can be reviewed later

 
https://plugins.jetbrains.com/docs/intellij/notifications.html#top-level-notifications-balloons

 
では実装してみます。

まずはボタンを用意します。

row {
    button("Notification Bus") { event -> handleNotificationBus(event) }
}

 
続いて、イベントハンドラの中でバルーン表示を行います。

private fun handleNotificationBus(event: ActionEvent) {
    val notification = Notification(
        "notificationGroupId",
        "Notification Bus Title",
        "Message with Notification Bus <br> Hello world", // \n ではなく <br> タグで改行できる
        NotificationType.INFORMATION)
    Notifications.Bus.notify(notification)
}

 
最後に、バルーンのIDを plugin.xml に登録します。

id 属性には、 Notification のコンストラクタの第1引数の値を設定します。

<extensions defaultExtensionNs="com.intellij">
    ...
    <notificationGroup displayType="BALLOON" id="notificationGroupId" />
</extensions>

 
動作確認します。ボタンをクリックすると、バルーンが右下に表示されました。

 
また、Notifications を開くと、バルーン表示した内容が記録されていました。

 

ToolWindowManagerのnotifyByBalloon()によるバルーンを使う

ToolWindowでは、 ToolWindowManagerのnotifyByBalloon() でもメッセージのバルーン表示ができるようです。
Tool Window Notification | Tool Windows | IntelliJ Platform Plugin SDK

 
では実装してみます。

ToolWindowManagerを取得するためには project が必要なことから、Actions を作成します。

class ToolWindowNotificationAction: AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project ?: return
        ToolWindowManager.getInstance(project).notifyByBalloon(
            "NotificationToolWindow",
            MessageType.INFO,
            "Tool Window Notify <br> Hello world"
        )
    }
}

 
次に、Actionを実行するボタンを用意します。

row {
    button("Tool Window Notification", ToolWindowNotificationAction())
}

 
動作確認します。ボタンをクリックすると、ToolWindowタブにバルーンが表示されました。

 
ただ、 Notification.Bus とは異なり、 Notifications には登録されないようです。

 

StatusBarを使う

公式ドキュメントには記載を見つけられなかったのですが、WindowManager インスタンスgetStatusBar() メソッドを使うことで StatusBar にもメッセージを表示できます。

では実装してみます。

まずは Action を用意します。

class StatusBarMessageAction: AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project ?: return

        val statusBar = WindowManager.getInstance().getStatusBar(project)
        statusBar.let {
            it.info = "Message with Status Bar. \n Hello world" // 改行は効かない
        }
    }
}

 
次に、Actionを実行するボタンを用意します。

row {
    button("Status Bar", StatusBarMessageAction())
}

 
動作確認します。

最初、StatusBarには何も表示されません。

 
次に、ボタンをクリックするとStatusBarにメッセージが表示されました。

 
なお、Notificationsには何も登録されていません。

 

ソースコード

Githubにあげました。
https://github.com/thinkAmi-sandbox/hello_jetbrains_plugin

今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/hello_jetbrains_plugin/pull/18