新手编写IntelliJ IDEA插件

2023-11-09

需求目的

可能你会想什么场景会需要用到插件开发,其实插件开发算是一种通用的解决方案,由服务平台定义标准让各自使用方进行自需的扩展。

这就像我们非常常用的 P3C 代码检查插件、代码审计插件、脚手架工程创建插件、自动化API提取插件、单元测试统计插件等等,这些都是在 IDEA 代码开发平台扩展出来的各项功能插件。

插件也可以说是一种解决方案,其实与你在代码编程时使用人家已经定义好的标准结构和功能下,扩展出自己的功能时是一样的。而这种方式也可以非常好的解决一些属于代码开发期间不易于放到代码提测后问题场景,并能及时提醒研发人员作出响应的修改处理。

环境说明

  • IntelliJ Platform Plugin JDK 不是自己安装的JDK1.8等,只有插件JDK才能开发插件

  • IntelliJ IDEA 2019.3.1 x64 如果你是其他版本,会涉及到 插件工程创建后版本修改

  • gradle-5.2.1 与 2019 IDEA 版本下的插件开发匹配,如果遇到一些环境问题可以参考我们开篇介绍

在官方文档 https://plugins.jetbrains.com/docs/intellij/disposers.html

(opens new window) 介绍开发 IDEA 插件的工程方式有两种,分别是模板方式和 Gradle 工程方式。这里我们分别演示下不同方式下工程的创建和所涉及到知识点内容的介绍,虽然两种方式都能创建 IDEA 插件工程,但更推荐使用 Gradle 方式。

模板方式创建

1. 创建引导

New -> Project -> IntelliJ Platform Plugin

2. 工程结构

lasse-idea-plugin-demo
├── resources
│   └── META-INF
│       └── plugin.xml 
└── src
    └── cn.lasse.idea.plugin
        └── MyAction.java 
  • plugin.xml 插件配置:开发描述、版本信息、Action事件入口、扩展信息(数据存放等)

  • src 具体的事件、UI窗体、工程逻辑代码开发

  • 另外类似 MyAction 的创建并不是直接创建普通类,而是通过 New -> Plugin DevKit -> Action 的方式进行创建,因为这样的创建方式可以再 plugin.xml 中自动添加 action 配置。当然如果你要是自己手动创建普通类那样创建 Action 类,则需要自己手动处理配置信息。

3. plugin.xml 配置

<idea-plugin>
  <id>cn.lasse.idea.plugin</id>
  <name>demo</name>
  <version>1.0</version>
  <vendor email="123456789@qq.com" >Lasse</vendor>

  <description><![CDATA[
      基于IDEA插件模板方式创建测试工程<br>
      <em>1. 学习IDEA插件工程搭建</em>
      <em>2. 验证插件基础功能实现</em>
    ]]></description>

  <change-notes><![CDATA[
      插件开发学习功能点<br>
      <em>1. 工程搭建</em>
      <em>2. 菜单读取</em>
      <em>3. 获取配置</em>
      <em>4. 回显页面</em>
    ]]>
  </change-notes>

  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
  <idea-version since-build="173.0"/>

  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <depends>com.intellij.modules.platform</depends>

  <extensions defaultExtensionNs="com.intellij">
    <!-- Add your extensions here -->
  </extensions>

  <actions>
    <!-- Add your actions here -->
    <action id="MyAction" class="cn.lasse.idea.plugin.MyAction" text="MyAction" description="MyAction">
      <add-to-group group-id="FileMenu" anchor="first"/>
    </action>

  </actions>
</idea-plugin>
  • 这里重点看 actions 其他上面的工程信息、版本描述、个人资料都按照自己的信息填写就行,不会影响插件运行。

  • actions 下是关于所有事件入口的配置,也就是你希望让你的 IDEA 插件在 IDEA 窗体中什么地方展示,以及配置快捷键等。这里的配置说明是在 FileMenu 下的第一个入口即为你的插件。

4. MyAction 事件入口

