1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        一時興起,自己動手開發(fā)了個IDEA插件!

        共 15388字,需瀏覽 31分鐘

         ·

        2021-09-13 22:26

        今天無聊帶你們撩一下IDEA插件

        前言

        最近工作比較閑,自己琢磨點東西,一時興起想自己做個IDEA插件玩玩,說不定還能賣錢,哈哈。

        版本工具說明

        • JDK1.8
        • IDEA2020.1
        • 插件項目基于gradle構(gòu)建。
        • 知識背景:swing

        達到什么目標?

        本實例實現(xiàn)一個Idea的插件,彈出一個表單Dialog,然后點擊按鈕,獲取表單里輸入的內(nèi)容,然后將內(nèi)容打印在表單的上方。

        成品圖展示:

        項目初始化

        新建一個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以上的環(huán)境中
         
        repositories {
            mavenCentral() //遠程倉庫
        }
         
        dependencies {
            //這里引別的依賴包
            testCompile group: 'junit', name: 'junit', version: '4.12'
        }
         
        // See https://github.com/JetBrains/gradle-intellij-plugin/
        intellij {
            // 這里是指打插件包的時候用idea什么版本的依賴包打
            // 比如這里用2019.3打包,如果你的插件實現(xiàn)源碼里用了2019.3不存在的依賴包或類,就會報錯
            // 一般就填當前IDEA的版本號即可
            version "2019.3"
        }
         
        patchPluginXml {
         
            //changeNotes里的內(nèi)容展示位置參考圖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選項:

        這里說下runIde,它用來調(diào)試插件,運行它會再次啟動一個Idea,這個Idea會自動安裝上你當前定義的插件包,讓你用來調(diào)試。

        新增plugin.xml

        這個文件非常重要,它可以指定你定義的插件出現(xiàn)在IDEA的哪個位置,可以指定具體的處理邏輯,還可以定義插件名稱、子名稱等等。

        這個文件位于MATE-INF下:

        配置內(nèi)容為:

        <idea-plugin>
            <!--插件的id,注意不要跟其他插件重復(fù),這個id全局唯一,盡可能復(fù)雜些-->
            <id>plugin.test</id>
            <!--插件的名稱-->
            <name>PluginTest</name>
            <vendor email="[email protected]" url="http://www.bilibili.com">你公司的名字</vendor>

            <!--插件的描述信息,支持html,展示的位置參考圖14-->
            <description><![CDATA[
            Plugin Test<br>
            第一行:單純只是個測試<br>
            第二行:都說了只是個測試(● ̄(?) ̄●)<br>
            <a >你猜猜這是哪個網(wǎng)站?</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用來控制分組出現(xiàn)在IDEA時呈現(xiàn)的文案,description是描述,不會展現(xiàn)出來,簡單描述下分組就行-->
                <group id="PluginTest" text="插件測試組" description="插件測試描述">
                    <!--add-to-group控制把該分組加到IDEA里,group-id用來描述加在哪個位置,MainMenu表示加在IDEA上方的主菜單欄里,
                    anchor表示順序,last表示最后一個,所以下面的配置可以描述為:將該插件加到IDEA上方主菜單欄的最后一位-->

                    <add-to-group group-id="MainMenu" anchor="last"/>
                    <!--這個用來指定一個分組下的觸發(fā)動作,同樣的需要一個id,自定義;class就是用來處理這個動作的邏輯類,具體的插件邏輯都會寫到對應(yīng)的action類里,text用來控制文案,description為描述-->
                    <action id="Plugin.Test.Action"
                            class="plugin.test.FromAction"
                            text="表單測試" description="表單測試描述"/>

                </group>
            </actions>
        </idea-plugin>

        然后定義一個Action類,記為FormAction,繼承AnAction,實現(xiàn)其抽象方法actionPerformed即可:

        public class FromAction extends AnAction {
            @Override
            public void actionPerformed(@NotNull AnActionEvent e) {
                //TODO 這里放插件邏輯
            }
        }

        啟動

        現(xiàn)在雙擊runIde即可調(diào)出另外一個安裝了這個插件的IDEA界面,然后可以看運行結(jié)果進行調(diào)試。runIde還支持debug模式,不過運行時要右擊選擇:

        來看下調(diào)試IDEA的界面運行效果:

        定義Action

        1. 定義會話框類

        經(jīng)過上面三步的配置,插件的基本樣式已經(jīng)展示出來,但是點擊下方“表單測試”的action,并沒有什么用,因為其綁定的FormAction類里沒有任何有意義的實現(xiàn)?,F(xiàn)在來實現(xiàn)開始的目標,點擊“表單測試”后,彈出一個自定義的表單會話框,然后點擊按鈕,獲取表單內(nèi)容后打印在會話框內(nèi)。

        會話框(Dialog)需要定義一個繼承了IDEA的DialogWrapper抽象類的子類,這個子類就是自定義的會話框?qū)崿F(xiàn),所有的樣式定義、功能觸發(fā)都是放到這個子類里的,現(xiàn)定于如下子類:

        public class FormTestDialog extends DialogWrapper {
         
            private String projectName; //假如需要獲取到項目名,作為該類的屬性放進來
         
            // DialogWrapper沒有默認的無參構(gòu)造方法,所以需要重寫構(gòu)造方法,它提供了很多重載構(gòu)造方法,
            // 這里使用傳project類型參數(shù)的那個,通過Project對象可以獲取當前IDEA內(nèi)打開的項目的一些屬性,
            // 比如項目名,項目路徑等
            public FormTestDialog(@Nullable Project project) {
                super(project);
                setTitle("表單測試~~"); // 設(shè)置會話框標題
                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;
            }
        }

        2. 會話框模塊&類元素對照

        找個實際的會話框為例,針對上述中幾個方法所控制的會話框里的元素如下:

        3. 會話框方法重定義

        按照本文的實現(xiàn)目標,自定義的表單主體部分可以位于createCenterPanel里,然后表單的大標題可以放到createNorthPanel里,提交按鈕可以放到createSouthPanel里,現(xiàn)在改寫如下:

        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("表單測試~~"); //設(shè)置會話框標題
                this.projectName = project.getName(); //獲取到當前項目的名稱
                init(); //觸發(fā)一下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();
            }
        }

        4. 自定義swing樣式

        下面是放置swing樣式的類:

        public class FormTestSwing {
         
            private JPanel north = new JPanel();
         
            private JPanel center = new JPanel();
         
            private JPanel south = new JPanel();
         
            //為了讓位于底部的按鈕可以拿到組件內(nèi)容,這里把表單組件做成類屬性
            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(32));
         
                //row1:按鈕事件觸發(fā)后將結(jié)果打印在這里
                r1.setForeground(new Color(2554793)); //設(shè)置字體顏色
                center.add(r1);
                r2.setForeground(new Color(13918120)); //設(shè)置字體顏色
                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;
            }
        }

        現(xiàn)在點擊下runIde按鈕,同樣的,在調(diào)試IDE里點擊“表單測試”,然后就會彈出如下表單框:

        除非有特殊情況需要自定義swing樣式,否則建議不加任何swing樣式,這樣自定義的swing界面是會隨著IDEA的主題改變而去自適應(yīng)的,比如將圖7中的調(diào)試IDE的主題設(shè)置成Darcula,自定義的表單也會自適應(yīng)的變成黑色背景:

        5. 事件綁定

        定義好了樣式,現(xiàn)在給“提交”按鈕綁定一個事件,現(xiàn)在改寫下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標簽里的內(nèi)容,替換為name和age
                r2.setText(String.format("name:%s, age:%s", name, age));
            });
         
            return south;
        }

        現(xiàn)在再來點擊下“提交”按鈕,就可以輸出表單內(nèi)容了:

        6. 插件綁定類:FormAction

        之前講過,這個類是插件的入口,結(jié)合上面定義好的表單Dialog,來看下它是怎么寫的:

        public class FromAction extends AnAction {
            @Override
            public void actionPerformed(@NotNull AnActionEvent e) {
                FormTestDialog formTestDialog = new FormTestDialog(e.getProject());
                formTestDialog.setResizable(true); //是否允許用戶通過拖拽的方式擴大或縮小你的表單框,我這里定義為true,表示允許
                formTestDialog.show();
            }
        }

        7. 插件的打包&安裝

        截止到第四步,都只是在調(diào)試IDE里查看效果,如果一個插件開發(fā)完成后,需要被實際的IDEA安裝,這個時候就需要借助打包選項來打包你的插件,點擊下面的選項構(gòu)建插件:

        構(gòu)建完成后,查看build包下的distributions目錄,里面的zip包就可以直接安裝進你的IDEA:

        然后選擇IDEA的Preferences下的plugins選項,彈出如下框,按照圖里的指示選擇zip包安裝即可:

        然后安裝完成,重啟IDEA即可:

        各個展示模塊對應(yīng)插件項目里配置的來源參考下圖:

        重啟后出現(xiàn)了跟調(diào)試IDEA里一樣的菜單欄,選中后運行成功:

        總結(jié)

        截止到這里,一個插件的開發(fā)、調(diào)試、安裝就完成了,理論上通過這個簡單的例子就可以實現(xiàn)一些實際的功能了,因為其完整展示了數(shù)據(jù)輸入到數(shù)據(jù)獲取整個過程。

        因為工作當中需要寫一個代碼生成器,想要以一個IDEA插件的方式提供服務(wù),所以在這里做個記錄,防止以后再次用到時從零開始。。

        要有一定的swing基礎(chǔ),我在開發(fā)代碼生成器的時候,就是因為swing基礎(chǔ)太差,布局花了非常多的時間。

        更多細節(jié)請看IDEA官方文檔:https://plugins.jetbrains.com/docs/intellij/welcome.html?from=jetbrains.org

        參考文檔

        • 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

        • — 【 THE END 】—
          本公眾號全部博文已整理成一個目錄,請在公眾號里回復(fù)「m」獲取!

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點“在看”,關(guān)注公眾號并回復(fù) PDF 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。

          謝謝支持喲 (*^__^*)

        瀏覽 52
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品片18区乱婬人成人 | 精品无码国产成人网站尤物app | 疯狂 自慰爽www看片 | 97AV电影| 免费看片十八禁 | 一级片手机在线观看 | 毛茸茸亚洲孕妇孕交片 | 性欧美老妇人精品HD | 精品人妻一区二区免费蜜桃视频 | 添女人的阴逼 |