
简介面向IntelliJ IDEA插件开发初学者与进阶者的完整源码示例聚焦菜单、弹出框与鼠标右键数据交互等典型场景帮助读者快速掌握IDE插件开发核心流程。压缩包内共16个文件以Java源码、XML配置、SVG图标及项目结构文件为主Java类实现具体业务逻辑如动作注册、事件响应与界面绘制plugin.xml与META-INF声明扩展点与插件描述.iml和.idea目录保存模块参数与工作区设置resources目录管理图标等静态资源。内容覆盖Action事件监听、自定义对话框与弹出框、Swing组件应用等知识点从项目搭建到功能实现均有清晰线索适合边读边改动手验证。包体仅10KB目录精简、层级分明可直接导入IDE运行调试便于观察每一步配置对插件行为的影响。已有785人学习下载对于希望深入理解IntelliJ IDEA插件机制、快速上手插件开发的开发者具有很高的参考价值。1. IntelliJ IDEA 插件开发上手难在哪这份 demo 恰好覆盖了最卡人的一段不少 Java 开发者第一次想碰 idea插件开发都被同一个问题卡住IDE 的扩展点找不到、Action 不知道往哪注册好不容易照着官方文档写了个类装进 IDEA 却毫无反应。这份 idea插件详细源码demo.zip 把“右键菜单 → 弹窗 → 数据交互”这条最典型的链路摊开在你面前。压缩包里的工程不大包名是 com.rcc从 plugin.xml 注册 Action 到 actionPerformed 里弹对话框一条线走完。它适合两类人一类是刚装好 IDEA、想用真实工程练手的插件新人另一类是打算给团队内部 IDE 定制右键工具却没时间啃官方文档的在职开发。2. 先读懂工程骨架plugin.xml、Action 扩展点与资源目录的分工2.1 解压后这十几个文件各自守什么岗位拿到压缩包第一件事不是找代码而是先把目录结构认全。这个 demo 的结构是标准 IDEA 插件工程的简化版每个文件都有明确的职责搞清楚它们之后你自己建项目时就不会对着 IDE 生成的一堆文件发懵。文件/目录作用说明src/com/rccJava 源码根目录Action 类、对话框逻辑都在这resources/META-INF/plugin.xml插件描述文件插件 ID、名称、依赖、Action 注册全在这resources/META-INF/pluginIcon.svg插件显示图标浅色主题下显示resources/META-INF/pluginIcon_dark.svg插件深色图标深色主题下显示ideaPluginProject.iml模块配置文件IDEA 靠它识别模块结构、源码目录和依赖.idea/工作区配置含 misc.xml、modules.xml、workspace.xmlartifacts/ideaPluginProject_jar.xml打包描述定义如何把工程打成插件 jar.gitignoreGit 忽略规则排除 out、.idea 等生成目录很多人会忽略 artifacts 这个目录其实它是这个 demo 能否装进 IDEA 的关键。IDEA 插件本质是一个包含 META-INF/plugin.xml 的 jar 包而 Artifact 配置决定了打包时把哪些内容塞进这个 jar。你如果只是把源码放进 IDEA但不按这个配置打 jar那插件永远不会出现在 IDE 里。2.2 plugin.xml 是插件的身份证Action 注册的三要素IDEA 插件与普通 Java 程序最大的区别在于你写的类不是自己 new 出来的而是由 IDE 根据 plugin.xml 里的声明加载。IDEA 启动时扫描每个已安装插件的 META-INF/plugin.xml把里面注册的 Action、扩展点、监听器全部登记到全局注册表里。后续你在界面上点某个菜单、按某个快捷键IDE 最终会反射调用到你写的类。这个 demo 里的 plugin.xml 结构大致长这样你可以对照自己解压出来的文件看idea-plugin idcom.rcc.demo/id nameRcc Demo Plugin/name version1.0/version vendor emaildevexample.comRcc/vendor description![CDATA[ IDEA plugin development demo. ]]/description dependscom.intellij.modules.platform/depends actions action idcom.rcc.demo.ShowDialogAction classcom.rcc.demo.ShowDialogAction textRcc Demo Dialog descriptionShow a dialog from editor context menu add-to-group group-idEditorPopupMenu anchorfirst/ keyboard-shortcut keymap$default first-keystrokectrl alt R/ /action /actions /idea-plugin这段配置里最核心的是action标签里的三个属性id是这个 Action 的唯一标识class指向你写的 Java 类全限定名text是显示在右键菜单里的文字。add-to-group决定菜单出现在哪里EditorPopupMenu是编辑器内的右键菜单anchorfirst表示排在菜单最顶部可选值还有last、before、after。keyboard-shortcut是快捷键声明first-keystrokectrl alt R表示按下 CtrlAltR 就能触发这个 Action注意这个组合键不要和系统里其他软件冲突。depends声明插件依赖的模块com.intellij.modules.platform是最小化的平台依赖几乎所有基础插件都这么写。如果你声明了dependscom.intellij.modules.java/depends就表示插件依赖 Java 模块支持可以在插件里安全调用 Java 相关的 PSI 类。2.3 AnAction 的 actionPerformed 到底在做什么理解了注册机制再看源码就轻松了。demo 里 src 下的核心类一般是继承AnAction这是所有菜单动作的基类。你真正要重写的是它的actionPerformed方法——当用户点击你注册的菜单项时IDEA 会构造一个AnActionEvent对象传进来这个方法就会被触发。package com.rcc.demo; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; public class ShowDialogAction extends AnAction { Override public void actionPerformed(AnActionEvent e) { // 从事件对象中取出当前项目后续所有 IDE 相关操作都基于 project Project project e.getProject(); // 弹出一个模态对话框标题是 Rcc Demo Messages.showInfoMessage(project, Hello from e.getPlace(), Rcc Demo); } }e.getPlace()返回当前 Action 被触发的位置比如在编辑器右键触发时它对应的就是你在 plugin.xml 里写的EditorPopupMenu。e.getProject()拿到的是当前打开的项目对象——这是插件访问项目级服务、文件系统的入口。demo 里用Messages.showInfoMessage弹窗属于最原始的交互方式优点是代码简单、依赖少适合理解 Action 触发链路缺点是弹窗样式和 IDEA 原生皮肤不一致后面我会在第 5 部分聊怎么换成DialogWrapper。AnActionEvent里能拿到的远不止 Project还有鼠标所在位置的编辑器实例e.getData(CommonDataKeys.EDITOR)、当前选中的文件e.getData(CommonDataKeys.VIRTUAL_FILE)、甚至是 PSI 语法树节点。demo 只演示了最基础的用法但你要做的“右键菜单 → 拿选中文件 → 做处理 → 弹结果”这条链路已经完整了。实际开发中点右键后想读当前光标所在的代码元素就是在actionPerformed里从AnActionEvent取数据这个习惯从 demo 阶段就要养成。3. 从“能看”到“能跑”SDK 配置、打包 jar 与右键菜单落地3.1 装好 Plugin DevKit用社区版就能开始IDEA 插件开发有个容易劝退新手的点需要额外装一个名为“Plugin DevKit”的插件而且从 2020.x 版本开始它已经不再随 IDE 默认启用。你打开 IDEA 的 Settings → Plugins在 Marketplace 搜索“Plugin DevKit”安装后重启 IDE才能在新建项目时看到“IntelliJ Platform Plugin”这个模板。如果你是学生或者手里没有商业版授权用社区版做插件开发完全足够。社区版同样内置了 IntelliJ Platform SDK 的加载机制插件开发不是旗舰版专属功能。这个 demo 本身也只用到了平台级的 API不涉及 Spring、JavaEE 等语言支持模块社区版跑它没有任何障碍。3.2 把 demo 导入并配置 IntelliJ Platform SDK解压 zip 后用 IDEA 直接 File → Open 选择解压出来的 ideaPluginProject 文件夹注意选的是包含.iml文件的根目录不是 src。IDEA 会读取.iml里的模块描述把src标记为源码根目录把resources标记为资源目录。如果类路径标红多半是 SDK 还没配。打开 File → Project Structure → SDKs点加号选择“IntelliJ IDEA Plugin SDK”然后指向你本机 IDEA 的安装目录。Windows 下通常是C:\Program Files\JetBrains\IntelliJ IDEA Community Edition xxxmacOS 下是/Applications/IntelliJ IDEA CE.app/Contents。选完后 IDEA 会自动把这个 SDK 挂到工程模块上。这一步没做对后面会出现大面积的“Cannot resolve symbol AnAction”红字。3.3 用 artifacts 配置打出插件 jar配置好 SDK 后先试着编译一遍Build → Build Project。如果编译通过说明源码本身没问题。接下来是把这个工程打成可安装的插件 jar也就是官方说的“Artifact”。IDEA 的 Build → Build Artifacts 会读取artifacts/ideaPluginProject_jar.xml里定义的打包规则。一个典型的配置内容是这样的component nameArtifactManager artifact typejar nameideaPluginProject_jar output-path$PROJECT_DIR$/out/artifacts/ideaPluginProject_jar/output-path root idarchive nameideaPluginProject.jar element idmodule-output nameideaPluginProject / element iddir-copy path$PROJECT_DIR$/resources / /root /artifact /componentelement idmodule-output把编译后的 .class 文件打进去element iddir-copy把整个 resources 目录原样复制进 jar。这一步极其关键如果打包时漏掉 resources 目录jar 里就没有 META-INF/plugin.xmlIDEA 会直接判定这个 jar 不是合法插件。你可以在打包完成后用压缩工具打开 jar确认里面有META-INF/plugin.xml、com/rcc/xxxx.class这些条目缺一个都装不上。3.4 安装到 IDEA 并验证右键菜单打包完成后在运行中的 IDEA 里打开 Settings → Plugins → 设置齿轮 → Install Plugin from Disk选择out/artifacts/ideaPluginProject_jar/ideaPluginProject.jar重启 IDE。重启后在任意编辑器窗口里点击右键如果看到顶部出现“Rcc Demo Dialog”菜单项说明注册成功点它就会弹出一个对话框里面显示 Hello from EditorPopupMenu。还有一种更贴近开发的运行方式配置一个 Application 类型的运行配置VM options 填入-Didea.is.internaltrue以开发者模式启动沙箱实例。这样调试插件时不用反复打包安装改动代码直接 Debug 就能拉起一个带插件的 IDEA 实例日志和断点都直接打在调试窗口里。我在后面第 5 部分会展开讲这个调试习惯。4. 避坑我在这份 demo 上踩过的五个高频问题4.1 插件装上了右键菜单却怎么都不出现现象jar 成功装进 IDEA插件列表里能看到名字但编辑器里点击右键没有任何新增菜单项。原因plugin.xml里action的class属性写的全限定名和源码包路径不一致。IDEA 启动加载插件时反射创建 Action 实例失败会静默跳过这条注册记录界面上不报错只是菜单不存在。另一个常见原因是add-to-group的group-id写错比如把EditorPopupMenu拼错成EditorPopup。解决先在 IDEA 的 Help → Show Log in Explorer 打开日志目录搜 “Cannot find action” 或 “ClassNotFoundException” 关键字日志里会精确指出哪个类加载失败。核对源码里的package com.rcc.demo;和 plugin.xml 里的classcom.rcc.demo.ShowDialogAction是否完全一致然后 Rebuild 再重新打包。我个人的习惯是任何一次 Action 注册改动都直接看日志而不去看界面日志比肉眼排查可靠得多。4.2 打包后的 jar 里找不到 META-INF/plugin.xml现象用压缩工具打开打好的 jar里面只有 class 文件没有 META-INF 目录安装时 IDEA 直接提示“Plugin file is invalid”。原因Artifact 配置里只放了module-output没有放dir-copyresources 目录整体没有被复制进 jar。这个 demo 自带的 artifacts 配置一般没问题但如果你自己在 IDEA 里新建 Artifact很多人会漏掉 resource 目录这一步。解决打开 Project Structure → Artifacts双击对应的 artifact 配置在左侧 Available Elements 里找到resources目录右键选择 Put into Archive。打包后再次检查 jar 内容确认META-INF/plugin.xml和图标文件都在。4.3 弹窗标题和按钮显示乱码现象代码里写的Rcc Demo Dialog在编辑器里正常但弹窗里标题或内容变成乱码。原因工程的编码设置不一致。IDEA 默认文件编码是 UTF-8但如果你在 Windows 上用 javac 手动编译过源码或者工程的.iml里指定了GBK编码class 文件里的字符串就会以非 UTF-8 方式编码运行时显示错乱。解决在 Settings → File Encodings 里把 Global Encoding、Project Encoding、Properties Files 全部设为 UTF-8并在编译器设置里加上-encoding UTF-8参数。IDE 里 Build → Build Artifacts 前先执行一次 File → Invalidate Caches / Restart避免 IDE 缓存了旧的编码元数据。4.4 运行 IDEA 版本和插件 build 版本不匹配现象插件在 A 版本 IDEA 上开发正常换到 B 版本后一启动就弹出 “Plugin com.rcc.demo is incompatible with current version”。原因plugin.xml 里没有声明idea-version since-buildxxx until-buildxxx/或者声明的 build 号区间和运行环境对不上。IDEA 的 platform API 在不同大版本之间多少有变动插件在不同 build 号间兼容性由这两个属性决定。解决在 plugin.xml 里加一行idea-version since-build211.0 until-build231.*/“211”和“231”分别替换成你实际使用的两个 IDEA 大版本号。如果只在非常有限的范围内用可以只写since-build和你当前版本的对应值。注意这个值对应的是 build 号比如 IDEA 2021.2 的 build 号是 211.x不是版本号里的“2021.2”。4.5 改完代码重新打包插件行为还是老样子现象源码里改动了弹窗内容重新 Build Artifacts 再安装发现插件行为完全没有变化像是把旧 jar 又装了一遍。原因最常见的是 jar 输出路径没刷新IDEA 的 Build Artifacts 默认是增量编译有时不会重新复制 resources 里的文件另一个可能是同名的旧 jar 还在磁盘上安装时 IDEA 加载的是缓存里的旧版本。解决Build → Rebuild Project 强制全量编译然后在out/artifacts/ideaPluginProject_jar目录看一眼 jar 的文件修改时间确认是新生成的。安装前先在 Settings → Plugins 里卸载旧版插件并删除本地缓存再装新 jar。如果你用的是沙箱运行方式还要把~/.IntelliJIdea/系统版本号/system/plugins下对应的旧版本目录删掉。这招治好了我不少次“明明改了却没反应”的玄学问题其实全是缓存。5. 从 demo 走到自己的插件换菜单位置、对话框升级与调试习惯5.1 用 DialogWrapper 替换 JOptionPane 风格弹窗demo 里用Messages.showInfoMessage足够展示流程但实际项目中这个弹窗还是少了点“原生气质”。把弹窗替换成DialogWrapper大致三步继承它、重写createCenterPanel、在 Action 里show()。package com.rcc.demo; import com.intellij.openapi.ui.DialogWrapper; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; public class RccDialog extends DialogWrapper { private final JTextField nameField new JTextField(); public RccDialog() { super(true); // true 表示模态对话框 setTitle(Rcc 数据录入); init(); } Override protected JComponent createCenterPanel() { JPanel panel new JPanel(new BorderLayout()); panel.add(new JLabel(输入项目名), BorderLayout.NORTH); panel.add(nameField, BorderLayout.CENTER); return panel; } public String getInputName() { return nameField.getText(); } }init()必须在构造函数里调用这个方法会触发createCenterPanel()并完成窗口布局。DialogWrapper自带的 OK/Cancel 按钮布局和 IDEA 原生弹窗完全一致不会出现那种 Swing 默认样式一眼假的效果。在actionPerformed里使用时先new RccDialog().show()再getInputName()拿用户输入整个数据交互循环就完整了。5.2 图标文件怎么换才不翻车pluginIcon.svg 和 pluginIcon_dark.svg 是插件在设置页和插件列表里的展示图标尺寸建议 40x40 左右格式是 SVG。IDEA 会按照当前主题自动选择浅色或深色版本。换图时注意一个坑SVG 里不要依赖外部字体或图片引用最好把所有图形都内联成 path否则 IDEA 的 SVG 渲染器可能画不出内容。5.3 调试习惯与收尾整个 demo 玩透之后我自己的调试习惯固定成了这套源码改动后先 Rebuild Project再打开日志目录查一遍有没有新增的 Exception如果改的是 Action 注册严格走“改 plugin.xml → Rebuild → 重新打包 → 卸载旧插件 → 安装新 jar”五步流程缺一步都可能踩到缓存坑。这个流程看似繁琐但能过滤掉大量“看起来没生效”的假问题。希望这份 demo 能帮你把 idea插件开发从“玄学”变成“可复现”后面做右键菜单增强、内部工具弹窗时至少有个能跑的底子在。希望帮到你。本文还有配套的精品资源点击获取