首页 > 其他分享 >IDEA 插件开发(一):菜单及气泡通知

IDEA 插件开发(一):菜单及气泡通知

时间:2022-10-03 16:33:36浏览次数:81  
标签:插件 菜单 java intellij IDEA util base com

开发工具

开发工具使用 Intellij IDEA,官网下载地址:https://www.jetbrains.com/idea/download/other.html

推荐使用 2020.3.4 社区版(Community),原因如下:

  1. 免费开源,在开发插件的时候,可以调试源代码
  2. 自带 Plugin DevKit 插件(IDEA 的插件开发套件);
  3. 项目默认配置 IntelliJ Platform Plugin SDK
  4. 该版本支持 M1 芯片(Apple Silicon)。

设置源码路径(可选)

  1. 查看 build 号:打开 IDEA,Help | About,查看 build 号
    查看 build 号

  2. IDEA Community 源码切换到与 build 号相同的分支,点击 Code 按钮,选择 Download ZIP

对于我们选择的 2020.3.4,源码地址为:https://github.com/JetBrains/intellij-community/tree/203.8084

开发插件

创建插件工程

选择 File | New | Project,左侧栏中选择 IntelliJ Platform Plugin 工程类型:
IntelliJ Platform Plugin

点击 Next,设置工程名称位置,点击 Finish 完成创建:
设置工程

可以到 File | Project Structure 来自定义工程设置。

插件工程结构

插件工程内容:

├── .idea
│   ├── .gitignore // git 提交忽略文件
│   ├── encodings.xml // 编码配置
│   ├── misc.xml // 各种杂项
│   ├── modules.xml // 模块信息
│   ├── sonarlint // 代码扫描插件
│   ├── workspace.xml // 工作空间
├── FirstPlugin.iml  // 项目标识文件(infomation of module)
├── resources
│   └── META-INF
│      ├── plugin.xml // ★插件配置:开发描述、版本信息、Action 事件入口、扩展信息(数据存放等)
│      ├── pluginIcon.svg // ★插件图标:名称固定,不可修改,自己放入
│      ├── pluginIcon_dark.svg // ★暗色系主题下的图标
└── src               // ★具体的事件、UI 窗体、工程逻辑的 Java/Kotlin 代码

修改插件配置文件

下面示例描述了可在 plugin.xml 文件配置的主要元素:

<idea-plugin>

  <!-- 插件唯一 id,不能和其他插件项目重复,所以推荐使用 com.xxx.xxx 的格式
       插件不同版本之间不能更改,若没有指定,则与插件名称相同 -->
  <id>com.ageovb.first</id>

  <!-- 插件名称,别人在官方插件库搜索你的插件时使用的名称 -->
  <name>First</name>

  <!-- 插件版本号 -->
  <version>1.0.0</version>

  <!-- 供应商主页和email(不能使用默认值,必须修改成自己的)-->
  <vendor email="ageovb.com" url="http://www.ageovb.com">ageovb</vendor>

  <!-- 插件的描述,支持 HTML 标签;
       不能使用默认值,必须修改成自己的。并且需要大于 40 个字符 -->
  <description><![CDATA[
      基于IDEA插件模板方式创建测试工程<br>
      <em>1. 学习IDEA插件工程搭建</em>
      <em>2. 验证插件基础功能实现</em>
    ]]></description>

  <!-- 插件版本变更信息,支持 HTML 标签;
       将展示在 settings | Plugins 对话框和插件仓库的 Web 页面 -->
  <change-notes><![CDATA[
      插件开发学习功能点<br>
      <em>1. 工程搭建</em>
      <em>2. 菜单读取</em>
      <em>3. 添加菜单</em>
      <em>4. 气泡通知</em>
    ]]>
  </change-notes>
  <!-- 以上信息会被抽取至插件市场主页展示 -->

  <!-- 兼容最低版本 173,对应 2017.3 版本 -->
  <idea-version since-build="173.0"/>

  <!-- 插件所依赖的其他插件的 id -->
  <depends>com.intellij.modules.platform</depends>

  <!-- 声明该插件对 IDEA core 或其他插件的扩展 -->
  <extensions defaultExtensionNs="com.intellij">
    <!-- 2020.3 及以后的版本,注册通知服务 -->
    <!--<notificationGroup id="Custom Notification Group" displayType="BALLOON" key="notification.group.name"/>-->
  </extensions>

  <!-- 编写插件动作 -->
  <actions>
    <action id="first" class="com.ageovb.first.FirstAction" text="Notification" description="Test notification">
      <add-to-group group-id="ToolsMenu" anchor="first"/>
      <keyboard-shortcut keymap="$default" first-keystroke="meta I"/>
    </action>
  </actions>

