🐜 版本信息:jdk1.8+
IntelliJ IDEA 2019.03
🐝 插件项目基于gradle
构建。
🦟 知识背景:swing
目标
本实例实现一个Idea
的插件,弹出一个表单Dialog
,然后点击按钮,获取表单里输入的内容,然后将内容打印在表单的上方。
成品图展示:
一、项目初始化
新建一个gradle
项目,修改其build.gradle
文件:
代码块11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| plugins { id 'java' id 'org.jetbrains.intellij' version '0.4.14' } group 'org.example' version '1.0' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' }
intellij { version "2019.3" } patchPluginXml { changeNotes """ 1.0版本.
第1.0版本:初始化这个测试插件项目""" sinceBuild "191" }
|
然后Idea的右边栏gradle将会多出intellij选项:
这里说下runIde
,它用来调试插件,运行它会再次启动一个Idea,这个Idea会自动安装上你当前定义的插件包,让你用来调试。
二、新增plugin.xml
这个文件非常重要,它可以指定你定义的插件出现在IDEA的哪个位置,可以指定具体的处理逻辑,还可以定义插件名称、子名称等等。
这个文件位于MATE-INF
下:
配置内容为:
代码块21 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <idea-plugin> <id>plugin.test</id> <name>PluginTest</name> <vendor email="xxxx@qq.com" url="http://www.bilibili.com">你公司的名字</vendor>
<description><![CDATA[ Plugin Test<br> 第一行:单纯只是个测试<br> 第二行:都说了只是个测试(● ̄(エ) ̄●)<br> <a href='https://www.bilibili.com'>你猜猜这是哪个网站?</a> <em>v1.0</em> ]]></description> <extensions defaultExtensionNs="com.intellij"> </extensions>
<idea-version since-build="191"/>
<actions> <group id="PluginTest" text="插件测试组" description="插件测试描述">
<add-to-group group-id="MainMenu" anchor="last"/> <action id="Plugin.Test.Action" class="plugin.test.FromAction" text="表单测试" description="表单测试描述"/> </group> </actions> </idea-plugin>
|
然后定义一个Action类,记为FormAction,继承AnAction,实现其抽象方法actionPerformed即可:
代码块31 2 3 4 5 6
| public class FromAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { } }
|
三、启动
现在双击runIde
即可调出另外一个安装了这个插件的IDEA界面,然后可以看运行结果进行调试。 runIde还支持debug模式
,不过运行时要右击
选择:
来看下调试IDEA的界面运行效果:
四、定义Action
4.1:定义会话框类
经过上面三步的配置,插件的基本样式已经展示出来,但是点击下方“表单测试”的action,并没有什么用,因为其绑定的FormAction类里没有任何有意义的实现。现在来实现开始的目标,点击“表单测试”后,弹出一个自定义的表单会话框,然后点击按钮,获取表单内容后打印在会话框内。
会话框(Dialog
)需要定义一个继承了IDEA的DialogWrapper
抽象类的子类,这个子类就是自定义的会话框实现,所有的样式定义、功能触发都是放到这个子类里的,现定于如下子类:
代码块41 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class FormTestDialog extends DialogWrapper { private String projectName; public FormTestDialog(@Nullable Project project) { super(project); setTitle("表单测试~~"); this.projectName = project.getName(); } @Override protected JComponent createNorthPanel() { return null; } @Override protected JComponent createSouthPanel() { return null; } @Override protected JComponent createCenterPanel() { return null; } }
|
4.2:会话框模块&类元素对照
找个实际的会话框为例,针对上述中几个方法所控制的会话框里的元素如下:
4.3:自定义会话框元素
4.3.1:会话框方法重定义
按照本文的实现目标,自定义的表单主体部分可以位于createCenterPanel
里,然后表单的大标题可以放到createNorthPanel
里,提交按钮可以放到createSouthPanel
里,现在改写如下:
代码块51 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class FormTestDialog extends DialogWrapper { private String projectName; private FormTestSwing formTestSwing = new FormTestSwing(); public FormTestDialog(@Nullable Project project) { super(true); setTitle("表单测试~~"); this.projectName = project.getName(); init(); } @Override protected JComponent createNorthPanel() { return formTestSwing.initNorth(); } @Override protected JComponent createSouthPanel() { return formTestSwing.initSouth(); } @Override protected JComponent createCenterPanel() { return formTestSwing.initCenter(); } }
|
4.3.2:自定义swing样式
下面是放置swing样式的类:
代码块61 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| public class FormTestSwing { private JPanel north = new JPanel(); private JPanel center = new JPanel(); private JPanel south = new JPanel(); private JLabel r1 = new JLabel("输出:"); private JLabel r2 = new JLabel("NULL"); private JLabel name = new JLabel("姓名:"); private JTextField nameContent = new JTextField(); private JLabel age = new JLabel("年龄:"); private JTextField ageContent = new JTextField(); public JPanel initNorth() { JLabel title = new JLabel("表单标题"); title.setFont(new Font("微软雅黑", Font.PLAIN, 26)); title.setHorizontalAlignment(SwingConstants.CENTER); title.setVerticalAlignment(SwingConstants.CENTER); north.add(title); return north; } public JPanel initCenter() { center.setLayout(new GridLayout(3, 2)); r1.setForeground(new Color(255, 47, 93)); center.add(r1); r2.setForeground(new Color(139, 181, 20)); center.add(r2); center.add(name); center.add(nameContent); center.add(age); center.add(ageContent); return center; } public JPanel initSouth() { JButton submit = new JButton("提交"); submit.setHorizontalAlignment(SwingConstants.CENTER); submit.setVerticalAlignment(SwingConstants.CENTER); south.add(submit); return south; } }
|
现在点击下runIde
按钮,同样的,在调试IDE里点击“表单测试”,然后就会弹出如下表单框:
🌿 除非有特殊情况需要自定义swing样式,否则建议不加任何swing样式,这样自定义的swing界面是会随着IDEA的主题改变而去自适应的,比如将图7中的调试IDE的主题设置成Darcula,自定义的表单也会自适应的变成黑色背景:
4.3.3:事件绑定
定义好了样式,现在给“提交”按钮绑定一个事件,现在改写下FormTestSwing.initSouth
方法:
代码块71 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public JPanel initSouth() { JButton submit = new JButton("提交"); submit.setHorizontalAlignment(SwingConstants.CENTER); submit.setVerticalAlignment(SwingConstants.CENTER); south.add(submit); submit.addActionListener(e -> { String name = nameContent.getText(); String age = ageContent.getText(); r2.setText(String.format("name:%s, age:%s", name, age)); }); return south; }
|
现在再来点击下“提交”按钮,就可以输出表单内容了:
之前讲过,这个类是插件的入口,结合上面定义好的表单Dialog,来看下它是怎么写的:
代码块81 2 3 4 5 6 7 8
| public class FromAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { FormTestDialog formTestDialog = new FormTestDialog(e.getProject()); formTestDialog.setResizable(true); formTestDialog.show(); } }
|
五、插件的打包&安装
截止到第四步,都只是在调试IDE里查看效果,如果一个插件开发完成后,需要被实际的IDEA安装,这个时候就需要借助打包选项来打包你的插件,点击下面的选项构建插件:
构建完成后,查看build包
下的distributions目录
,里面的zip包
就可以直接安装进你的IDEA:
然后选择IDEA的Preferences
下的plugins
选项,弹出如下框,按照图里的指示选择zip包
安装即可:
然后安装完成,重启IDEA即可:
各个展示模块对应插件项目里配置的来源参考下图:
重启后出现了跟调试IDEA里一样的菜单栏,选中后运行成功:
写在最后
截止到这里,一个插件的开发
、调试
、安装
就完成了,理论上通过这个简单的例子就可以实现一些实际的功能了,因为其完整展示了数据输入
到数据获取
整个过程。
因为工作当中需要写一个代码生成器,想要以一个IDEA插件的方式提供服务,所以在这里做个记录,防止以后再次用到时从零开始。。
要有一定的swing
基础,我在开发代码生成器的时候,就是因为swing基础太差,布局花了非常多的时间。
之后不会深入去研究插件的开发,如果后续工作中有用到插件开发的其他的功能点,会更新在这个分类里,如果想深入搞IDEA插件开发,建议看IDEA的官方文档,官方文档有点乱,有很多只是简单介绍几句甚至没有示例,好在他们有个问答社区,建议搜索时用google搜英文关键词,里面会有人提问,比如版本兼容的问题就是google出来的,社区里正好有一篇问答,相关链接在下面的参考文档里。
📒 参考文档:
http://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system/prerequisites.html
http://www.jetbrains.org/intellij/sdk/docs/user_interface_components/tool_windows.html
http://www.jetbrains.org/intellij/sdk/docs/user_interface_components/dialog_wrapper.html
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003338799-Build-compatible-plugin