idea plugin插件开发1——idea底部窗口(带按钮)

目录

第一步:新建一个Executor

第二步:自定义按钮

第三步:定义runner

第四步:定义插件Action

第五步:plugin.xml 配置

 相关文章推荐


idea插件开发资料实在太少,官方demo的例子也很少。

 官方demo:GitHub - JetBrains/intellij-sdk-code-samples: Mirror of the IntelliJ SDK Docs Code Sampleshttps://github.com/JetBrains/intellij-sdk-code-samples

这里笔者介绍一下官方demo中没有的例子——底部窗口

这只是一个demo,用于实际开发,还要结合官方手册来。

先看下效果图: 

给大家看下我的目录结构:

第一步:新建一个Executor

package com.example.action.t3_tool_windows.console_view.bottom_console;

import com.example.utils.MyIconUtil;
import com.intellij.execution.Executor;
import org.jetbrains.annotations.NotNull;

import javax.swing.Icon;

public class ConsoleTool_Executor extends Executor {

    public static final String PLUGIN_ID = "SQL Plugin ID";

    public static final String TOOL_WINDOW_ID = "SQL Scanner";

    public static final String CONTEXT_ACTION_ID = "custom context action id";

    @NotNull
    @Override
    public String getId() {
        return PLUGIN_ID;
    }

    @Override
    public String getToolWindowId() {
        return TOOL_WINDOW_ID;
    }

    @Override
    public Icon getToolWindowIcon() {
        return MyIconUtil.ICON;
    }

    @NotNull
    @Override
    public Icon getIcon() {
        return MyIconUtil.ICON;
    }

    @Override
    public Icon getDisabledIcon() {
        return MyIconUtil.ICON;
    }

    @Override
    public String getDescription() {
        return TOOL_WINDOW_ID;
    }

    @NotNull
    @Override
    public String getActionName() {
        return TOOL_WINDOW_ID;
    }

    @NotNull
    @Override
    public String getStartActionText() {
        return TOOL_WINDOW_ID;
    }

    @Override
    public String getContextActionId() {
        return CONTEXT_ACTION_ID;
    }

    @Override
    public String getHelpId() {
        return TOOL_WINDOW_ID;
    }

}

在 plugin.xml 中添加, 注意路径换成你自己的。

<!-- 插件扩展 -->
<extensions defaultExtensionNs="com.intellij">
      <!-- 自定义 底部view -->
    <executor id="CustomRunExecutor" order="last" implementation="com.example.action.t3_tool_windows.console_view.bottom_console.ConsoleTool_Executor"/>
</extensions>

我的build.gradle配置如下:


plugins {
    id 'org.jetbrains.intellij' version '0.4.10'
    id "org.jetbrains.kotlin.jvm" version "1.3.41"
    id 'java'
}
repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

apply {
    "java"
    "terminal"
    "ant"
}
group 'org.example'
version '1.0-SNAPSHOT'

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
    version '2019.3.3'
    // 必须,否则无法找到 PsiClass 等
    plugins = ['java', 'gradle']
    intellij.updateSinceUntilBuild false
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

apply {
    "java"
    "terminal"
    "ant"
}

test {
    useJUnitPlatform()
}

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

buildPlugin {
    buildSearchableOptions.enabled = false
}

第二步:自定义按钮

先添加后面需要用到的工具类

这个类是为了获取当前窗口的运行状态,以便后续扩充操作。

public enum MyProjectUtil {
    ;

    public static void setRunning(Project project, String key, boolean value) {
        PropertiesComponent.getInstance(project).setValue(key, value);
    }

    public static boolean getRunning(Project project, String key) {
        return PropertiesComponent.getInstance(project).getBoolean(key);
    }
}

下面这个类是获取正在运行的Executor


public enum MyExecutorUtil {
    ;

    /**
     * 返回正在运行的 Executor
     * @param id Executor id
     */
    public static Executor getRunExecutorInstance(String id) {
        return ExecutorRegistry.getInstance().getExecutorById(id);
    }
}