public class MyAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        Project project = e.getData(PlatformDataKeys.PROJECT);
        PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
        String classPath = psiFile.getVirtualFile().getPath();

        Messages.showMessageDialog(project, "本少爷说你的路径是: " + classPath, "Hi IDEA Plugin", Messages.getInformationIcon());
    }
}
  • 在 MyAction 事件入口中获取 Project 工程信息、PsiFile 文件信息,以及对应的类路径。

  • 最后在 Messages.showMessageDialog 下打印,这样把鼠标放到工程类下,在点这个按钮的时候就可以看到类的路径弹窗了。

5. 运行测试

  • 点击 Plugin 绿色箭头,和正常启动程序一样

  • 这个时候它会打开一个新的 IDEA 工程,并在这个工程中默认安装你开发好的插件

  • 在新打开的 IDEA 插件工程中,选中工程类后,点击 File -> MyAction

6.运行结果

通过测试运行效果可以看到,已经可以打出工程下类的路径信息了。你也可以尝试把Action的入口放到其他按钮下进行测试

Gradle 方式创建(推荐)

1. 创建引导

New -> Project -> Gradle 选中 Java & IntelliJ Platform Plugin

2. 工程结构

lasse-idea-plugin-create-project-by-gradle
├── .gradle
└── src
    ├── main
    │   └── java
    │   	└── cn.lasse.guide.idea.plugin 
    │       	└── MyAction.java    
    ├── resources
    │   └── META-INF
    │       └── plugin.xml 
    ├── build.gradle  
    └── gradle.properties
  • 与模板方式创建 Gradle 主要差异在 build.gradle、gradle.properties 内容的配置,这两个文件主要是处理 Gradle 相关信息的,其中 gradle.properties 用于配置 JVM Xmx 参数的,避免下载耗费资源较大崩溃。

  • plugin.xml 配置插件入口等内容,MyAction 是事件入口。

3. build.gradle 配置

plugins {
    id 'java'
    id 'org.jetbrains.intellij' version '0.6.3'
}

group 'cn.bugstack.guide.idea.plugin'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
    version '2019.3.1'
}
patchPluginXml {
    changeNotes """
      <![CDATA[
      插件开发学习功能点<br>
      <em>1. 工程搭建</em>
      <em>2. 菜单读取</em>
      <em>3. 获取配置</em>
      <em>4. 回显页面</em>
    ]]>"""
}
  • gradle 与 maven 的使用配置上,还是可以相通的找到一些类似的地方的,如果没有使用过 gradle 也是可以使用的。

  • 这里需要注意 plugins 中 id 'org.jetbrains.intellij' version '0.6.3' 默认创建工程的版本有点高,与 gradle 5.x 不匹配。不过你可以尝试调试合适版本进行使用

4. MyAction 事件入口

public class MyAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        Project project = e.getData(PlatformDataKeys.PROJECT);
        PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
        String classPath = psiFile.getVirtualFile().getPath();

        Messages.showMessageDialog(project, "本少爷说你的路径是: " + classPath, "Hi IDEA Plugin", Messages.getInformationIcon());
    }
}

5. 运行测试

  • 点击 Plugin 绿色箭头,和正常启动程序一样

  • 这个时候它会打开一个新的 IDEA 工程,并在这个工程中默认安装你开发好的插件

  • 在新打开的 IDEA 插件工程中,选中工程类后,点击 File -> MyAction

6.运行结果

通过测试运行效果可以看到,已经可以打出工程下类的路径信息了。你也可以尝试把Action的入口放到其他按钮下进行测试

总结

  • 整篇内容的学习还是蛮简单的,哪怕你之前没开发过 IDEA 插件,按照这样的套路往下折腾也是可以完成插件开发的。类似这样的知识内容只是平时常做业务开发所以接触的也不多,乍一听上去还是很陌生的,不过有这样的资料就可以上手了。

  • 本章节初步介绍 IDEA 插件的方式和一个非常简单的基本功能,后续我们在 Gradle 创建插件的基础上,继续开发其他案例功能,逐步学习 IDEA 插件开发用到的各项技巧用于完成所需要解决的问题。

  • 在学习的过程中可以自行尝试扩展一些其他组件入口,打印不同的工程信息。就像你使用的一些的插件一样,帮助你生成get、set,或者提取采集接口信息,也包括你写了多少行代码,思考它们是如何实现的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