</idea-plugin>

创建 Action

一个 Action 表示 IDEA 菜单里的一个 menu item 或工具栏上的一个按钮,通过继承 AnAction 实现,当选择一个 menu item 或点击工具栏上的按钮时,就会调用 AnAction 类的 actionPerformed() 方法。

实现自定义 Action 分两步:

  1. 定义一个或多个 action;
  2. 注册 action,将 item 添加到菜单或工具栏上。

新建 Action 文件

新建一个 Package,如 com.ageovb.first,然后右击新建 Action 文件:
新建 Action 文件

如果没有看到 Plugin DevKit 选项,说明项目没有配置 IntelliJ Platform Plugin SDK,推荐的 2020.3.4 不会出现该情况。

填写必要的信息:
菜单信息

编写 Action 代码

package com.ageovb.first;

import com.intellij.notification.Notification;
import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.MessageType;
import org.jetbrains.annotations.NotNull;

/**
 * 通过 Plugin Devkit 创建的 Action 继承了 AnAction
 */
public class FirstAction extends AnAction {
    /**
     * 需要实现点击事件发生之后的抽象方法
     */
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        // 这是老版本的,NotificationGroup 已经过时
        NotificationGroup notificationGroup = new NotificationGroup("Notification", NotificationDisplayType.BALLOON, false);
        Notification notification = notificationGroup.createNotification("Test notification", MessageType.INFO);
        Notifications.Bus.notify(notification);

        // 2020.3 及以后的版本可以在 plugin.xml 中注册通知服务,并编写通知工具类 NotifyUtil
        //NotifyUtil.notifyInfo(e.getProject(), "Test notification");
    }
}

运行插件

与正常 Java 项目一样,直接点击右上角的 Run 按钮运行插件:
运行插件

插件以 Debug/Run 模式运行时是在 SandBox(沙箱) 中进行的,不会影响当前的 IntelliJ IDEA,启动后选择 Tools | Notification
Tools 菜单

即可看到右下角的气泡通知:
气泡通知

运行错误解决

找不到 Python

2022-10-03 14:20:52,094 [   1141]   WARN - .intellij.util.EnvironmentUtil - can't get shell environment 
java.lang.RuntimeException: command [/bin/zsh, -l, -i, -c, '/Applications/IntelliJ IDEA CE.app/Contents/bin/printenv.py' '/var/folders/k2/b_96l4cx3hdfvybcbrwjvhw80000gn/T/intellij-shell-env.17742117045732721406.tmp']
	exit code:127 text:0 out:(anon):setopt:7: can't change option: monitor

[ERROR]: gitstatus failed to initialize.


  Add the following parameter to ~/.zshrc for extra diagnostics on error:

    GITSTATUS_LOG_LEVEL=DEBUG

  Restart Zsh to retry gitstatus initialization:

    exec zsh
env: python: No such file or directory
	at com.intellij.util.EnvironmentUtil$ShellEnvReader.runProcessAndReadOutputAndEnvs(EnvironmentUtil.java:353)
	at com.intellij.util.EnvironmentUtil$ShellEnvReader.readShellEnv(EnvironmentUtil.java:254)
	at com.intellij.util.EnvironmentUtil$ShellEnvReader.readShellEnv(EnvironmentUtil.java:269)
	at com.intellij.util.EnvironmentUtil.getShellEnv(EnvironmentUtil.java:204)
	at com.intellij.util.EnvironmentUtil.lambda$loadEnvironment$0(EnvironmentUtil.java:106)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
	at java.base/java.lang.Thread.run(Thread.java:834)

默认是使用 python 命令去获取 shell 环境变量的,即使我们使用 xcode-select --install 命令安装过开发者命令行工具,可以使用 ll /Library/Developer/CommandLineTools/usr/bin/python* 命令查看,并没有 python 命令,我们可以使用命令 sudo ln -s /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/bin/python3 /Library/Developer/CommandLineTools/usr/bin/python 创建一个软链接,让 python 实际调用 python3

找不到类 OpenURIHandler

