IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> idea plugin插件开发3——可编辑表单 -> 正文阅读

[开发工具]idea plugin插件开发3——可编辑表单

目录

第一步:定义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

大家可以自己替换icon

package com.example.action.t6_table;

import com.intellij.execution.Executor;
import com.intellij.icons.AllIcons;
import org.jetbrains.annotations.NotNull;

import javax.swing.Icon;

public class TableExecutor extends Executor {


    public static final String PLUGIN_ID = "TableExecutor";

    public static final String TOOL_WINDOW_ID = "TableExecutor";

    public static final String CONTEXT_ACTION_ID = "2222";

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

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

    @Override
    public Icon getToolWindowIcon() {
        return AllIcons.Actions.Redo;
    }

    @NotNull
    @Override
    public Icon getIcon() {
        return AllIcons.Actions.Redo;
    }

    @Override
    public Icon getDisabledIcon() {
        return AllIcons.Actions.Redo;
    }

    @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;
    }

}

第二步:定义表单元素

?先定义一个抽象类:

package com.example.action.t6_table.table;

import com.intellij.ide.browsers.BrowserSpecificSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.UUID;

public abstract class AbstractRow {
    public AbstractRow() {
    }

    @NotNull
    public abstract UUID getId();

    @NotNull
    public abstract String getName();


    @NotNull
    public abstract MyIconItem getIcon();

    @Nullable
    public abstract String getPath();

    @Nullable
    public abstract BrowserSpecificSettings getSpecificSettings();
}

定义table

package com.example.action.t6_table.table;

import com.intellij.ide.browsers.BrowserSpecificSettings;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.intellij.util.ui.LocalPathCellEditor;
import com.intellij.util.ui.table.IconTableCellRenderer;
import com.intellij.util.ui.table.TableModelEditor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.JComponent;
import javax.swing.event.TableModelEvent;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.util.Comparator;
import java.util.UUID;


/**
 * 参考
 * {@link com.intellij.ide.browsers.BrowserSettingsPanel}
 */
public class MyTable {

    private TableModelEditor<MyRow> browsersEditor;

    private JComponent browsersTable;

    public JComponent getBrowsersTable() {
        return browsersTable;
    }

    private static final FileChooserDescriptor APP_FILE_CHOOSER_DESCRIPTOR = FileChooserDescriptorFactory.createSingleFileOrExecutableAppDescriptor();


    private static final TableModelEditor.EditableColumnInfo<MyRow, Boolean> selectOptColumn = new TableModelEditor.EditableColumnInfo<MyRow, Boolean>("select") {
        @Override
        public Class getColumnClass() {
            return Boolean.class;
        }

        @Override
        public Boolean valueOf(MyRow item) {
            return item.isActive();
        }

        @Override
        public void setValue(MyRow item, Boolean value) {
            item.setActive(value);
        }
    };

    private static final TableModelEditor.EditableColumnInfo<MyRow, String> nameColumn = new TableModelEditor.EditableColumnInfo<MyRow, String>("Name") {
        @Override
        public String valueOf(MyRow item) {
            return item.getName();
        }

        @Override
        public void setValue(MyRow item, String value) {
            item.setName(value);
        }

        /**
         * 添加排序比较,支持列排序
         */
        @NotNull
        @Override
        public Comparator<MyRow> getComparator() {
            return new Comparator<MyRow>() {
                @Override
                public int compare(MyRow o1, MyRow o2) {
                    if (o1.getName().compareTo(o2.getName()) > 0) {
                        return 1;
                    } else if (o1.getName().compareTo(o2.getName()) == 0) {
                        return 0;
                    } else {
                        return -1;
                    }
                }
            };
        }
    };

    private static final ColumnInfo<MyRow, MyIconItem> browserColumn = new ColumnInfo<MyRow, MyIconItem>("browser") {
        @Override
        public Class getColumnClass() {
            return MyIconItem.class;
        }

        @Override
        public MyIconItem valueOf(MyRow item) {
            return item.getIcon();
        }

        @Override
        public void setValue(MyRow item, MyIconItem value) {
            item.setIcon(value);
            item.setSpecificSettings(value.createBrowserSpecificSettings());
        }

        @NotNull
        @Override
        public TableCellRenderer getRenderer(MyRow item) {
            return IconTableCellRenderer.ICONABLE;
        }
    };

    private static final ColumnInfo[] COLUMNS = {
            selectOptColumn,
            nameColumn,
            browserColumn,
            new TableModelEditor.EditableColumnInfo<MyRow, String>("Path") {
                @Override
                public String valueOf(MyRow item) {
                    return PathUtil.toSystemDependentName(item.getPath());
                }

                @Override
                public void setValue(MyRow item, String value) {
                    item.setPath(value);
                }

                @Nullable
                @Override
                public TableCellEditor getEditor(MyRow item) {
                    return new LocalPathCellEditor().fileChooserDescriptor(APP_FILE_CHOOSER_DESCRIPTOR).normalizePath(true);
                }
            }};


