如何动态设置Jtree节点图标

时间:2015-05-12 13:08:26

标签: java swing jtree treecellrenderer

我想为分组和未分组的节点显示单独的图标。我创建了一个customTreeCellRender.My示例代码如下所示。在for循环奇数中,一个节点有一个图标,而evens有另一个。但是没有更改节点的图标。在我的应用程序,从db填充树节点并根据某些条件进行分组。这是一个可运行的示例代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;

public class TestTree extends JDialog {

    JTree tree;

    DefaultTreeModel treeModel;

    public TestTree() {
        setSize(300, 800);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        System.out.println(getContentPane().getBackground());
    }

    protected static ImageIcon createImageIcon(String path) throws MalformedURLException {
        java.net.URL imgURL = new URL(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    public void init() throws MalformedURLException {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Numbers");
        treeModel = new DefaultTreeModel(root);
        tree = new JTree(treeModel);
        tree.setBackground(new Color(238, 238, 244));
        tree.setOpaque(true);

        CustomIconRenderer customIconRenderer = new CustomIconRenderer(true);
        customIconRenderer.setTextSelectionColor(Color.white);
        customIconRenderer.setBackgroundSelectionColor(Color.blue);
        customIconRenderer.setBorderSelectionColor(Color.black);
        customIconRenderer.setBackgroundNonSelectionColor(new Color(238, 238,
                244));
        ImageIcon icon = createImageIcon("http://i.stack.imgur.com/wCF8S.png");
        customIconRenderer.setLeafIcon(icon);


        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
                        "node_" + i);
                root.add(subroot);

                    tree.setCellRenderer(new CustomIconRenderer(false));

                if (i % 3 == 0) {
                    for (int j = 10; j < 15; j++) {
                        DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
                                "node_" + j);
                        subroot.add(leaf);
                    }
                }

            } else {
                DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
                        "node_" + i);
                root.add(subroot);
                tree.setCellRenderer(new CustomIconRenderer(true));
                if (i % 4 == 0) {
                    for (int j = 15; j < 20; j++) {
                        DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
                                "node_" + j);
                        subroot.add(leaf);
                    }

                }

            }
        }

        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandRow(i);
        }

        tree.setCellRenderer(customIconRenderer);

        getContentPane().add(tree, BorderLayout.CENTER);
    }

    public static void main(String args[]) throws MalformedURLException {
        TestTree tt = new TestTree();
        tt.init();
        tt.setVisible(true);
    }
}
class CustomIconRenderer extends DefaultTreeCellRenderer {
    /**
     * 
     */
    private static final long serialVersionUID = 967937360839244309L;
    ImageIcon groupedIcon;
    ImageIcon unGroupedIcon;
    boolean grouped;

    public CustomIconRenderer() {

    }

    public CustomIconRenderer(boolean grouped) throws MalformedURLException {
        this.grouped = grouped;
        URL url=new URL("http://i.stack.imgur.com/wCF8S.png");
        URL url1=new URL("http://i.stack.imgur.com/T5uTa.png");
        groupedIcon = new ImageIcon(url1
                );
        unGroupedIcon = new ImageIcon(url
                );
    }
@Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean sel, boolean expanded, boolean leaf, int row,
            boolean hasFocus) {

        super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
                row, hasFocus);

        Object nodeObj = ((DefaultMutableTreeNode) value).getUserObject();
        // check whatever you need to on the node user object
        if (grouped) {
            setIcon(unGroupedIcon);
        } else {
            System.out.println("reached");
            setIcon(groupedIcon);
        }
        return this;
    }
}

2 个答案:

答案 0 :(得分:3)

原始代码中存在一些错误,最值得注意的是:

  • 每次添加节点时设置一个单元格渲染器(一棵树只能有一个单元格渲染器,因此最后一个添加了一个单元格获取者)。
  • 期望您为获取树状单元格渲染器而编写的稍微改变的方法将被调用。 (你 做了 我在评论中提出的实验,对吗?)

我认为这更符合要求。请注意,我试图尽可能接近原始代码。我会在这里以不同的方式看待它。

  • 此示例:检查传递给方法的String的{​​{1}}值,以使单元格渲染器查看它是否包含value个字符,然后拆分字符串并将最后一部分解析回整数值。
  • 如何完成:为树的叶子传递_个对象。在单元格渲染器中,对值的检查是Integer的实例,如果是,请在数字前加上Integer ..

enter image description here

node_

答案 1 :(得分:1)

  

我创建了一个customTreeCellRender。但没有更改图标

您无需直接致电getTreeCellRendererComponent,而是让JTree通过明确设置TreeCellRenderer的{​​{1}}来处理它,如Oracle tutorial

JTree