🐜 版本信息:html
🐞 JDK:1.8+java
🐌 IDEA:2019.3git
🐝 插件項目基於gradle構建。github
🦟 知識背景:swingwindows
🦇 參考文檔:app
http://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system/prerequisites.htmlmaven
http://www.jetbrains.org/intellij/sdk/docs/user_interface_components/tool_windows.htmlide
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-pluginpost
本實例實現一個Idea的插件,彈出一個表單Dialog,而後點擊按鈕,獲取表單裏輸入的內容,而後將內容打印在表單的上方。
成品圖展現:
圖1
新建一個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插件只能運行在jdk8以上的環境中 repositories { mavenCentral() //遠程倉庫 } dependencies { //這裏引別的依賴包 testCompile group: 'junit', name: 'junit', version: '4.12' } // See https://github.com/JetBrains/gradle-intellij-plugin/ intellij { // 這裏是指打插件包的時候用idea什麼版本的依賴包打 // 好比這裏用2019.3打包,若是你的插件實現源碼裏用了2019.3不存在的依賴包或類,就會報錯 // 通常就填當前IDEA的版本號便可 version "2019.3" } patchPluginXml { //changeNotes裏的內容展現位置參考圖14 changeNotes """ 1.0版本.
第1.0版本:初始化這個測試插件項目""" // 這個意思是說當前定義的這個插件最先支持到什麼版本的IDEA // 這裏配置sinceBuild=191,表示插件只能被版本號大於等於2019.1版本的IDEA安裝,低於這個版本的將拋沒法兼容的錯誤 // ↑上方參考這篇問答:https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003338799-Build-compatible-plugin sinceBuild "191" }
而後Idea的右邊欄gradle將會多出intellij選項:
圖2
這裏說下runIde,它用來調試插件,運行它會再次啓動一個Idea,這個Idea會自動安裝上你當前定義的插件包,讓你用來調試。
這個文件很是重要,它能夠指定你定義的插件出如今IDEA的哪一個位置,能夠指定具體的處理邏輯,還能夠定義插件名稱、子名稱等等。
這個文件位於MATE-INF下:
圖3
配置內容爲:
<idea-plugin> <!--插件的id,注意不要跟其餘插件重複,這個id全局惟一,儘量複雜些--> <id>plugin.test</id> <!--插件的名稱--> <name>PluginTest</name> <vendor email="xxxx@qq.com" url="http://www.bilibili.com">你公司的名字</vendor> <!--插件的描述信息,支持html,展現的位置參考圖14--> <description><![CDATA[ Plugin Test<br> 第一行:單純只是個測試<br> 第二行:都說了只是個測試(● ̄(エ) ̄●)<br> <a href='https://www.bilibili.com'>你猜猜這是哪一個網站?</a> <em>v1.0</em> ]]></description> <extensions defaultExtensionNs="com.intellij"> <!-- Add your extensions here --> </extensions> <!--跟build.gradle裏的sinceBuild一致便可,意義相同,必須配置--> <idea-version since-build="191"/> <actions> <!--下面的group是分組,分組須要有一個惟一的id標識,text用來控制分組出如今IDEA時呈現的文案,description是描述,不會展示出來,簡單描述下分組就行--> <group id="PluginTest" text="插件測試組" description="插件測試描述"> <!--add-to-group控制把該分組加到IDEA裏,group-id用來描述加在哪一個位置,MainMenu表示加在IDEA上方的主菜單欄裏, anchor表示順序,last表示最後一個,因此下面的配置能夠描述爲:將該插件加到IDEA上方主菜單欄的最後一位--> <add-to-group group-id="MainMenu" anchor="last"/> <!--這個用來指定一個分組下的觸發動做,一樣的須要一個id,自定義;class就是用來處理這個動做的邏輯類,具體的插件邏輯都會寫到對應的action類裏,text用來控制文案,description爲描述--> <action id="Plugin.Test.Action" class="plugin.test.FromAction" text="表單測試" description="表單測試描述"/> </group> </actions> </idea-plugin>
而後定義一個Action類,記爲FormAction,繼承AnAction,實現其抽象方法actionPerformed便可:
public class FromAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { //TODO 這裏放插件邏輯 } }
如今雙擊runIde便可調出另一個安裝了這個插件的IDEA界面,而後能夠看運行結果進行調試。 runIde還支持debug模式,不過運行時要右擊選擇:
圖4
來看下調試IDEA的界面運行效果:
圖5
通過上面三步的配置,插件的基本樣式已經展現出來,可是點擊下方「表單測試」的action,並無什麼用,由於其綁定的FormAction類裏沒有任何有意義的實現。如今來實現開始的目標,點擊「表單測試」後,彈出一個自定義的表單會話框,而後點擊按鈕,獲取表單內容後打印在會話框內。
會話框(Dialog)須要定義一個繼承了IDEA的DialogWrapper抽象類的子類,這個子類就是自定義的會話框實現,全部的樣式定義、功能觸發都是放到這個子類裏的,現定於以下子類:
public class FormTestDialog extends DialogWrapper { private String projectName; //假如須要獲取到項目名,做爲該類的屬性放進來 // DialogWrapper沒有默認的無參構造方法,因此須要重寫構造方法,它提供了不少重載構造方法, // 這裏使用傳project類型參數的那個,經過Project對象能夠獲取當前IDEA內打開的項目的一些屬性, // 好比項目名,項目路徑等 public FormTestDialog(@Nullable Project project) { super(project); setTitle("表單測試~~"); // 設置會話框標題 this.projectName = project.getName(); } // 重寫下面的方法,返回一個自定義的swing樣式,該樣式會展現在會話框的最上方的位置 @Override protected JComponent createNorthPanel() { return null; } // 重寫下面的方法,返回一個自定義的swing樣式,該樣式會展現在會話框的最下方的位置 @Override protected JComponent createSouthPanel() { return null; } // 重寫下面的方法,返回一個自定義的swing樣式,該樣式會展現在會話框的中央位置 @Override protected JComponent createCenterPanel() { return null; } }
找個實際的會話框爲例,針對上述中幾個方法所控制的會話框裏的元素以下:
圖6
按照本文的實現目標,自定義的表單主體部分能夠位於createCenterPanel裏,而後表單的大標題能夠放到createNorthPanel裏,提交按鈕能夠放到createSouthPanel裏,如今改寫以下:
public class FormTestDialog extends DialogWrapper { private String projectName; //swing樣式類,定義在4.3.2 private FormTestSwing formTestSwing = new FormTestSwing(); public FormTestDialog(@Nullable Project project) { super(true); setTitle("表單測試~~"); //設置會話框標題 this.projectName = project.getName(); //獲取到當前項目的名稱 init(); //觸發一下init方法,不然swing樣式將沒法展現在會話框 } @Override protected JComponent createNorthPanel() { return formTestSwing.initNorth(); //返回位於會話框north位置的swing樣式 } // 特別說明:不須要展現SouthPanel要重寫返回null,不然IDEA將展現默認的"Cancel"和"OK"按鈕 @Override protected JComponent createSouthPanel() { return formTestSwing.initSouth(); } @Override protected JComponent createCenterPanel() { //定義表單的主題,放置到IDEA會話框的中央位置 return formTestSwing.initCenter(); } }
下面是放置swing樣式的類:
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() { //定義表單的標題部分,放置到IDEA會話框的頂部位置 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() { //定義表單的主體部分,放置到IDEA會話框的中央位置 //一個簡單的3行2列的表格佈局 center.setLayout(new GridLayout(3, 2)); //row1:按鈕事件觸發後將結果打印在這裏 r1.setForeground(new Color(255, 47, 93)); //設置字體顏色 center.add(r1); r2.setForeground(new Color(139, 181, 20)); //設置字體顏色 center.add(r2); //row2:姓名+文本框 center.add(name); center.add(nameContent); //row3:年齡+文本框 center.add(age); center.add(ageContent); return center; } public JPanel initSouth() { //定義表單的提交按鈕,放置到IDEA會話框的底部位置 JButton submit = new JButton("提交"); submit.setHorizontalAlignment(SwingConstants.CENTER); //水平居中 submit.setVerticalAlignment(SwingConstants.CENTER); //垂直居中 south.add(submit); return south; } }
如今點擊下runIde按鈕,一樣的,在調試IDE裏點擊「表單測試」,而後就會彈出以下表單框:
圖7
🌿 除非有特殊狀況須要自定義swing樣式,不然建議不加任何swing樣式,這樣自定義的swing界面是會隨着IDEA的主題改變而去自適應的,好比將圖7中的調試IDE的主題設置成Darcula,自定義的表單也會自適應的變成黑色背景:
圖8
定義好了樣式,如今給「提交」按鈕綁定一個事件,如今改寫下FormTestSwing.initSouth方法:
public JPanel initSouth() { //定義表單的提交按鈕,放置到IDEA會話框的底部位置 JButton submit = new JButton("提交"); submit.setHorizontalAlignment(SwingConstants.CENTER); //水平居中 submit.setVerticalAlignment(SwingConstants.CENTER); //垂直居中 south.add(submit); //按鈕事件綁定 submit.addActionListener(e -> { //獲取到name和age String name = nameContent.getText(); String age = ageContent.getText(); //刷新r2標籤裏的內容,替換爲name和age r2.setText(String.format("name:%s, age:%s", name, age)); }); return south; }
如今再來點擊下「提交」按鈕,就能夠輸出表單內容了:
圖9
截止到第四步,都只是在調試IDE裏查看效果,若是一個插件開發完成後,須要被實際的IDEA安裝,這個時候就須要藉助打包選項來打包你的插件,點擊下面的選項構建插件:
圖10
構建完成後,查看build包下的distributions目錄,裏面的zip包就能夠直接安裝進你的IDEA:
圖11
而後選擇IDEA的Preferences下的plugins選項,彈出以下框,按照圖裏的指示選擇zip包安裝便可:
圖12
而後安裝完成,重啓IDEA便可:
圖13
各個展現模塊對應插件項目裏配置的來源參考下圖:
圖14
重啓後出現了跟調試IDEA裏同樣的菜單欄,選中後運行成功:
圖15
截止到這裏,一個插件的開發、調試、安裝就完成了,理論上經過這個簡單的例子就能夠實現一些實際的功能了,由於其完整展現了數據輸入到數據獲取整個過程。
由於工做當中須要寫一個代碼生成器,想要以一個IDEA插件的方式提供服務,因此在這裏作個記錄,防止之後再次用到時從零開始。。
要有必定的swing基礎,我在開發代碼生成器的時候,就是由於swing基礎太差,佈局花了很是多的時間。
🍒 以後不會深刻去研究插件的開發,若是後續工做中有用到插件開發的其餘的功能點,會更新在這個系列裏,若是想深刻搞IDEA插件開發,建議看IDEA的官方文檔,官方文檔有點亂,有不少只是簡單介紹幾句甚至沒有示例,好在他們有個問答社區,建議搜索時用google搜英文關鍵詞(google對英文搜索支持強大,沒試過分娘,應該也能夠搜到),裏面會有人提問,好比版本兼容的問題就是google出來的,社區里正好有一篇問答。(連接放到開頭裏了)