    public MyTable() {
        TableModelEditor.DialogItemEditor<MyRow> itemEditor = new TableModelEditor.DialogItemEditor<MyRow>() {
            @NotNull
            @Override
            public Class<MyRow> getItemClass() {
                return MyRow.class;
            }

            @Override
            public MyRow clone(@NotNull MyRow item, boolean forInPlaceEditing) {
                return new MyRow(forInPlaceEditing ? item.getId() : UUID.randomUUID(),
                        item.getIcon(), item.getName(), item.getPath(), item.isActive(),
                        forInPlaceEditing ? item.getSpecificSettings() : cloneSettings(item));
            }

            @Override
            public void edit(@NotNull MyRow browser, @NotNull Function<MyRow, MyRow> mutator, boolean isAdd) {
                BrowserSpecificSettings settings = cloneSettings(browser);
                if (settings != null && ShowSettingsUtil.getInstance().editConfigurable(browsersTable, settings.createConfigurable())) {
                    mutator.fun(browser).setSpecificSettings(settings);
                }
            }

            @Override
            public void applyEdited(@NotNull MyRow oldItem, @NotNull MyRow newItem) {
                oldItem.setSpecificSettings(newItem.getSpecificSettings());
            }

            @Override
            public boolean isEditable(@NotNull MyRow browser) {
                return false;
            }


            @Nullable
            private BrowserSpecificSettings cloneSettings(@NotNull MyRow browser) {
                BrowserSpecificSettings settings = browser.getSpecificSettings();
                if (settings == null) {
                    return null;
                }

                BrowserSpecificSettings newSettings = browser.getIcon().createBrowserSpecificSettings();
                assert newSettings != null;
                TableModelEditor.cloneUsingXmlSerialization(settings, newSettings);
                return newSettings;
            }

        };

        TableModelEditor.DataChangedListener<MyRow> dataChangedListener = new TableModelEditor.DataChangedListener<MyRow>() {
            @Override
            public void tableChanged(@NotNull TableModelEvent event) {
            }

            @Override
            public void dataChanged(@NotNull ColumnInfo<MyRow, ?> columnInfo, int rowIndex) {
            }
        };

        browsersEditor = new TableModelEditor<>(COLUMNS, itemEditor, "No web browsers configured");
        browsersEditor.modelListener(dataChangedListener);

        ListTableModel<MyRow> model = this.browsersEditor.getModel();
        MyRow myRow1 = new MyRow(
                UUID.randomUUID(),
                MyIconItem.CHROME,
                "3",
                "null",
                true,
                null
        );
        MyRow myRow2 = new MyRow(
                UUID.randomUUID(),
                MyIconItem.CHROME,
                "4",
                "null",
                true,
                null
        );

        model.addRow(myRow1);
        model.addRow(myRow2);

        browsersTable = browsersEditor.createComponent();
    }

}



定义行元素 row

package com.example.action.t6_table.table;

import com.intellij.ide.browsers.BrowserSpecificSettings;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.UUID;

public class MyRow extends AbstractRow {

    private final UUID id;

    @NotNull
    private MyIconItem icon;

    @NotNull
    private String name;

    private boolean active;

    private String path;

    /**
     * 保存当前表格数据
     */
    private BrowserSpecificSettings specificSettings;

    @SuppressWarnings("UnusedDeclaration")
    MyRow() {
        this(UUID.randomUUID(), MyIconItem.CHROME);
    }

    MyRow(@NotNull UUID id, @NotNull MyIconItem icon) {
        this(id, icon, icon.getName(), icon.getExecutionPath(), true, icon.createBrowserSpecificSettings());
    }

    public MyRow(@NotNull UUID id,
                 @NotNull MyIconItem icon,
                 @NotNull String name,
                 @Nullable String path,
                 boolean active,
                 @Nullable BrowserSpecificSettings specificSettings) {
        this.id = id;
        this.icon = icon;
        this.name = name;

        this.path = StringUtil.nullize(path);
        this.active = active;
        this.specificSettings = specificSettings;
    }

    public void setName(@NotNull String value) {
        name = value;
    }

    public void setIcon(@NotNull MyIconItem value) {
        icon = value;
    }

    @Nullable
    @Override
    public String getPath() {
        return path;
    }

    public void setPath(@Nullable String value) {
        path = PathUtil.toSystemIndependentName(StringUtil.nullize(value));
    }

    @Override
    @Nullable
    public BrowserSpecificSettings getSpecificSettings() {
        return specificSettings;
    }

