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

2020-03-08  本文已影响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相关功能,还具备以下几个优势:

相比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;
    }
}
上一篇下一篇

猜你喜欢

热点阅读