如何动态设置Jtree节点图标

How to set Jtree node icon dynamically

我想为分组和未分组显示单独的图标 nodes.I 创建了一个 customTreeCellRender.My 给定的示例代码 below.In for loop odd one nodes with one icon and evens have another.But 不更改 nodes.In 我的应用程序的图标,从数据库填充树节点并根据一些 conditions.This 进行分组是一个示例可运行代码。

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

I created a customTreeCellRender.But not changing the icon

您不需要直接调用 getTreeCellRendererComponent,而是让 JTree 通过显式设置 JTreeTreeCellRenderer 来处理它,如 Oracle tutorial

tree.setCellRenderer(customIconRenderer);

原始代码中有几个错误,最值得注意的是:

  • 每次添加节点时都设置一个单元格渲染器(一棵树只能有一个单元格渲染器,所以 'last one added' 获胜)。
  • 预计您为获取树单元渲染器而编写的略有改动的方法将被调用。 (你做了我在评论中提出的实验,对吧?)

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

  • 此示例: 检查传递给方法的 valueString 值以获取单元格渲染器以查看它是否包含 _ 字符,然后拆分字符串并将最后一部分解析回整数值。
  • 应该怎么做: 为树的叶子传递 Integer 个对象。在单元格渲染器中,值的检查是 Integer 的实例,如果是,则在数字前加上 node_ ..

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

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();
        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);
        tree.setCellRenderer(new CustomIconRenderer());

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

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

    public CustomIconRenderer() throws MalformedURLException {
        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();
        String s = nodeObj.toString();
        System.out.println("s: " + s);
        boolean includesUnderscore = s.indexOf("_") > 0;
        if (includesUnderscore) {
            String lastPart = s.split("_")[1];
            int num = Integer.parseInt(lastPart);
            // check whatever you need to on the node user object
            if (num % 2 == 0) {
                setIcon(unGroupedIcon);
            } else {
                System.out.println("reached");
                setIcon(groupedIcon);
            }
        }
        return this;
    }
}