基於TinyPng,本身開發一個IntelliJ插件

Hello Plugin

建立項目

  1. 打開Intellij,選擇file -> new project
  2. 從左側的選項中 選擇Gradle,而後選擇IntelliJ Platform Plugin,而後你能夠根據本身對選擇,選擇java、kotlin等
    image
  3. GroupId - groupId 新項目。若是您計劃在本地部署項目,則能夠省略此字段。
    ArtifactId - artifactId做爲新項目的名稱添加。
    version 新項目。默認狀況下,會自動指定此字段。
    設置完成後點擊下一步
    image
  4. 在嚮導的下一頁上,爲項目配置自動導入,Gradle版本等,使用默認選項便可
    image

Hello My Plugin

  1. 在src/main/java/目錄下建立新的包,這裏包名爲以前輸入的groupId:com.first.plugin
  2. 在IntelliJ中全部的行爲都是繼承自AnAction類,所以咱們這裏新建一個類繼承AnAcction,並在其actionPerformed方法中彈出一個消息彈窗
    image
  3. Action編寫好後,如同Android開發同樣,咱們須要在plugin.xml的actions標籤中像Activity同樣加入剛剛編寫的Action。其中add-to-group表明咱們須要把這個action加入到哪一個位置。
    image
  4. 完成上述步驟以後咱們直接運行,便可打開一個ide進行運行咱們剛剛寫的那個action了。
    image

用Gradle發佈Plugin

  1. 在build/libs目錄下找到編譯好的HelloPlugin.jar
    image
  2. 登錄網站plugins.jetbrains.com/,選擇uploadPlugin,而後上傳咱們的jar包,填寫完信息便可。注意要修改plugin.xml中的description和changeNotes,須要使用英文,不然會審覈不過
  3. 上傳確認之後會在2-3個工做日審覈,審覈完後就能夠在intellij的plugin市場中找到咱們的插件了。

學以至用

下面介紹一下如何基於知名圖片壓縮網站TinyPng開發一款圖片壓縮插件。效果以下:
html

image

添加依賴庫

直接在lib中加入tinyPng提供的api jar包便可,這裏爲了便於開發,依賴了rxjava2java

建立Action事件

像HelloAciton同樣,建立CompressAction繼承AnAction便可,而後咱們定義一下事件的位置:鼠標右鍵和頂部Tools工具欄內。
在plugin.xml加入以下配置:android

<actions>
    <action id="com.noober.plugin.tiny" class="com.noober.plugin.tiny.CompressAction" text="TinyCompress"
            description="a plugin to compress images">
        <add-to-group group-id="ProjectViewPopupMenu" anchor="after" relative-to-action="ReplaceInPath"/>
        <add-to-group group-id="ToolsMenu" anchor="last"/>
    </action>
</actions>
複製代碼

獲取選中的圖片文件

private VirtualFile[] getSelectFiles(AnActionEvent e) {
    return DataKeys.VIRTUAL_FILE_ARRAY.getData(e.getDataContext());
}


private ArrayList<String> getFileArrayList(VirtualFile file) {
    ArrayList<String> pathList = new ArrayList<>();
    if (!file.isDirectory()) {
        if (file.getPath().endsWith(".jpg") || file.getPath().endsWith(".jpeg") || file.getPath().endsWith(".png")) {
            pathList.add(file.getPath());
        }
    } else {
        for (VirtualFile file1 : file.getChildren()) {
            pathList.addAll(getFileArrayList(file1));
        }
    }
    return pathList;
}
複製代碼

經過getSelectFiles方法獲取選中的文件夾的文件數組,而後進行遍歷,咱們經過getFileArrayList方法取出全部圖片文件便可。git

ArrayList<String> imagePaths = new ArrayList<>();
                        for (VirtualFile file : getSelectFiles(anActionEvent)) {
                            imagePaths.addAll(getFileArrayList(file));
                        }
複製代碼

