如何开发带窗口、控件及设置面板的IntelliJ插件?
IntelliJ插件:自定义窗口、控件与设置面板实现示例
一、创建带控件的自定义工具窗口
先实现ToolWindowFactory接口来构建工具窗口,集成文本框、按钮等控件并绑定事件:
import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowFactory; import com.intellij.ui.components.JBTextField; import com.intellij.ui.components.JBButton; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import javax.swing.*; import java.awt.*; public class MyToolWindowFactory implements ToolWindowFactory { @Override public void createToolWindowContent(Project project, ToolWindow toolWindow) { // 主面板布局 JPanel mainPanel = new JPanel(new BorderLayout()); // 添加文本输入框 JBTextField inputField = new JBTextField("请输入内容..."); mainPanel.add(inputField, BorderLayout.NORTH); // 按钮面板 JPanel buttonPanel = new JPanel(new FlowLayout()); JBButton settingsBtn = new JBButton("打开设置"); JBButton submitBtn = new JBButton("提交内容"); // 设置按钮点击事件:唤起自定义设置面板 settingsBtn.addActionListener(e -> { MySettingsConfigurable.showSettingsDialog(project); }); // 提交按钮点击事件:处理输入内容 submitBtn.addActionListener(e -> { String input = inputField.getText().trim(); JOptionPane.showMessageDialog(null, "你输入的内容是: " + input); }); buttonPanel.add(settingsBtn); buttonPanel.add(submitBtn); mainPanel.add(buttonPanel, BorderLayout.SOUTH); // 将面板添加到工具窗口 ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); Content content = contentFactory.createContent(mainPanel, "我的工具窗口", false); toolWindow.getContentManager().addContent(content); } }
然后在plugin.xml中注册工具窗口:
<extensions defaultExtensionNs="com.intellij"> <toolWindow id="MyToolWindow" anchor="right" factoryClass="com.yourpackage.MyToolWindowFactory"/> </extensions>
二、实现可唤起的自定义设置面板
通过Configurable接口创建设置界面,搭配PersistentStateComponent实现配置持久化:
1. 设置面板实现类
import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.ui.components.JBTextField; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; public class MySettingsConfigurable implements Configurable { private JPanel mainPanel; private JBTextField apiUrlField; private JBTextField tokenField; // 静态方法直接唤起设置对话框 public static void showSettingsDialog(Project project) { Messages.showSettingsDialog(project, new MySettingsConfigurable(), "我的插件设置"); } @Nls(capitalization = Nls.Capitalization.Title) @Override public String getDisplayName() { return "我的插件设置"; } @Nullable @Override public JComponent createComponent() { mainPanel = new JPanel(new GridLayout(2, 2, 10, 10)); mainPanel.add(new JLabel("API地址:")); apiUrlField = new JBTextField(); apiUrlField.setText(MyPluginSettings.getInstance().getApiUrl()); mainPanel.add(apiUrlField); mainPanel.add(new JLabel("授权Token:")); tokenField = new JBTextField(); tokenField.setText(MyPluginSettings.getInstance().getToken()); mainPanel.add(tokenField); return mainPanel; } @Override public boolean isModified() { // 判断设置是否被修改 return !apiUrlField.getText().equals(MyPluginSettings.getInstance().getApiUrl()) || !tokenField.getText().equals(MyPluginSettings.getInstance().getToken()); } @Override public void apply() throws ConfigurationException { // 保存修改后的配置 MyPluginSettings.getInstance().setApiUrl(apiUrlField.getText()); MyPluginSettings.getInstance().setToken(tokenField.getText()); } @Override public void reset() { // 重置为已保存的配置值 apiUrlField.setText(MyPluginSettings.getInstance().getApiUrl()); tokenField.setText(MyPluginSettings.getInstance().getToken()); } }
2. 配置持久化类
import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.util.xmlb.XmlSerializerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @State( name = "MyPluginSettings", storages = @Storage("MyPluginSettings.xml") ) public class MyPluginSettings implements PersistentStateComponent<MyPluginSettings> { private String apiUrl = "https://default.api.example.com"; private String token = ""; public static MyPluginSettings getInstance() { return ServiceManager.getService(MyPluginSettings.class); } @Nullable @Override public MyPluginSettings getState() { return this; } @Override public void loadState(@NotNull MyPluginSettings state) { XmlSerializerUtil.copyBean(state, this); } // Getter & Setter public String getApiUrl() { return apiUrl; } public void setApiUrl(String apiUrl) { this.apiUrl = apiUrl; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } }
最后在plugin.xml中注册配置组件:
<extensions defaultExtensionNs="com.intellij"> <applicationService serviceImplementation="com.yourpackage.MyPluginSettings"/> <configurable implementation="com.yourpackage.MySettingsConfigurable"/> </extensions>
三、关键提示
- 优先使用IntelliJ自带的
JB*系列控件(如JBTextField、JBButton),保证与IDE风格统一 - 事件处理逻辑和普通Java Swing开发一致,直接使用
ActionListener即可 - 配置存储必须通过
PersistentStateComponent实现,不要自行读写文件,确保兼容IDE的配置系统
内容的提问来源于stack exchange,提问作者Factor Three
相关产品推荐
相关产品推荐

