网站设计的总结,网站的外链接数,wordpress中文前端,ios开发者账号有什么用系列文章 
IntelliJ IDE 插件开发 |#xff08;一#xff09;快速入门IntelliJ IDE 插件开发 |#xff08;二#xff09;UI 界面与数据持久化IntelliJ IDE 插件开发 |#xff08;三#xff09;消息通知与事件监听 
前言 
在前两篇文章中讲解了关于插件开发的基础知识一快速入门IntelliJ IDE 插件开发 |二UI 界面与数据持久化IntelliJ IDE 插件开发 |三消息通知与事件监听 
前言 
在前两篇文章中讲解了关于插件开发的基础知识本文将介绍关于消息通知和事件监听方面的内容关于 IntelliJ IDE 插件开发的基本内容也就到此为止在下一篇文章中将开发一个简单的插件对这部分内容做一个总结后续再介绍关于虚拟文件和PSI相关的知识最后以一个代码生成插件作为结尾。话不多说下面就开始本文的主题同时本文涉及到的的完整代码已上传到Github。 
消息通知 
在 IntelliJ IDE 中用于展示消息提示的方式有很多种例如侧边栏的消息通知、对话框、鼠标悬浮代码时出现的弹框等等下面就一一进行介绍。 
侧边栏通知 
这种通知是在 IDE 内的右下角进行显示同时这类消息会集中收集在消息通知中可进行查看如下图所示并且还可以让用户在Settings | Appearance  Behavior | Notifications中设置。 这种通知可使用Notifications.Bus.notify()方法或NotificationGroupManager类来进行实现例如上面的例子如果使用Notifications.Bus.notify()方法就是 
val notification  Notification(listener, Hello, world!, NotificationType.INFORMATION)
Notifications.Bus.notify(notification, e.project)可以看到需要传递两个参数一个是通知对象一个是项目对象可选。不过核心还是Notification这个通知类其中推荐使用的构造方式有两种 
Notification(String groupId, String content, NotificationType type)Notification(String groupId, String title, String content, NotificationType type) 
在上述例子里使用的则是第一个构造参数方式其中第一个参数是分组 id可以使用系统的已有的分组也可以选择自己创建分组这里还是推荐自行创建只要在 plugin.xml 中加入如下配置即可 
extensions defaultExtensionNscom.intellijnotificationGroup idlistener displayTypeBALLOON/
/extensions其中配置的 id 就可以使用了。 
对于第二参数则是我们要显示的内容如果选择的是第二个构造函数则可以设置消息的标题效果如下 这里的内容也支持使用 HTML 标签 
val content  h4四级标题h1p第一段原色字体/pp stylecolor: blue;第二段蓝色字体/p
.trimIndent()
val notification  Notification(listener, Title, content, NotificationType.INFORMATION)
Notifications.Bus.notify(notification, e.project)对应的效果如下 最后一个参数则是消息的类型总共有四种IDE_UPDATE、INFORMATION、WARNING、ERROR效果如下图所示 同样地如果使用NotificationGroupManager类则按照以下方式使用即可其中 Title 参数也是可选项 
NotificationGroupManager.getInstance().getNotificationGroup(listener).createNotification(Title, Hello, world!, NotificationType.INFORMATION).notify(e.project)除了以上设置内容之外相信你也经常可以看到类似如下包含可点击内容的消息通知 可以通过 Notification 类的addAction方法可添加多个 Action 实现类似的效果 
val notification  Notification(listener, Title, Hello, world!, NotificationType.INFORMATION)
notification.addAction(object : NotificationAction(ShowProjectStructureSettings) {override fun actionPerformed(e: AnActionEvent, notification: Notification) {// 用于打开设置界面, 这里的 ShowSettings 是 IDEA 定义的常量值ActionManager.getInstance().getAction(ShowSettings).actionPerformed(e)}
})
Notifications.Bus.notify(notification, e.project)最终效果如下 如果设置了多个 Action 无法在一行显示则默认会进行折叠通过点击 More 可以进行查看并操作 ActionManager.getInstance().getAction(actionName).actionPerformed(e) 可根据 Action 的 id 调用自行创建的或者平台已定义的 Action例如打开设置界面这里的 ShowSettings 就是已经定义好的  也就是说只要我们知道内部定义的 Action 对应的 id我们也就可以自由地使用平台已有的功能同时如果有类似功能需求的时候还可以根据相应的类找到对应源码然后我们再进行修改即可。哪有没有快速知道一个操作对应 Action 的方法呢还好平台内部也给我们准备了内部工具打开和使用方式参考开启内部工具部分进行查看。 对话框通知 
对话框通知的一般效果如下 官方推荐使用DialogWrapper抽象类来创建上面效果对应的代码如下 
class DialogDemo(private val project: Project): DialogWrapper(project) {init {// 设置标题并初始化title  Titleinit()}// 创建布局面板override fun createCenterPanel(): JComponent {return panel {row {label(Hello, world!)}}}}其中 title 用于设置对话框左上角的标题createCenterPanel()则用于创建布局内容这里的布局对象同样支持我们在第二篇文章中的创建方式也就是说除了基本的文本信息各种表单输入框也都是支持的。而这里为了方便就使用了Koltin UI DSL也很好理解可以参考官方文档进行学习后续会再写一篇文章进行讲解这里就不再展开说了。 
当然除了以上基本的对话框内容DialogWrapper还支持自定义按钮事件并且可以显示帮助按钮以及不再展示的提示 上述效果对应的代码如下 
class DialogDemo(private val project: Project): DialogWrapper(project) {private lateinit var checkBox: CellJBCheckBoxinit {// 设置标题并初始化title  Titleinit()}// 创建 Dont show again 选择框override fun createDoNotAskCheckbox(): JComponent {return panel { row { checkBox  checkBox(Do not show again)}}}// 设置帮助按钮 idoverride fun getHelpId(): String {return ListenerHelp}// 设置帮助按钮的 Tooltipoverride fun setHelpTooltip(helpButton: JButton) {helpButton.toolTipText  Tip}// 处理帮助按钮事件override fun doHelpAction() {showInfo(Help)}// 处理 OK 按钮事件override fun doOKAction() {super.doOKAction()showInfo(OK, value: ${checkBox.selected()})}// 处理取消按钮事件override fun doCancelAction() {super.doCancelAction()showInfo(Cancel)}// 展示消息private fun showInfo(msg: String) {Notifications.Bus.notify(Notification(listener, msg, NotificationType.INFORMATION), project)}// 创建布局面板override fun createCenterPanel(): JComponent {return panel {row {label(Hello, world!)}}}}如果还有其它定制化需求重写DialogWrapper内的相应方法即可。如果我们只是为了显示简单的文本信息类似下述效果 也可以选择平台已经封装好的com.intellij.openapi.ui.Messages类使用其中的工具方法即可上述效果只需要一行代码即可 
Messages.showInfoMessage(Hello, world!, Title)在Messages类中已经封装好了很多基础对话框这里就不再一一展示。 
编辑器提示 
正如标题这种信息的展示方式是在编辑器中通过悬浮框展示的类似下述效果 使用方式也很简单只需要一行代码即可 
e.getData(PlatformDataKeys.EDITOR)?.let { HintManager.getInstance().showInformationHint(it, Information)
}同时除了showInformationHint还支持showErrorHint展示错误提示信息 不过还有一个showQuestionHint使用较为复杂在 IDEA 中提示我们导包就是通过这种方式 这种通知方式除了包含提示外还会对指定单词增加下划线这里就不复现完整的效果了只展示下基础的使用方式 
e.getData(PlatformDataKeys.EDITOR)?.let {HintManager.getInstance().showQuestionHint(it, Question, it.caretModel.offset, it.caretModel.offset  6) {true}
}效果如下 编辑器横幅 
当我们新建一个 Java 项目缺没有配置 JDK通常会在编辑器内出现类似下图的提示 这个提示配置 JDK 的提示就是编辑器横幅的效果。 
实现这个效果也很简单只需要继承EditorNotificationProvider并重写其中的方法即可 
class EditorBanner: EditorNotificationProvider {override fun collectNotificationData(project: Project, virtualFile: VirtualFile): Functionin FileEditor, out JComponent? {return Function {val banner  EditorNotificationPanel()banner.text  EditorBannerbanner.toolTipText  ShowSettingsbanner.createActionLabel(ShowSettings) {ShowSettingsUtil.getInstance().showSettingsDialog(project, Editor)}banner}}}然后在plugin.xml中增加如下配置 
extensions defaultExtensionNscom.intellijeditorNotificationProvider implementationcn.butterfly.listener.ui.EditorBanner/
/extensions最终效果如下 这里展示编辑器横幅一般是先获取本地时候是否缺少指定配置如果判断已经包含某个配置则 collectNotificationData 需要返回 null否则才需要创建 banner 进行展示。 “Got It” 提示 
在更新 IDEA 后我们通常能看到类似下图中介绍新功能的提示 这种效果也很容易实现只需要使用GotItTooltip这个类即可在这里我们结合前文对话框通知中创建的帮助按钮来使用只展示变更部分 
private lateinit var helpButton: JButton// 设置帮助按钮的 Tooltip
override fun setHelpTooltip(helpButton: JButton) {helpButton.toolTipText  Tipthis.helpButton  helpButton
}// 处理帮助按钮事件
override fun doHelpAction() {showInfo(Help)GotItTooltip(listener.tip.id, GotItTooltip).show(helpButton, GotItTooltip.BOTTOM_MIDDLE)
}可以得到如下效果点击帮助按钮后出现 GotItTooltip 使用了建造者模式因此配置项可通过链式调用可自行选择配置项 弹出框 
除了以上常见的消息展示方式外还有一种弹出框选项的方式当我们使用Ctrl  Shift  Alt  /快捷键的时候会出现以下弹出框 这种弹出框则需要使用JBPopupFactory进行创建使用方式也很简单 
class PopupAction:AnAction() {override fun actionPerformed(e: AnActionEvent) {JBPopupFactory.getInstance().createListPopup(MyListPopupStep(Title, arrayOf(Option 1, Option 2, Option 3))).showInFocusCenter()}}class MyListPopupStep constructor(title: String?, values: ArrayString?) : BaseListPopupStepString(title, *values) {override fun onChosen(selectedValue: String, finalChoice: Boolean): PopupStep* {// 选中事件return FINAL_CHOICE}override fun getIconFor(value: String): Icon? {// 设置图标return null}override fun isMnemonicsNavigationEnabled(): Boolean  false}以上代码可以实现如下的效果 除了使用createListPopup还可以直接选择使用createMessage直接展示信息或者使用createConfirmation展示只有 yes 和 no 的弹出框 使用createMessage(Hello, world!)的效果 使用createConfirmation(Title, {}, 0)的效果 事件监听 
在开发插件的过程中我们有时候需要在项目打开或关闭的时候去完成一些操作而 IntelliJ 平台也为我们提供了相应的监听器类当然除了项目监听平台包含插件还自带了很多其它类型的监听器这里就不逐一介绍了以项目监听为例然后再说明如何自定义一个事件监听器。 
项目监听器 
对项目打开和关闭的监听方式很简单只需要继承ProjectManagerListener类即可然后既可以在相应方法中处理对应操作 
class MyProjectManagerListener: ProjectManagerListener {init {// 项目启动处理val notification  Notification(listener, Title, Open, NotificationType.INFORMATION)Notifications.Bus.notify(notification, null)}override fun projectClosing(project: Project) {// 项目即将关闭println(Closing)}}同时在plugin.xml中增加如下配置 
projectListenerslistener classcn.butterfly.listener.listener.MyProjectManagerListenertopiccom.intellij.openapi.project.ProjectManagerListener/
/projectListeners 
在新版本中平台建议我们继承ProjectActivity类并通过postStartupActivity扩展点来实现这里也展示一下使用方法 
class MyProjectActivity: ProjectActivity {override suspend fun execute(project: Project) {val notification  Notification(listener, Title, Open, NotificationType.INFORMATION)Notifications.Bus.notify(notification, null)}}然后也需要在plugin.xml中增加配置 
extensions defaultExtensionNscom.intellijpostStartupActivity implementationcn.butterfly.listener.listener.MyProjectActivity/
/extensions自定义事件监听器 
在 IntelliJ 平台中的事件可以看作是发布订阅的模式我们需要先定义一个主题然后发布者发布相应的事件订阅者实现对应的监听器事件即可。继续使用前文中的帮助按钮的例子如果点击了帮助按钮我们就在界面中显示帮助按钮被点击下面介绍如何实现这个功能。 
首先自定义一个监听器 
interface MyListener {companion object {var MY_TOPIC: TopicMyListener  Topic.create(listener, MyListener::class.java)}fun afterHelpBtnClicked(msg: String)}然后定义实现类 
class MyListenerA: MyListener {override fun afterHelpBtnClicked(msg: String) {Messages.showInfoMessage(msg, Title)}}之后在plugin.xml中注册 
projectListenerslistener classcn.butterfly.listener.listener.MyListenerAtopiccn.butterfly.listener.listener.MyListener/
/projectListeners最后在点击了帮助按钮后发布事件用于测试 
// 处理帮助按钮事件
override fun doHelpAction() {showInfo(Help)// 发布事件project.messageBus.syncPublisher(MyListener.MY_TOPIC).afterHelpBtnClicked(点击了帮助按钮)GotItTooltip(listener.tip.id, GotItTooltip).show(helpButton, GotItTooltip.BOTTOM_MIDDLE)
}效果如下 其它平台自带监听器 
除了上文提到的项目监听器平台还提供了很多其它监听器还可以使用其它插件内定义的监听器比如 Git 插件的一些事件参考上述自定义监听器的实现和使用方式即可完整列表可参考官方文档。 
开启内部工具 
选择Help | Edit Custom Properties...然后在文件内加上idea.is.internaltrue的配置最后保存文件并重启 IDEA 即可。 
重启后我们就可以使用了例如上文提到的查看某个操作对应 Action 的 id参考下述动图步骤即可可以看到在打开设置界面后里面出现了我们前文使用的ShowSettings这个 id 内部工具的使用先到此为止由于其中实用功能挺多的就在后续专门用一篇文章进行讲解。 
总结 
本文讲解了关于消息通知和事件监听相关的内容在下一篇文章将会实战开发一个类似 VSCode 中 Timer Master 的插件如下图所示来对这一部分的内容做一个小结。