    public void setSpecificSettings(@Nullable BrowserSpecificSettings value) {
        specificSettings = value;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean value) {
        active = value;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof MyRow)) {
            return false;
        }

        MyRow browser = (MyRow) o;
        return getId().equals(browser.getId()) &&
                icon.equals(browser.icon) &&
                active == browser.active &&
                Comparing.strEqual(name, browser.name) &&
                Comparing.equal(path, browser.path) &&
                Comparing.equal(specificSettings, browser.specificSettings);
    }

    @Override
    public int hashCode() {
        return getId().hashCode();
    }

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

    @Override
    @NotNull
    public final UUID getId() {
        return id;
    }

    @Override
    @NotNull
    public MyIconItem getIcon() {
        return icon;
    }


    @Override
    public String toString() {
        return getName() + " (" + getPath() + ")";
    }
}

定义行元素中的特殊值:icon

package com.example.action.t6_table.table;

import com.intellij.icons.AllIcons.Xml.Browsers;
import com.intellij.ide.browsers.BrowserSpecificSettings;
import com.intellij.ide.browsers.chrome.ChromeSettings;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.Icon;

public enum MyIconItem implements Iconable {
    CHROME("chrome", "chrome", "google-chrome", "Google Chrome", Browsers.Chrome16) {
        @Override
        public BrowserSpecificSettings createBrowserSpecificSettings() {
            return new ChromeSettings();
        }
    },
    ;

    private final String myName;
    private final String myWindowsPath;
    private final String myUnixPath;
    private final String myMacPath;
    private final Icon myIcon;

    private MyIconItem(@NotNull String name, @NotNull String windowsPath, @Nullable String unixPath, @Nullable String macPath, @NotNull Icon icon) {
        this.myName = name;
        this.myWindowsPath = windowsPath;
        this.myUnixPath = unixPath;
        this.myMacPath = macPath;
        this.myIcon = icon;
    }

    @Nullable
    public BrowserSpecificSettings createBrowserSpecificSettings() {
        return null;
    }

    @Nullable
    public String getExecutionPath() {
        if (SystemInfo.isWindows) {
            return this.myWindowsPath;
        } else {
            return SystemInfo.isMac ? this.myMacPath : this.myUnixPath;
        }
    }

    public String getName() {
        return this.myName;
    }

    public Icon getIcon() {
        return this.myIcon;
    }

    public String toString() {
        return this.myName;
    }

    public Icon getIcon(@IconFlags int flags) {
        return this.getIcon();
    }
}

第三步:定义Runner

我们会用到工具类:


import com.intellij.execution.Executor;
import com.intellij.execution.ExecutorRegistry;

public enum MyExecutorUtil {
    ;

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

?Runner代码如下:

package com.example.action.t6_table;

import com.example.action.t6_table.table.MyTable;
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.runners.ExecutionEnvironment;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.icons.AllIcons;
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.Icon;

public class TableRunner {

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


    public TableRunner(@NotNull Project project) {
        this.project = project;
    }


    public void run() {

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

        // 创建 RunnerLayoutUi
        final RunnerLayoutUi.Factory factory = RunnerLayoutUi.Factory.getInstance(project);
        RunnerLayoutUi layoutUi = factory.create("id2", "title2", "session name2", project);

        // 创建描述信息
        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());

        MyTable myTable = new MyTable();


        final Content content = layoutUi.createContent("contentId", myTable.getBrowsersTable(), "displayName2", AllIcons.Debugger.Console, myTable.getBrowsersTable());
        content.setCloseable(true);
        layoutUi.addContent(content);


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


}

第四步:定义Action

我们会用到工具类:


import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.project.Project;

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);
    }
}

?Action代码如下:

package com.example.action.t6_table.action;

import com.example.action.t6_table.TableRunner;
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 TableAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        runExecutor(e.getProject());
    }

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

        MyProjectUtil.setRunning(project, "running", true);


        TableRunner executor = new TableRunner(project);

        executor.run();
    }
}

第五步:配置 plugin.xml

?plugin.xml:

	<!-- 插件扩展 -->
	<extensions defaultExtensionNs="com.intellij">
	   <!-- 自定义 底部view -->
        <executor id="TableExecutor" order="last"
                  implementation="com.example.action.t6_table.TableExecutor"/>
	</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.id3"
                    class="com.example.action.t6_table.action.TableAction"
                    text="底部-ToolWindow-表格" description="Description">
            </action>
        </group>
    </actions>

笔者项目用的 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
}

相关文章推荐

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

idea plugin插件开发1——idea底部窗口(带按钮)https://zhangxiaofan.blog.csdn.net/article/details/123093013

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

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:50:46  更:2022-02-26 11:51:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:45:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码