建立可輸入的彈窗

彈窗ui交互以下:github

  1. 由於TinyPng的使用須要輸入專門的key,所以咱們須要建立一個彈窗用於給開發者提供輸入key。若是用戶沒有key,咱們則提供一個默認的key給用戶使用。
  2. 同時咱們須要在開始上傳壓縮以及壓縮完成以後給用戶提醒,所以這裏可使用一個系統提供的Notifications控件。
  3. 如何壓縮咱們只須要使用TinyPng的Api便可。

繼承DialogWrapper,重寫createCenterPanel、doOKAction方法便可。
其中createCenterPanel用於建立圖形界面,直接調用java swing的api便可,而doOKAction則是點擊ok事件的回調方法。
完整代碼以下:api

public class SampleDialogWrapper extends DialogWrapper {

        String msg;

        public SampleDialogWrapper(String msg) {
            super(true);
            this.msg = msg;
            init();
            getCancelAction().setEnabled(false);
            setTitle("TinyCompress");
        }

        @Nullable
        @Override
        protected JComponent createCenterPanel() {
            //經過java swing的方法建立界面
            JPanel dialogPanel = new JPanel();
            jTextField = new JTextField(hint);
            dialogPanel.add(jTextField);
            return dialogPanel;
        }

        @Override
        protected void doOKAction() {
            super.doOKAction();
            String key;
            if(jTextField.getText().equals(hint)){
                key = "LHZoJXCysEceDReZIsQPWPxdODBxhavW";
            }else {
                key = jTextField.getText();
            }
            Observable.create((ObservableOnSubscribe<Boolean>) observableEmitter -> {
                observableEmitter.onNext(true);
                Tinify.setKey(key);
                //獲取圖片文件
                ArrayList<String> imagePaths = new ArrayList<>();
                for (VirtualFile file : getSelectFiles(anActionEvent)) {
                    imagePaths.addAll(getFileArrayList(file));
                }
                boolean result = true;
                for (String path : imagePaths) {
                    Source source;
                    try {
                            //進行圖片壓縮
                            source = Tinify.fromFile(path);
                            source.toFile(path);
                    } catch (Exception e1) {
                        e1.printStackTrace();
                        //若是是帳戶問題,好比key無效、使用次數達到限制,則再也不調用api接口
                        if(e1 instanceof AccountException){
                            result = false;
                            observableEmitter.onError(e1);
                            break;
                        }else {
                            observableEmitter.onError(e1);
                        }

                    }
                }
                if(result){
                    observableEmitter.onComplete();
                }
            }).subscribe(result -> {
                if(result){
                    //彈出開始壓縮的通知
                    Notifications.Bus.notify(new Notification(groupId, "TinyCompress", "start compress", NotificationType.INFORMATION, null));
                }
            }, error -> {
                //出錯時彈出錯誤的通知
                Notifications.Bus.notify(new Notification(groupId, "TinyCompress", error.getMessage(), NotificationType.WARNING, null));

            }, () -> {
                //彈出壓縮完成的通知
                Notifications.Bus.notify(new Notification(groupId, "TinyCompress", "compress complete", NotificationType.INFORMATION, null));
            });
        }
    }
複製代碼

dialog寫完以後,咱們只須要重寫AnAction的actionPerformed方法,將dialog展現便可。數組

@Override
public void actionPerformed(AnActionEvent e) {
    anActionEvent = e;
    SampleDialogWrapper startDialog = new SampleDialogWrapper("start compress");
    startDialog.show();
}
複製代碼

收尾

代碼已經完成,接下來咱們只須要修改plugin.xml中的版本號、id、介紹以及更新說明便可。app

結語

TinyCompress這個插件已經能夠在android studio的plugin市場中搜到,歡迎你們使用。項目地址以下:github.com/JavaNoober/…
關於plugin更多的api,能夠參考官方文檔IntelliJ Platform SDKide

相關文章
相關標籤/搜索