重启按钮Action:

package com.example.action.t3_tool_windows.console_view.bottom_console.toolbar;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAware;

/**
 * 重启 ConsoleTool
 */
public class ConsoleTool_Rerun_Action extends AnAction implements DumbAware {

    /**
     * 重启 ToolWindow
     */
    private Runnable rerun;

    public ConsoleTool_Rerun_Action(Runnable rerun) {
        super("Rerun", "Rerun", AllIcons.Actions.Restart);
        this.rerun = rerun;
    }

    /**
     * 执行动作
     */
    @Override
    public void actionPerformed(AnActionEvent e) {
        rerun.run();
    }

    /**
     * 监听该Action, 每次焦点更换、窗口切换都会触发 update
     */
    @Override
    public void update(AnActionEvent e) {
        e.getPresentation().setVisible(rerun != null);
    }
}

关闭按钮Action

package com.example.action.t3_tool_windows.console_view.bottom_console.toolbar;

import com.example.utils.MyProjectUtil;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAware;

public class ConsoleTool_Stop_Action extends AnAction implements DumbAware {

    /**
     * 停止 ToolWindow
     */
    private Runnable stop;


    public ConsoleTool_Stop_Action(Runnable stop) {
        super("Stop", "Stop", AllIcons.Actions.Suspend);
        this.stop = stop;
    }

    /**
     * 执行动作
     */
    @Override
    public void actionPerformed(AnActionEvent e) {
        stop.run();
    }

    /**
     * 监听该Action, 每次焦点更换、窗口切换都会触发 update
     */
    @Override
    public void update(AnActionEvent e) {
        if (null != e && null != e.getProject()) {
            e.getPresentation().setEnabled(MyProjectUtil.getRunning(e.getProject(), "running"));
        }
    }
}

 一个自定义的执行按钮

package com.example.action.t3_tool_windows.console_view.bottom_console.toolbar;

import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;

public class Scanner_Action extends AnAction {

    private ConsoleView consoleView;

    public Scanner_Action(ConsoleView consoleView) {
        super("Scanner Sql", "Scanner sql", AllIcons.Actions.Upload);
        this.consoleView = consoleView;
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        // Messages.showMessageDialog("SQL Scan Action", "Scanner", Messages.getInformationIcon());
        if (null != consoleView) {
            consoleView.print("新输出一条日志.", ConsoleViewContentType.NORMAL_OUTPUT);
        }
    }
}

第三步:定义runner

package com.example.action.t3_tool_windows.console_view.bottom_console;

import com.example.action.t3_tool_windows.console_view.bottom_console.toolbar.ConsoleTool_Rerun_Action;
import com.example.action.t3_tool_windows.console_view.bottom_console.toolbar.ConsoleTool_Stop_Action;
import com.example.action.t3_tool_windows.console_view.bottom_console.toolbar.Scanner_Action;
import com.example.utils.MyExecutorUtil;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.project.Project;
import com.intellij.ui.content.Content;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;

public class ConsoleTool_Runner {

    /**
     * Project
     */
    private Project project = null;

    /**
     * 视图面板
     */
    private ConsoleView consoleView = null;


    /**
     * 重启/运行 ToolWindow
     */
    private Runnable rerun;

    /**
     * 停止 ToolWindow
     */
    private Runnable stop;


    public ConsoleTool_Runner(@NotNull Project project, Runnable rerun, Runnable stop) {
        this.project = project;
        this.consoleView = createConsoleView(project);
        this.rerun = rerun;
        this.stop = stop;
    }

    private ConsoleView createConsoleView(Project project) {
        TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
        ConsoleView console = consoleBuilder.getConsole();
        console.print("第一行日志输出", ConsoleViewContentType.LOG_DEBUG_OUTPUT);
        return console;
    }

