下面介绍一下如何基于知名图片压缩网站TinyPng开发一款图片压缩插件。效果如下:
直接在lib中加入tinyPng提供的api jar包即可,这里为了便于开发,依赖了rxjava2
像HelloAciton一样,创建CompressAction继承AnAction即可,然后我们定义一下事件的位置:鼠标右键和顶部Tools工具栏内。
在plugin.xml加入如下配置:
<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方法取出所有图片文件即可。
ArrayList<String> imagePaths = new ArrayList<>(); for (VirtualFile file : getSelectFiles(anActionEvent)) { imagePaths.addAll(getFileArrayList(file)); } 复制代码
弹窗ui交互如下:
继承DialogWrapper,重写createCenterPanel、doOKAction方法即可。
其中createCenterPanel用于创建图形界面,直接调用java swing的api即可,而doOKAction则是点击ok事件的回调方法。
完整代码如下:
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、介绍以及更新说明即可。
TinyCompress这个插件已经可以在android studio的plugin市场中搜到,欢迎大家使用。项目地址如下: github.com/JavaNoober/… 。
关于plugin更多的api,可以参考官方文档 IntelliJ Platform SDK 。