IDEA插件开发环境搭建和入门示例,可以看之前的文章 《IDEA插件开发入门指南》
这里来说一下开发插件的一些相关知识
gradle task 运行 打包
1、打开gradle面板
gradle面板
2、runIde,启动沙盒idea,运行插件
3、buildPlugin,打包构建插件,打包好后,插件在项目的build > distributions文件里面
插件的访问入口
Action
MyFirstAction示例
1、创建Action
Action作为插件的常用入口,创建方式很简单
创建Action
也可以自己编写一个Action类,继承AnAction,重写actionPerformed方法,在actionPerformed方法里编写插件的业务代码
2、注册Action
通过idea创建action时,会弹出创建框,来填写action的信息,填写完点确定,idea会自动将创建好的action注册到resources/META-INF/plugin.xml里,它会在在actions节点下,添加一个action的配置节点,当然,也可以自己去plugin.xml里面去增加,action配置示例如下:
<actions>
<action id="com.abc.action.MyFirstAction"
class="com.abc.action.MyFirstAction"
text="MyFirstAction"
description="一个示例">
<add-to-group group-id="ToolsMenu" anchor="first"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl F" second-keystroke="ctrl A"/>
</action>
</actions>
配置说明:
属性 | 说明 |
id | action的唯一标识符,推荐使用action的全路径,必填 |
class | action的实现类路径,必填 |
text | action在idea中显示的名字,必填 |
description | action的描述 |
group-id | action加在哪个菜单组里,示例是加在Tools菜单组里 |
anchor | action在菜单组的位置,示例是加在tools菜单里的第一个 |
first-keystroke | 快捷键1 |
second-keystroke | 快捷键2 |
Tool Window
就是在idea的左边,右边,下边显示的工具窗口(插件窗口)
借用官网的一段说明:Tool windows provide access to development tasks: viewing your project structure, running and debugging your application, integration with version control systems and other external tools, code analysis, search, navigation, and so on. By default, tool windows are attached to the bottom and sides of the main window. However, you can rearrange and even detach them to use as separate windows, for example, on another monitor.
- Project tool window
- Structure tool window
- Run tool window
- Maven tool window
Tool Window
1、创建tool window
通过实现ToolWindowFactory创建tool window,然后将我们定义好的组件,添加进去,例如按钮,下拉框等
说明:idea插件UI组件使用Java swing开发的,需要了解一些swing组件的用法
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class MyFirstToolWindow implements ToolWindowFactory {
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();//获取内容面板工厂
Content content = contentFactory.createContent(pluginUI(), "", false);//添加自定义的面板
toolWindow.getContentManager().addContent(content);//添加到tool window管理器中
}
private JPanel pluginUI() {
JPanel panel = new JPanel();
JLabel label = new JLabel("hello");
panel.add(label);
return panel;
}
}
2、注册tool window
同样的是在plugin.xml中配置
<extensions defaultExtensionNs="com.intellij">
<toolWindow factoryClass="com.abc.toolwin.MyFirstToolWindow" id="plugin tool window"/>
</extensions>
tool window显示效果
插件数据存储
1、创建State
插件开发中,会涉及到有些数据需要存储起来,通过实现PersistentStateComponent接口来实现,数据会以xml的格式存放在项目的idea文件夹下,插件加载时会获取数据并设值,代码示例
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@State(name = "my-data", storages = {@Storage(value = "my-data.xml")})
public class MyData implements PersistentStateComponent<MyData> {
private String name;
//获取数据
@Override
public @Nullable MyData getState() {
return this;
}
//加载数据
@Override
public void loadState(@NotNull MyData state) {
this.name = state.getName();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、配置State
同样的是在plugin.xml中配置
<extensions defaultExtensionNs="com.intellij">
<toolWindow factoryClass="com.abc.toolwin.MyFirstToolWindow" id="plugin tool window"/>
<!--projectService时项目级,applicationService应用级-->
<projectService serviceImplementation="com.abc.data.MyData"/>
</extensions>
3、使用State的数据
import com.abc.data.MyData;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
public class MyFirstToolWindow implements ToolWindowFactory {
public static Project project;
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
MyFirstToolWindow.project = project;
ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();//获取内容面板工厂
Content content = contentFactory.createContent(pluginUI(), "", false);//添加自定义的面板
toolWindow.getContentManager().addContent(content);//添加到tool window管理器中
}
private JPanel pluginUI() {
saveData();
MyData data = getData();
JPanel panel = new JPanel();
JLabel label = new JLabel("hello");
panel.add(label);
JTextField field = new JTextField();
field.setText(data.getName());
field.setPreferredSize(new Dimension(300, 30));
panel.add(field);
return panel;
}
//获取数据
private MyData getData() {
return project.getService(MyData.class).getState();
}
//保存数据
public void saveData() {
MyData state = project.getService(MyData.class).getState();
state.setName("张三");
}
}
常用组件
Idea插件是基于Java swing开发,所以swing的组件都可以使用,idea在swing组件的基础上进行了扩展,例如常见的JBLabel -> JLabel,JBTextField ->JTextField。这里写一下idea的一些独有的组件
1、通知组件notify
在 IDEA 右下角通知用户
通知
JButton button = new JButton("通知");
button.addActionListener(e -> {
Notifications.Bus.notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "通知标题", "通知内容", NotificationType.INFORMATION), null);
});
panel.add(button);
通知类型常用的有INFORMATION(信息),WARNING(警告),ERROR(错误)
2、弹出提示框
提示框
是,否,取消弹框
JButton alertError = new JButton("弹出提示");
alertError.addActionListener(e -> {
Messages.showErrorDialog("错误信息", "标题");
});
panel.add(alertError);
JButton alertYesOrNo = new JButton("是否提示框");
alertYesOrNo.addActionListener(e -> {
int retVal = Messages.showYesNoCancelDialog("消息内容", "标题", Messages.getQuestionIcon());
if (Messages.YES == retVal) {
Messages.showErrorDialog("点击了【是】", "标题");
} else if (Messages.NO == retVal) {
Messages.showErrorDialog("点击了【否】", "标题");
} else if (Messages.CANCEL == retVal) {
Messages.showErrorDialog("点击了【取消】", "标题");
}
});
panel.add(alertYesOrNo);
结束
喜欢的朋友,点赞关注收藏吧,这是很大的驱动力
凭谁问,廉颇老矣,尚能饭否?