IDEA插件开发 - 02 - 几种用户界面组件(一)

2,603 阅读3分钟

本文简介

上一文中我们介绍了 IDEA 插件开发的第一个 demo,今天我们要说的是 IDEA 插件中的几个常用的用户界面组件。例如工具窗口、弹窗、通知等。另外从本文开始,本教程讲提供 demo 的代码,托管在 github 上,提供参考。

本文概要

  1. 工具窗口
  2. 对话框
  3. 弹出窗口
  4. 通知

1. 工具窗口

1.1 介绍

工具窗口是 IDE 的子窗口,用于显示信息。这些窗口通常在主窗口的外边缘有自己的工具栏(称为工具窗口栏),其中包含一个或多个工具窗口按钮,这些按钮可激活显示在主 IDE 窗口左侧、底部和右侧的面板。

1.2 代码

1.2.1 plugin.xml

<extensions defaultExtensionNs="com.intellij">
        <toolWindow factoryClass="icu.zheteng.tool.window.FirstToolWindowFactory"
                    id="firstToolWindow" icon="AllIcons.Actions.Colors"/>
</extensions>

1.2.2 FirstToolWindowFactory.java

public class FirstToolWindowFactory implements ToolWindowFactory {

    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        FirstToolWindow myToolWindow = new FirstToolWindow();
        ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
        Content content = contentFactory.createContent(myToolWindow.getContent(), "", false);
        toolWindow.getContentManager().addContent(content);
    }
}

1.2.3 FirstToolWindow.java

public class FirstToolWindow {
    private JPanel rootPane;
    private JLabel hello;

    public FirstToolWindow() {
    }

    public JComponent getContent() {
        return rootPane;
    }
}

1.2.4 FirstToolWindow.form

1.3 效果

2. 对话框

2.1 介绍

对话框通常用作从用户处接收附加信息,或者提供发生了某种事件的通知。

2.2 DialogWrapper 对话框包装器

DialogWrapper 是应用于 IntelliJ 平台中显示的所有模式对话框(和一些非模式对话框)的基类。

它提供一下功能:

  1. 按钮布局(OK/cancel 按钮的平台特定顺序)
  2. 上下文帮助
  3. 记住对话框的大小
  4. 非模态验证(当输入到对话框中的数据无效时显示错误消息文本)
  5. 键盘快捷键(ESC/left/right/Y/N)
  6. 可选的不再询问复选框

2.3 代码

2.3.1 自定义 DialogWrapper

public class SampleDialogWrapper extends DialogWrapper {

    private String msg;

    public SampleDialogWrapper(String title,String msg) {
        // use current window as parent
        super(true);
        this.msg = msg;
        setTitle(title);
        init();
    }

    @Nullable
    @Override
    protected JComponent createCenterPanel() {
        JPanel dialogPanel = new JPanel(new BorderLayout());

        JLabel label = new JLabel(msg);
        label.setPreferredSize(new Dimension(100, 100));
        dialogPanel.add(label, BorderLayout.CENTER);

        return dialogPanel;
    }
}

2.3.2 FirstToolWindow.form 添加按钮

2.3.3 FirstToolWindow 添加按钮事件

public FirstToolWindow() {
        wrapperBtn.addActionListener(a -> {
            boolean showAndGet = new SampleDialogWrapper("test","this is first dialog").showAndGet();
            if (showAndGet){
                new SampleDialogWrapper("test","press OK").showAndGet();
            }else {
                new SampleDialogWrapper("test","press CANCEL OR CLOSE").showAndGet();
            }
        });
    }

2.4 效果

iShot_2022-05-25_14.57.33

3. 弹出窗口

3.1 介绍

IntelliJ 平台用户界面广泛使用弹出窗口 - 没有镶边(显式关闭按钮)并在失去焦点时自动消失的半模态窗口。 弹出窗口可以选择显示标题,可选择移动和调整大小(并支持记住它们的大小),并且可以嵌套(选择项目时显示另一个弹出窗口)。

3.2 代码

3.2.1 FirstToolWindow.form 中添加 popBtn 按钮

3.2.2 FirstToolWindow 中添加 popBtn 点击事件

popBtn.addActionListener(a -> {
            PopupWindow window = new PopupWindow();
            window.popup();
        });

3.2.3 PopupWindow.form

3.2.4 PopupWindow

public class PopupWindow {
    private JPanel panel1;
    private JLabel popup;
    private JPanel root;
    private JPanel popupPanel;

    public PopupWindow() {
        root.setPreferredSize(new Dimension(600,400));
    }

    /**
     * 弹出
     */
    public void popup(){
        JBPopup jbPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(root, popupPanel)
                .setProject(ProjectManager.getInstance().getDefaultProject())
                .setResizable(true)
                .setMovable(true)

                .setModalContext(false)
                .setRequestFocus(true)
                .setBelongsToGlobalPopupStack(true)
                .setDimensionServiceKey(null, "DOC_VIEW_POPUP", true)
                .setLocateWithinScreenBounds(false)
                // 单击外部时取消弹窗
                .setCancelOnClickOutside(false)
                // 在其他窗口打开时取消
                .setCancelOnOtherWindowOpen(false)
                .setCancelOnWindowDeactivation(false)
                .createPopup();
        jbPopup.showCenteredInCurrentWindow(ProjectManager.getInstance().getDefaultProject());
    }
}

3.3 效果

iShot_2022-05-31_06.05.20

4. 通知

4.1 介绍

通知的主要设计原则之一就是避免使用模式消息框来通知用户错误和其他可能引起用户注意的情况。作为替代,IntelliJ 平台提供了多个非模态通知 UI 选项。

4.2 通知类型

有四种类型的通知:

4.2.1 alert 立即需要处理的动作

4.2.2 baners 必要但不需要立即执行的动作

4.2.3 ballon 不需要操作的
  • sticky ballons 黏性气球

  • timed ballons 定时气球

4.2.4 tool window ballon 不需要操作的

4.3 代码(仅演示 ballon 用法)

4.3.1 FirstToolWindow.form 添加两个通知按钮

4.3.2

import com.intellij.notification.NotificationGroupManager;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;

import javax.annotation.Nullable;

/**
 * @author yangpeng
 * @version 1.0.0
 * @date 2022年05月31日
 */
public class MyNotifier {

    public static void notifyError(@Nullable Project project,
                                   String content) {
        NotificationGroupManager.getInstance()
                .getNotificationGroup("Custom Notification Group")
                .createNotification(content, NotificationType.ERROR)
                .notify(project);
    }

    public static void notifyWarning(@Nullable Project project,
                                     String content) {
        NotificationGroupManager.getInstance()
                .getNotificationGroup("Custom Notification Group")
                .createNotification(content, NotificationType.WARNING)
                .notify(project);
    }
}

4.3.3 FirstToolWindow 添加两个通知按钮的点击事件

errNotifyBtn.addActionListener(a ->
                MyNotifier.notifyError(ProjectManager.getInstance().getDefaultProject(), "error test!!!"));

warnNotifyBtn.addActionListener(a ->
        MyNotifier.notifyWarning(ProjectManager.getInstance().getDefaultProject(), "error warning"));

4.4 效果

iShot_2022-05-31_06.59.36

本文参考

IntelliJ 平台插件-用户界面组件

本文代码

plugin-demo02