IntelliJ Platform Pluginを作っている際、何らかの方法でメッセージをUI上に表示したくなりました。
実現方法を調べたところ、公式ドキュメントに Notification
として記載がありました。
Notifications | IntelliJ Platform Plugin SDK
そこで、各Notificationにて「改行ありのメッセージ」の表示をためしてみたときのメモを残します。
なお、今回は「ボタンをクリックしたらメッセージを表示する」形で実装します。
また、記事で説明に使う部分のみソースコードを記載しています。ToolWindowの登録方法など、ソースコード全体を知りたい場合は、後述のGithubのソースコードを参照してください。
目次
環境
- プラグインの開発環境
- Widnows 11
- IntelliJ IDEA 2023.3.4 Ultimate Edition
- IntelliJ Platform Plugin Template 1.12.0
- Kotlinで実装
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) {
Messages.showMessageDialog("Message with Message Dialog. \n Hello world", "Dialog Title", Messages.getInformationIcon())
}
動作確認します。ボタンをクリックすると、画面中央にメッセージが表示されました。
DialogWrapperによる独自ダイアログを使う
Messages.showMessageDialog()
のダイアログではない、独自ダイアログにメッセージを表示したい場合は DialogWrapper
を継承した独自ダイアログが使えます。
DialogWrapper
については、公式ドキュメントの以下に記載があります。
Dialogs | IntelliJ Platform Plugin SDK
では実装してみます。
まずは、DialogWrapper
を継承した独自ダイアログを用意します。
このときの独自ダイアログの実装方針は以下とします。
createCenterPanel()
をオーバーライドして、ダイアログのコンテンツを表示する
- メッセージの表示は
label
コンポーネントに記載する
label
コンポーネントで改行表示する場合、SwingのJLable同様、 <html>
タグと <br>
タグを使う
実際のコードです。
class CustomNotificationDialog: DialogWrapper(true) {
init {
title = "Custom Dialog Title"
init()
}
override fun createCenterPanel(): JComponent {
return panel {
row {
label("<html>Dialog message <br> Hello world</html>")
}
}
}
}
続いて、ToolWindowのcontentにボタンを用意します。
row {
button("Custom Dialog") { event -> handleCustomDialog(event) }
}
あとは、イベントハンドラで独自ダイアログを使って表示します。
private fun handleCustomDialog(event: ActionEvent) {
CustomNotificationDialog().show()
}
動作確認します。ボタンをクリックすると、画面中央にメッセージが表示されました。
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()
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が自動的に閉じます。
また、今回 JBPopupFactory
の createConfirmation()
による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",
NotificationType.INFORMATION)
Notifications.Bus.notify(notification)
}
最後に、バルーンのIDを plugin.xml
に登録します。
id
属性には、 Notification
のコンストラクタの第1引数の値を設定します。
<extensions defaultExtensionNs="com.intellij">
...
<notificationGroup displayType="BALLOON" id="notificationGroupId" />
</extensions>
動作確認します。ボタンをクリックすると、バルーンが右下に表示されました。
また、Notifications を開くと、バルーン表示した内容が記録されていました。
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