    public void run() {
        // 返回定义的 Executor
        Executor executor = MyExecutorUtil.getRunExecutorInstance(ConsoleTool_Executor.PLUGIN_ID);
        if (executor == null) {
            return;
        }

        // 创建 RunnerLayoutUi
        final RunnerLayoutUi.Factory factory = RunnerLayoutUi.Factory.getInstance(project);
        RunnerLayoutUi layoutUi = factory.create("id", "title", "session name", project);

        // 创建 panel
        final JPanel panel = new JPanel();
        panel.add(consoleView.getComponent(), BorderLayout.CENTER);

        // 创建描述信息
        RunContentDescriptor descriptor = new RunContentDescriptor(new RunProfile() {
            @Nullable
            @Override
            public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException {
                return null;
            }

            @NotNull
            @Override
            public String getName() {
                return "name";
            }

            @Nullable
            @Override
            public Icon getIcon() {
                return null;
            }
        }, new DefaultExecutionResult(), layoutUi);
        descriptor.setExecutionId(System.nanoTime());

        final Content content = layoutUi.createContent("contentId", panel, "displayName", AllIcons.Debugger.Console, panel);
        content.setCloseable(true);
        layoutUi.addContent(content);

        // 新增左边工具条
        layoutUi.getOptions().setLeftToolbar(createActionToolbar(consoleView), "RunnerToolbar");

        ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor);
    }

    private ActionGroup createActionToolbar(ConsoleView consoleView) {
        final DefaultActionGroup actionGroup = new DefaultActionGroup();
        // ConsoleView 按钮: warp
        actionGroup.add(consoleView.createConsoleActions()[2]);
        // ConsoleView 按钮: scroll to end
        actionGroup.add(consoleView.createConsoleActions()[3]);
        // ConsoleView 按钮: clear
        actionGroup.add(consoleView.createConsoleActions()[5]);
        // 自定义按钮
        actionGroup.add(new Scanner_Action(consoleView));
        actionGroup.add(new ConsoleTool_Rerun_Action(rerun));
        actionGroup.add(new ConsoleTool_Stop_Action(stop));
        return actionGroup;
    }
}

第四步:定义插件Action

package com.example.action.t3_tool_windows.console_view.bottom_console.action;

import com.example.action.t3_tool_windows.console_view.bottom_console.ConsoleTool_Runner;
import com.example.utils.MyProjectUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;

public class ConsoleTool_Action extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        runExecutor(e.getProject());
    }

    public void runExecutor(Project project) {
        if (project == null) {
            return;
        }

        // 设置restart (再次执行这个action)
        Runnable rerun = () -> runExecutor(project);

        // 设置stop
        Runnable stop = () -> MyProjectUtil.setRunning(project, "running", false);

        MyProjectUtil.setRunning(project, "running", true);
        ConsoleTool_Runner executor = new ConsoleTool_Runner(project, rerun, stop);

        executor.run();
    }
}

至此代码写完!

第五步:plugin.xml 配置

注意,下面的路径需要更换成你自己的路径。

	<!-- 插件扩展 -->
	<extensions defaultExtensionNs="com.intellij">
	      <!-- 自定义 底部view -->
	    <executor id="CustomRunExecutor" order="last" implementation="com.example.action.t3_tool_windows.console_view.bottom_console.ConsoleTool_Executor"/>
	</extensions>
    <actions>
        <!-- 自定义分组 -->
        <group id="zhang.group1.id" text="Zhang-菜单汇总" description="Group1 description">
            <add-to-group group-id="MainMenu" anchor="last"/>

            <action id="zhang.bottom_tool.id"
                    class="com.example.action.t3_tool_windows.console_view.bottom_console.action.ConsoleTool_Action"
                    text="底部-ToolWindow" description="Description">
            </action>
        </group>
    </actions>

 相关文章推荐

笔者的开源插件:Java Mybatis SQL Scannerhttps://zhangxiaofan.blog.csdn.net/article/details/123094358

idea plugin插件开发2——预览代码(多窗口)https://zhangxiaofan.blog.csdn.net/article/details/123097015idea plugin插件开发3——可编辑表单https://zhangxiaofan.blog.csdn.net/article/details/123097368

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值