2022-10-03 14:20:52,631 [   1678]   WARN - i.mac.MacOSApplicationProvider - com/apple/eawt/OpenURIHandler 
java.lang.NoClassDefFoundError: com/apple/eawt/OpenURIHandler
	at com.intellij.ui.mac.MacOSApplicationProvider.initApplication(MacOSApplicationProvider.java:57)
	at com.intellij.idea.ApplicationLoader.startApp(ApplicationLoader.kt:152)
	at com.intellij.idea.ApplicationLoader.executeInitAppInEdt(ApplicationLoader.kt:68)
	at com.intellij.idea.ApplicationLoader.access$executeInitAppInEdt(ApplicationLoader.kt:1)
	at com.intellij.idea.ApplicationLoader$initApplication$1$1.run(ApplicationLoader.kt:374)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.ClassNotFoundException: com.apple.eawt.OpenURIHandler
	at com.intellij.util.lang.UrlClassLoader.findClass(UrlClassLoader.java:338)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	... 18 more

这篇文章里指出,从 JDK 9 开始,已经不提供包 com.apple.eawtcom.apple.eio,取而代之的是 java.awt.desktop。不知道哪里的代码用的还是 JDK 8,目前不影响,先不用管。

缺少 Times 字体

Warning: the fonts "Times" and "Times" are not available for the Java logical font "Serif", which may have unexpected appearance or behavior. Re-enable the "Times" font to remove this warning.

下载并安装 Times 字体。

Gitee 地址

项目已上传到 Gitee。

参考资料

你们要的Intellij IDEA 插件开发秘籍,来了!
Idea插件开发-开发自己的第一款idea插件
IntelliJ -IDEA插件开发教程-UI篇-编辑提示、消息通知(五)

标签:插件,菜单,java,intellij,IDEA,util,base,com
From: https://www.cnblogs.com/ageovb/p/16749993.html

相关文章

  • C#(一沙框架) .net core3.1 SignalR 服务端推送消息至客户端的实现方法,用弹窗插件进行显
    C#(一沙框架).netcore3.1SignalR服务端推送消息至客户端的实现方法,用弹窗插件进行显示,非常美观实用运行效果:1、安装Microsoft.AspNetCore.SignalR(安装方法自行百度)2、引入......
  • idea Mac格式化代码快捷键
    ideaMac格式化代码快捷键:Command+option+L优秀不够,你是否无可替代软件测试交流QQ群:721256703,期待你的加入!!欢迎关注我的微信公众号:软件测试君......
  • Spring Tool 4 安装 Thymeleaf 3.0 插件
    目录参考资料说在前面最小要求步骤1.下载SpringTool4.7.12.下载thymeleaf的eclipse插件2.打开STS-Help-InstallNewSoftware...3.点击【Add...】-【Archive........
  • Vue2 插件
    概述Vue的插件就是一个js文件,里面允许我们完成一些特定的功能。使用创建一个插件plugins.jsexportdefault{install(Vue){//全局过滤器Vue.filt......
  • 杂记 idea相关
    彻底删除idea项目removemodule手动删除文件夹删除项目引用使用Everything搜索找到项目.contexts.zip和项目.tasks.zip两个文件,将其删除idea快捷键批量编辑:alt+......
  • 太棒了,这才称得上 Jupyter Notebook 五大效率插件
    ​​JupyterNotebook​​​是一个很棒的教学、探索和编程环境,但其功能不足也是出了名的。幸好,有许多方法可以改进这个不错的工具,如​​JupyterNotebook​​扩展工具。......
  • 如何将谷歌插件下载到本地?
    如何将谷歌插件下载到本地?在谷歌商店里找到想要下载的插件或在扩展程序里找到已安装的插件,复制插件的ID号。复制插件ID然后复制到id%3D和%26的中间部分。https:/......
  • 关于IDEA调试的一些基本操作
    一.怎么开启断点调试?随着开发的深入,越来越觉得高效的调试方法是多么的重要了,但我们一般上来就是敲一些代码,谁会去静下心来学一些看似没什么用的调试技巧呢?但这恰恰就是新......
  • markdown preview插件安装后无法同步显示网页
    安装了Plug用:checkhealth检查,说ruby有问题,按照提示,安装了编译环境,gcc和g++的都需要安装ruby没有问题了猜想:现在checkhealth只有python3那边说需要设置一个pythonhost......
  • 网络安全中常用浏览器插件、拓展
    引言现在的火狐、Edge( Chromium内核)、Chrome等浏览器带有插件、拓展(Plugin)的功能。这些插件中有的可以过滤广告,有的提供便捷的翻译,有的提供JavaScript脚本支持,方便用户的......