当前位置: 首页 > 科技观察

一时兴起,自己开发了一个IDEA插件!

时间:2023-03-13 03:44:18 科技观察

前言最近工作比较忙,自己在想一些事情,一时兴起想做一个IDEA插件玩玩,说不定还能卖钱,哈哈。版本工具说明JDK1.8IDEA2020.1插件工程基于gradle构建。知识背景:swing达到什么目的?本例实现一个Idea插件,弹出一个窗体Dialog,然后点击按钮获取窗体中输入的内容,然后在窗体顶部打印内容。成品图展示:项目初始化新建一个gradle项目,修改其build.gradle文件:plugins{id'java'id'org.jetbrains.intellij'version'0.4.14'//引入intellij的gradle插件}group'org.example'version'1.0'//定义jar包/zip包的版本号sourceCompatibility=1.8//限制jdk的版本号,这里限制为8,也就是说生成的idea插件只能运行在jdk8repositories上面的环境中{mavenCentral()//远程仓库}dependencies{//这里引入其他依赖包testCompilegroup:'junit',name:'junit',version:'4.12'}//参见https://github。com/JetBrains/gradle-intellij-plugin/intellij{//这里指的是构建插件包时使用idea的依赖包是什么版本//比如这里使用2019.3进行打包。如果你的插件实现源码使用了2019.3中不存在的依赖包或类,会报错//一般只填当前IDEA版本号version"2019.3"}patchPluginXml{//中的内容显示位置changeNotes参考图14changeNotes"""Version1.0.Version1.0:Initializethistestplug-inproject"""//这个意思是当前定义的插件最早支持什么版本的IDEA//配置sinceBuild=191这里的意思是插件只能被版本号大于等于2019.1的IDEA安装,低于这个版本的会抛出。兼容错误//↑参考上面这个问答:https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003338799-Build-compatible-pluginsinceBuild"191"}和然后Idea右侧栏的gradle中会多出intellij选项:“这里是runIde,用来调试插件的,运行它又会启动一个Idea,就是一个Idea会自动安装你当前定义的插件包,这对你调试新的plugin.xml文件非常重要。它可以指定你定义的插件在IDEA中出现的位置,指定具体的处理逻辑,并且可以定义插件名称、子名称等。这个文件位于MATE-INF下:配置内容是:PluginTestyourcompanyname第一行:简单测试
第二行OK:我说只是测试(● ̄(?) ̄●)
猜猜这是哪个网站?v1.0]]>
然后定义一个Action类,记录作为FormAction,继承AnAction,并实现其抽象方法actionPerformed:publicclassFromActionextendsAnAction{@OverridepublicvoidactionPerformed(@NotNullAnActionEvente){//TODO将插件逻辑放在这里}}Start现在双击runIde调出另一个有此插件的安装好IDEA界面,然后可以看到运行结果来调试runIde也支持调试模式,但是运行的时候需要右键选择:下面看看调试IDEA界面的运行效果:DefineAction1.定义会话框类经过上面三步的配置,插件的基本样式已经显示出来了,但是点击下面“FormTest”的动作是没有用的,因为绑定的FormAction类中并没有有意义的实现。现在要达到最初的目的,点击“表单测试”后,会弹出一个自定义表单对话框,然后在对话框中点击按钮获取表单内容并进行打印。对话框(Dialog)需要定义一个继承IDEA的DialogWrapper抽象类的子类。该子类是自定义对话框实现。所有的样式定义和函数触发器都放在这个子类中,现在调度在下面的子类:默认无参构造方法,所以需要重写构造方法,它提供了很多重载的构造方法,//这里使用的是传递项目类型参数的,当前IDEA中打开的项目的一些属性可以通过Project对象获取,//如项目名称,项目路径等publicFormTestDialog(@NullableProjectproject){super(project);setTitle("Formtest~~");//设置对话框的标题this.//重写下面的方法,返回一个自定义的swing样式,显示在对话框的底部@OverrideprotectedJComponentcreateSouthPanel(){returnnull;}//重写下面的方法,返回一个自定义的swing样式,显示在对话框的底部对话框中心@OverrideprotectedJComponentcreateCenterPanel(){returnnull;}}2.对话框模块&类元素对比找一个实际的对话框作为例子,对于上述方法控制的对话框中的元素如下:3.对话框方法的重新定义根据本文的目标,自定义窗体的主体部分可以放在createCenterPanel中,然后窗体的标题可以放在createNorthPanel中。提交按钮可以放在createSouthPanel中,现在重写如下:publicclassFormTestDialogextendsDialogWrapper{privateStringprojectName;//swing样式类,定义在4.3.2privateFormTestSwingformTestSwing=newFormTestSwing();publicFormTestDialog(@NullableProjectproject){super(true);setTitle("FormTest~~");//设置对话框的标题this.projectName=project.getName();//获取当前项目的名称init();//触发init方法,否则session框中不会显示swing样式}@OverrideprotectedJComponentcreateNorthPanel(){returnformTestSwing.initNorth();//返回位置对话盒北位置的摆动样式}//特别说明:不需要显示SouthPanel,重写返回null,否则IDEA会显示默认的“Cancel”和“确定”按钮@OverrideprotectedJComponentcreateSouthPanel(){returnformTestSwing.initSouth();}@OverrideprotectedJComponentcreateCenterPanel(){//定义窗体的主题,并将其放置在IDEA会话框的中央returnformTestSwing.initCenter();}}4.自定义摆动样式e下面是放置swing样式的类:publicclassFormTestSwing{privateJPanelnorth=newJPanel();privateJPanelcenter=newJPanel();privateJPanelsouth=newJPanel();//为了让底部的按钮能够获取组件内容,这里表单组件做成类属性privateJLabelr1=newJLabel("Output:");privateJLabelr2=newJLabel("NULL");privateJLabelname=newJLabel("Name:");privateJTextFieldnameContent=newJTextField();privateJLabelage=newJLabel("Age:");privateJTextFieldageContent=newJTextField();publicJPanelinitNorth(){//定义窗体的标题部分,放在IDEA会话框的顶部JLabeltitle=newJLabel("表单标题");title.setFont(newFont("微软雅黑",Font.PLAIN,26));//字体样式title.setHorizo??ntalAlignment(SwingConstants.CENTER);//水平居中title.setVerticalAlignment(SwingConstants.CENTER);//垂直居中north.add(title);returnnorth;}publicJPanelinitCenter(){//定义窗体的主要部分,并将其放置在IDEA会话框的中心//一个简单的3行2-columntablelayoutcenter.setLayout(newGridLayout(3,2));//row1:按钮事件触发后,这里打印结果r1.setForeground(newColor(255,47,93));//设置字体颜色center.add(r1);r2。setForeground(newColor(139,181,20));//设置字体颜色center.add(r2);//row2:name+textboxcenter.add(name);center.add(nameContent);//row3:age+文本框center.add(age);center.add(ageContent);returncenter;}publicJPanelinitSouth(){//定义表单的提交按钮,放在底部IDEA会话框的JButtonsubmit=newJButton("submit");提交。setHorizo??ntalAlignment(SwingConstants.CENTER);//水平居中提交。setVerticalAlignment(SwingConstants.CENTER);//垂直居中south.add(submit);returnssouth;}}现在点击runIde按钮。同样,在调试IDE中点击“FormTest”,会弹出如下表单框:“除非有特殊情况需要自定义swing样式,否则建议不要添加任何swing样式,这样自定义的swing界面会随着IDEA的主题变化而适配,比如将图7调试IDE的主题设置为Darcula,自定义窗体也会自适应变成黑色背景:5.事件绑定定义了样式,现在给“提交”按钮绑定一个事件,现在重写FormTestSwing.initSouth方法:publicJPanelinitSouth(){//定义表单的提交按钮,放在IDEA会话框底部JButtonsubmit=newJButton("submit");submit.setHorizo??ntalAlignment(SwingConstants.CENTER);//水平居中submit.setVerticalAlignment(SwingConstants.CENTER);//垂直居中south.add(submit);//按钮事件绑定submit.addActionListener(e->{//获取名字和ageStringname=nameContent.getText();Stringage=ageContent.getText();//刷新r2标签内容,替换为name和ager2.setText(String.format("name:%s,age:%s",name,age));});returnssouth;}现在点击“提交”按钮输出表单内容:6.插件绑定类:FormAction之前说过,这个类是插件的入口,结合上面定义的表单Dialog,我们看看它是如何写的:publicclassFromActionextendsAnAction{@OverridepublicvoidactionPerformed(@NotNullAnActionEvente){FormTestDialogformTestDialog=newFormTestDialog(e.getProject());formTestDialog.setResizable(true);//是否允许用户通过拖拽来展开或者缩小你的表单框,我这里定义为true,也就是说formTestDialog.showisallowed();}}7、到第四步,插件的打包安装只是在调试IDE中查看效果。如果开发了一个插件,需要用实际的IDEA安装,这时候就需要借助packaging选项进行打包。对于你的插件,点击下面选项构建插件:构建完成后,查看构建包下的distributions目录,里面的zip包可以直接安装到你的IDEA中:然后选择Preferences下的plugins选项IDEA,会弹出如下框,按照图中提示选择zip包进行安装:然后安装完成,重启IDEA:各显示模块对应的插件工程中的配置源参考下图:重启后,出现和调试IDEA一样的菜单栏,选择Successfuloperation后:Summary至此,一个插件的开发、调试、安装就完成了。理论上,通过这个简单的例子可以实现一些实用的功能,因为它充分展示了从数据输入到数据获取的整个过程。由于工作需要写一个代码生成器,想以IDEA插件的形式提供服务,所以在这里做一个记录,以防以后再用的时候从头开始。你必须有一定的挥杆基础。我在开发代码生成器的时候,因为swing基础太差,花了很多时间来布局。