美文网首页
(九)IntelliJ 插件开发—— List and Tree

(九)IntelliJ 插件开发—— List and Tree

作者: 秋水畏寒 | 来源:发表于2020-03-08 15:19 被阅读0次

    官方文档

    https://www.jetbrains.org/intellij/sdk/docs/user_interface_components/lists_and_trees.html

    Github

    https://github.com/kungyutucheng/my_gradle_plugin

    运行环境

    macOS 10.14.5
    IntelliJ idea 2019.2.4

    图形素材来源

    https://www.iconfont.cn/collections/detail?spm=a313x.7781069.1998910419.de12df413&cid=16957

    定义

    相比JList,JBList出了拥有JList相关功能,还具备以下几个优势:

    • 元素内容长度超过组件宽度时,可以以tooltip的形式展示完整内容
    • 没有元素时,可以通过调用getEmptyText().setText()来设置默认展示文本
    • 可以通过调用setPaintBusy()展示一个icon在组件右上角,以显示当前有后台运行任务

    相比JTree,Tree则多了拖拉等功能

    JBList

    效果

    初始效果 查找模式 AddAction ExtraAction

    Demo

    ListAction

    package com.kungyu.jblist;
    
    import com.intellij.openapi.actionSystem.AnAction;
    import com.intellij.openapi.actionSystem.AnActionEvent;
    import org.jetbrains.annotations.NotNull;
    
    /**
     * @author wengyongcheng
     * @since 2020/3/5 11:23 下午
     */
    public class ListAction extends AnAction {
    
        @Override
        public void actionPerformed(@NotNull AnActionEvent e) {
            new ListDialogWrapper().showAndGet();
        }
    }
    

    注册Action

    <action id="com.kungyu.jblist.ListAction" class="com.kungyu.jblist.ListAction"
                    text="ListAction" description="ListAction">
        <add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="com.kungyu.file.chooser.FileChooserAction"/>
    </action>
    

    ListDialogWrapper

    package com.kungyu.jblist;
    
    import com.intellij.openapi.ui.DialogWrapper;
    import com.intellij.openapi.ui.Messages;
    import com.intellij.openapi.ui.ValidationInfo;
    import com.intellij.ui.ColoredListCellRenderer;
    import com.intellij.ui.ListSpeedSearch;
    import com.intellij.ui.ToolbarDecorator;
    import com.intellij.ui.components.JBList;
    import org.apache.commons.lang.StringUtils;
    import org.jetbrains.annotations.NotNull;
    import org.jetbrains.annotations.Nullable;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * @author wengyongcheng
     * @since 2020/3/6 11:55 下午
     */
    public class ListDialogWrapper extends DialogWrapper {
    
        private JBList<Integer> list;
    
        private DefaultListModel<Integer> defaultListModel;
    
        public ListDialogWrapper(){
            super(true);
            init();
            setTitle("JBList");
        }
    
        @Nullable
        @Override
        protected JComponent createCenterPanel() {
    
            defaultListModel = new DefaultListModel<>();
            for (int i = 0;i < 10; i++) {
                defaultListModel.addElement(i);
            }
            list = new JBList<>(defaultListModel);
    
            // 修饰每一行的元素
            ColoredListCellRenderer<Integer> coloredListCellRenderer = new ColoredListCellRenderer<Integer>() {
                @Override
                protected void customizeCellRenderer(@NotNull JList<? extends Integer> list, Integer value, int index, boolean selected, boolean hasFocus) {
                    append(value + "-suffix");
                }
            };
            list.setCellRenderer(coloredListCellRenderer);
    
            // 触发快速查找
            new ListSpeedSearch<>(list);
    
            // 增加工具栏(新增按钮、删除按钮、上移按钮、下移按钮)
            ToolbarDecorator decorator = ToolbarDecorator.createDecorator(list);
            // 新增元素动作
            decorator.setAddAction(actionButton -> addAction());
            // 自定义按钮
            decorator.addExtraAction(new ExtraButtonAction(defaultListModel,list));
    
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            panel.add(decorator.createPanel(), BorderLayout.CENTER);
            return panel;
        }
    
        private void addAction() {
            String newItem = Messages.showInputDialog("Input A Item", "Add", Messages.getInformationIcon());
            if (StringUtils.isNotBlank(newItem)) {
                defaultListModel.addElement(Integer.valueOf(newItem));
            }
        }
    
    
        @Nullable
        @Override
        protected ValidationInfo doValidate() {
            Integer value = list.getSelectedValue();
            if (value != null) {
                Messages.showMessageDialog(value + "",value + "", Messages.getInformationIcon());
            }
            return null;
        }
    }
    

    ExtraButtonAction

    package com.kungyu.jblist;
    
    import com.intellij.openapi.actionSystem.AnActionEvent;
    import com.intellij.openapi.ui.Messages;
    import com.intellij.openapi.util.IconLoader;
    import com.intellij.ui.AnActionButton;
    import com.intellij.ui.components.JBList;
    import org.apache.commons.lang.StringUtils;
    import org.jetbrains.annotations.NotNull;
    
    import javax.swing.*;
    
    /**
     * @author wengyongcheng
     * @since 2020/3/7 9:38 下午
     */
    public class ExtraButtonAction extends AnActionButton {
    
        private JBList list;
    
        private DefaultListModel<Integer> model;
    
        public ExtraButtonAction(DefaultListModel<Integer> model,JBList list) {
            super("Extra", IconLoader.getIcon("/icons/edit.svg"));
            this.model = model;
            this.list = list;
        }
    
    
        @Override
        public void actionPerformed(@NotNull AnActionEvent e) {
            int index = list.getSelectedIndex();
            String newValue = Messages.showInputDialog(model.get(index) + "", "Edit", Messages.getInformationIcon());
            if (StringUtils.isNotBlank(newValue)) {
                model.add(index, Integer.valueOf(newValue));
            }
        }
    }
    
    

    其中,数据集合还可以使用SortedListModel等,也可以继承AbstractListModel来自定义,若是使用自定义数据集合,新增元素时需触发以下方法

        /**
         * <code>AbstractListModel</code> subclasses must call this method
         * <b>after</b>
         * one or more elements are added to the model.  The new elements
         * are specified by a closed interval index0, index1 -- the enpoints
         * are included.  Note that
         * index0 need not be less than or equal to index1.
         *
         * @param source the <code>ListModel</code> that changed, typically "this"
         * @param index0 one end of the new interval
         * @param index1 the other end of the new interval
         * @see EventListenerList
         * @see DefaultListModel
         */
        protected void fireIntervalAdded(Object source, int index0, int index1)
        {
            Object[] listeners = listenerList.getListenerList();
            ListDataEvent e = null;
    
            for (int i = listeners.length - 2; i >= 0; i -= 2) {
                if (listeners[i] == ListDataListener.class) {
                    if (e == null) {
                        e = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED, index0, index1);
                    }
                    ((ListDataListener)listeners[i+1]).intervalAdded(e);
                }
            }
        }
    

    SortedListModel为例,其添加元素的方法是这样的:

      private void add(int index, T item) {
        myItems.add(index, item);
        fireIntervalAdded(this, index, index);
      }
    

    Tree

    效果

    Tree

    Demo

    TreeAction

    package com.kungyu.tree;
    
    import com.intellij.openapi.actionSystem.AnAction;
    import com.intellij.openapi.actionSystem.AnActionEvent;
    import org.jetbrains.annotations.NotNull;
    
    /**
     * @author wengyongcheng
     * @since 2020/3/7 10:21 下午
     */
    public class TreeAction extends AnAction {
        @Override
        public void actionPerformed(@NotNull AnActionEvent e) {
            new TreeDialogWrapper().showAndGet();
        }
    }
    
    

    注册Action

    <action id="com.kungyu.tree.TreeAction" class="com.kungyu.tree.TreeAction"
                    text="TreeAction" description="TreeAction">
        <add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="com.kungyu.jblist.ListAction"/>
    </action>
    

    TreeDialogWrapper

    package com.kungyu.tree;
    
    import com.intellij.openapi.ui.DialogWrapper;
    import com.intellij.ui.ColoredTreeCellRenderer;
    import com.intellij.ui.ToolbarDecorator;
    import com.intellij.ui.TreeSpeedSearch;
    import com.intellij.ui.treeStructure.Tree;
    import com.intellij.util.ui.EditableTreeModel;
    import org.jetbrains.annotations.NotNull;
    import org.jetbrains.annotations.Nullable;
    
    import javax.swing.*;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreePath;
    import java.awt.*;
    import java.util.Collection;
    
    /**
     * @author wengyongcheng
     * @since 2020/3/7 10:22 下午
     */
    public class TreeDialogWrapper extends DialogWrapper {
    
        private Tree tree;
    
        private DefaultTreeModel model;
    
        public TreeDialogWrapper() {
            super(true);
            init();
            setTitle("Tree");
        }
        @Nullable
        @Override
        protected JComponent createCenterPanel() {
            // 创建节点
            DefaultMutableTreeNode child1Leaf1 = new DefaultMutableTreeNode();
            child1Leaf1.setUserObject("child1Leaf1");
    
            DefaultMutableTreeNode child1 = new DefaultMutableTreeNode();
            child1.add(child1Leaf1);
            child1.setUserObject("child1");
    
            DefaultMutableTreeNode child1Leaf2 = new DefaultMutableTreeNode();
            child1Leaf2.setUserObject("child1Leaf2");
    
            DefaultMutableTreeNode child2 = new DefaultMutableTreeNode();
            child2.add(child1Leaf2);
            child2.setUserObject("child2");
    
            DefaultMutableTreeNode root = new DefaultMutableTreeNode();
            root.setUserObject("root");
            root.add(child1);
            root.add(child2);
    
            // 创建数据模型
            model = new DefaultTreeModel(root);
            tree = new Tree(model);
            tree.setDragEnabled(true);
            tree.setExpandableItemsEnabled(true);
    
            // 快速查找
            new TreeSpeedSearch(tree);
    
            // 自定义样式
            ColoredTreeCellRenderer coloredTreeCellRenderer = new ColoredTreeCellRenderer() {
                @Override
                public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
                    append(value + "-suffix");
    
                }
            };
            tree.setCellRenderer(coloredTreeCellRenderer);
    
            // 工具栏
            ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(tree);
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            panel.add(toolbarDecorator.createPanel(), BorderLayout.CENTER);
            return panel;
        }
    }
    

    相关文章

      网友评论

          本文标题:(九)IntelliJ 插件开发—— List and Tree

          本文链接:https://www.haomeiwen.com/subject/arecdhtx.html