新手编写IntelliJ IDEA插件 的相关文章

  • 正则表达式 - 捕获所有重复组

    我有如下字符串 property one some text email protected cdn cgi l email protection another optional text here etc 其中包含 里面的字符串 我想通
  • 学习 Java Native Access 时出现 com.sun.glass.ui 包错误

    我正在尝试在 JavaFX 项目中使用 Undecorated 阶段 stage initStyle StageStyle UNDECORATED 它是一个模块化的 Gradle 项目 它也是一个多项目构建 https guides gra
  • 在 JSF/JSP EL 和 Javascript 中连接字符串[重复]

    这个问题在这里已经有答案了 我在使用 EL 和 javascript 函数 JSF 1 2 Facelets Richfaces 3 3 0GA 时遇到问题 我有一个页面包含另一个组合
  • 编写代码来处理单词列表并删除单词中的所有空格

    该代码应该检查字符串数组并查看单词之间是否有空格 这是一个例子 every near ing checking food stand value 应改为hold every nearing checking food stand value
  • Hibernate中通过ID获取对象

    我注意到我们的高级开发人员使用以下代码通过 ID 检索实体 Override public Source get Long id Session session getSession if session null session sess
  • Java Swing - 在运行时动态切换语言环境

    我了解如何国际化 java 程序 但我有一个问题 我的程序中的语言可以随时切换 但我的程序可以存在多种状态 这意味着它可能会也可能不会打开多个 JLabels JPanel JFrame 等 是否有一个类或方法可以将当前的 GUI 更新为切
  • ffmpeg 用于屏幕捕获?

    所以我有一个小程序来捕获屏幕和计算机麦克风的声音 然后屏幕截图被编码为 ScreenVideo2 声音被编码为 AAC 如何使用 ffmpeg 逐帧混合 然后将混合输出发送到 wowza 媒体服务器 如果用ffmpeg无法完成 您能提供一些
  • 使用简单的 UPDATE 查询“不支持 DML 操作”

    我收到错误Not supported for DML operations当我使用以下 HQL 时 Query UPDATE WorkstationEntity w SET w lastActivity timestamp WHERE w
  • Android ImageView未加载

    我正在使用 android imageView 并将图像放入可绘制文件夹中 并将 imageView 源更改为该图像 但它没有在预览面板中显示图像 当我在 android studio 中打开图片时 它显示这样的错误 但我可以在电脑桌面上打
  • 了解 Android 上的默认键盘

    我想知道 Android 中用户选择的默认键盘 我知道我可以使用以下命令访问启用的输入法列表InputMethodManager 但我想知道用户当前使用的是哪一个 到目前为止 我已经尝试获取当前的输入法子类型 InputMethodMana
  • Android MediaCodec 在异步模式下比同步模式下慢?

    再次 我有一个关于 Android 的 MediaCodec 类的问题 我已成功解码原始 h264 内容并将结果显示在两个纹理视图中 h264 流来自运行 openGL 场景的服务器 该场景有一个摄像头 因此可以响应用户输入 为了进一步减少
  • 如何使用 RestTemplate 禁用编码

    我正在使用 REST 模板有意在请求 uri 中发送 例如 items a b String responseEntity restTemplate exchange items a b requestObj getHttpMethod r
  • Java 数组返回奇怪的输出[重复]

    这个问题在这里已经有答案了 我正在为家庭作业问题创建一个方法 该方法返回数组中的最高值 我正在使用一个 for循环将数字输入到数组中 输入代码如下所示 int array new int n for i 0 i
  • Spring - 捕获bean创建异常

    我想在我的代码中捕获 bean 实例化异常 我有什么选择 一种方法是使用基于 Java 的容器配置 Configuration public class AppConfig Bean public SomeBean someBean try
  • Hibernate + Oracle IN 子句限制,如何解决?

    我知道这个问题已经发了很多次了 但我想问一下细节 使用 Oracle 您不能向 IN 子句传递超过 1000 个参数 因此将 hibernate 与 Oracle 一起使用可能有一些解决此问题的方案 例如 1 对于每个 1000 个参数列表
  • 如何动态更新属性文件?

    我的应用程序是一个批处理过程 它从 application properties 文件中提取环境变量 我使用的密码必须每隔几个月更新一次 我想自动化密码更新过程并将更新后的密码保存在属性文件中 以便在将来的运行中使用 但我尝试进行的任何更新
  • 如何使用 Spring 状态机在状态转换期间引发异常

    我试图了解状态转换期间操作如何抛出异常 我配置了这个简单的状态机 transitions withExternal source State A1 target State A2 event Event E1 action executeA
  • 在java中读取文本文件[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 当每行都包含整数 字符串和双精度数时 如何在 Java 中读取 txt 文件并将每一行放入数组中 每行都有不同数量的单词 数字 Try
  • 无法查找 Websphere 8.5 中是否启用了 SSL

    我编写了一个简单的 ejb 瘦客户端来查找 IBM WebSphere 8 5 中部署的 bean 当服务器上未启用 SSL 时 我能够成功查找 bean 但是一旦启用 SSL 我就开始收到下面提到的异常 This is how I ena
  • 总小时数无法从 Android 插入 MySQL

    我使用以下公式获得总小时数 public void updateTotalHours int a SplitTime objMyCustomBaseAdapter getFistTime int b SplitTime objMyCusto

随机推荐

  • 创建React项目

    在开发React项目前最关键的当然是项目的创建 现在的前端工程化使得前端项目的创建也变得越来越复杂 在这里介绍三种从零开始创建React项目的方式 分别是在浏览器中直接引入 使用官方脚手架create react app 使用Webpack
  • 不会盗QQ,还当什么程序员?

    上面这个段子估计很多朋友都看过 程序员被黑过无数次 在其他人眼中 仿佛我们需要写得了木马 翻得了围墙 修得了电脑 找得到资源 但凡是跟计算机沾点边的 咱都得会才行 段子归段子 言归正传 对于咱们程序员来说 多多少少了解一些信息安全的技术知识
  • 打印HashMap的方法分享

    HashMap简介 Hash Map是哈希表基于 Map 接口的实现类 HashMap用于存储数据 允许使用null值和null键 除了非同步和允许使用 null 之外 HashMap 类与 Hashtable 大致相同 HashMap不保
  • 区块链三加一:什么是量化交易

    量化交易是指以先进的数学模型替代人为的主观判断 利用计算机技术从庞大的历史数据中海选能带来超额收益的多种 大概率 事件以制定策略 极大地减少了投资者情绪波动的影响 避免在市场极度狂热或悲观的情况下作出非理性的投资决策 量化交易 有时候也称自
  • Kali Linux Armitage生成被控端和主控端

    目录 说明 使用 Armitage生成被控端和主控端 说明 按照 Kali Linux2 网络渗透测试实践指南 第二版 第八章操作 仅供学习讨论使用 请勿进行非法操作 使用 Armitage生成被控端和主控端 选中 payload 然后选择
  • 深入解析锂电池保护电路工作原理

    1 锂离子电池介绍 锂离子电池是一种二次电池 充电电池 它主要依靠锂离子在正极和负极之间移动来工作 在充放电过程中 Li 在两个电极之间往返嵌入和脱嵌 充电时 Li 从正极脱嵌 经过电解质嵌入负极 负极处于富锂状态 放电时则相反 锂离子电池
  • 对象不支持“addEventListener”属性或方法 ie8 jquery

    解决方法 1 请查看你使用的jquery版本 2 jQuery 2 x 已经不支持IE9以下的IE浏览器 如果你想继续支持IE6 7 8 请使用jQuery 1 x版本 最新版本 jQuery 1 11 0 3 如果要兼容 IE 6 7 8
  • 假设检验/T检验/F检验/Z检验/卡方检验

    显著性水平 一个概率值 原假设为真时 拒绝原假设的概率 表示为 alpha 常用取值为0 01 0 05 0 10 什么是P值 p值是当原假设为真时样本观察结果及更极端结果出现的概率 如果P值很小 说明这种情况发生的概率很小 如果这种情况还
  • react面试题(三)

    1 setState 何时同步何时异步 1 setState 只在合成事件 react为了解决跨平台 兼容性问题 自己封装了一套事件机制 代理了原生的事件 像在jsx中常见的onClick onChange这些都是合成事件 和钩子函数 生命
  • hive遇到的错误

    1 数据库的命名不能用数字开头 0 jdbc hive2 192 168 171 151 10000 gt create database 0328 不区分大小写字母 Error Error while compiling statemen
  • 离散数学期末复习-求主范式

    文章目录 析取范式与合取范式 定义 简单析取式 析取式 简单合取式 合取式 析取范式 合取范式 范式 公式A的析取范式 公式A的合取范式 命题公式的范式 求公式A的范式的步骤 求公式的范式举例 极大项与极小项 定义 主析取范式与主合取范式
  • 银河麒麟操作系统(kylin os)学习

    poweroff 关机命令 sudo su 进入超级用户 su username 切普通用户 Ctrl Alt t 打开终端terminal窗口 Ctrl Alt d 最小化全部应用 然后显示桌面 dpkg i libqt5 deb 安装d
  • 安卓app与阿里云服务器的无线通信(非局域网)

    参考 安卓app与阿里云服务器的无线通信 非局域网 作者 图触靓 发布时间 2020 08 01 16 13 14 网址 https blog csdn net bhbhhyg article details 107732156 目录 写在
  • react学习笔记9:循环处理和数组map函数

    为什么80 的码农都做不了架构师 gt gt gt 在我们实际开发中 循环是必不可少的 尤其在表格中的数据显示 我们会把ajax的json数据显示在表格中 1 一个最简单的例子 import React from react import
  • STM32与FPGA之间的SPI通讯

    STM32与FPGA之间的SPI通讯 SPI通讯协议 SPI协议物理层 协议层 STM32的SPI特性及架构 STM32的SPI架构 SPI初始化结构体 STM32标准库 STM32实验代码 FPGA从机代码编写 实验结果 SPI通讯协议
  • 车间束流变压器定标-2021.2.3

    标定了这么多次 感觉这是最来劲的一次 就兴奋的贴在这里了 无他 因为国产精品示波器的使用 试了一下极限 结果喜人 眼神好的留意一下最后一幅图 看看惊不惊艳 惨不忍睹的顶降还是无视吧 加工的这一批次的磁环太丿了 车间束流变压器定标 2021
  • Ubuntu安装SSH/FTP/NFS

    sudo apt get update 一 SSH sudo apt get install openssh server sudo ps e grep ssh 有出现sshd说明ssh服务已经启动 负责执行 sudo service ss
  • 在Windows和树莓派之间通过WinSCP传送文件,并开启root用户远程登录。

    目录 下载WinSCP工具 设置树莓派root用户密码 打开root远程登录的权限 可选 使用WinSCP远程登录 下载WinSCP工具 要想在Windows和树莓派之间传输文件 我们需要借助一个工具WinSCP WIn指的是Windows
  • 【VUE】vue组件之间通信有几种方式

    vue组件之间通信可分为以下几种 props和 emit 也就是常说的父子组件通信 常用 attrs和 listeners 中央事件总线 非父子组件间通信 v model provide和inject parent和 children vu
  • 新手编写IntelliJ IDEA插件

    需求目的 可能你会想什么场景会需要用到插件开发 其实插件开发算是一种通用的解决方案 由服务平台定义标准让各自使用方进行自需的扩展 这就像我们非常常用的 P3C 代码检查插件 代码审计插件 脚手架工程创建插件 自动化API提取插件 单元测试统