基于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

相关文章
相关标签/搜索