为JTree中的每个节点设置图标。

14
我想为我的JTree组件中的每个节点设置不同的图标。我使用一个while循环从数据库加载每个节点。我将它们设置为根节点、叶子节点或父节点。我按照以下方式设置它们:
我的所有声明都是全局的:
private ResultSet myResultSet;
protected DefaultTreeModel treeModel;
private DefaultMutableTreeNode rootNode,childNode,parent1,parent2;

这是我设置节点的方式:
myResultSet=rtnNodes(); /*Method that returns a RS with my nodes*/
while(myResultSet.next()){
  switch(myResultSet.getInt(1)){  /*The first column is the type of node: root, parent, leaf...*/
    case 0: treeModel = new DefaultTreeModel((rootNode=new DefaultMutableTreeNode(myResultSet.getString(2)))); break;  /*root node*/
    case 1: case 4: parent1 = parent2 = makeNode(rootNode); break;  /*parent node*/
    case 2: makeNode(parent2); break;  /*leaf node*/
    case 3: parent2 = makeNode(parent1); break;  /*sub patern node*/
  } /*makeNode is the method where I create the nodes*/
}
makeNode 方法如下所示:
public DefaultMutableTreeNode makeNode(DefaultMutableTreeNode parent){
  //The second column in the RS is the name of the node
  treeModel.insertNodeInto((childNode=new DefaultMutableTreeNode(myResultSet.getString(2))),parent,parent.getChildCount());
  return childNode;
}

在将我的节点填充到treemodel之后,我将模型设置为我的JTree:
myJTree.setModel(treeModel);
myJTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

但是问题出现在我尝试设置图标的时候。我创建了一个名为MyTreeRenderer的子类,并使用了以下代码:
myJTree.setCellRenderer(new MyTreeRenderer());

但它没有按照我想要的方式设置图标,子类如下:
private ImageIcon root,parent,leaf;

public MyTreeRenderer() {
   root=setIcons(2);  /*setIcons is a method that I dont publish in this post, that helps me to set the path of the icons*/
   parent=setIcons(3);
   leaf=setIcons(4);
}

@Override
public Component getTreeCellRendererComponent(JTree tree,Object value,boolean selected,boolean expanded,boolean leaf,int row,boolean hasFocus){               
   super.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,hasFocus);
   DefaultMutableTreeNode nodo = (DefaultMutableTreeNode)value;
   TreeNode t = nodo.getParent();
   if(t!=null){
      setIcon(root);
   }
   return this;
}

如何在不使用节点名称的情况下为每个节点设置图标?子类的代码会将所有节点都设置为相同的图标,并且每次在jtree中选择一个节点时,都会运行getTreeCellRendererComponent方法,我不希望这样。
2个回答

25

您可以在不使用自定义渲染器的情况下更改JTree节点图标的默认UI值:

URL resource = logaff.class.getResource(IMAGE);
Icon icon = new ImageIcon(resource);

UIManager.put("Tree.closedIcon", icon);
UIManager.put("Tree.openIcon", icon);
UIManager.put("Tree.leafIcon", icon);

或者使用类似下面这样的东西:

@Override
public Component getTreeCellRendererComponent(JTree tree,
    Object value, boolean selected, boolean expanded,
    boolean leaf, int row, boolean hasFocus) {
        super.getTreeCellRendererComponent(tree, value, selected,expanded, leaf, row, hasFocus);
        DefaultMutableTreeNode nodo = (DefaultMutableTreeNode) value;
        if (tree.getModel().getRoot().equals(nodo)) {
            setIcon(root);
        } else if (nodo.getChildCount() > 0) {
            setIcon(parent);
        } else {
            setIcon(leaf);
        }
        return this;
}

还可以阅读关于Swing JTable和JTree的渲染机制的内容。


1
哇!我已经寻找了两个星期的答案,我和一个朋友一直在阅读,但是一直感到困惑。简单地看代码是完美的,我会测试它,然后告诉你它的工作原理。 非常感谢你的帮助!!! - Vlad
很棒的解决方案!图标大小是16x16像素²还是其他尺寸? - Sam Ginrich

8
你可以使用一个简短的方式,"tree"是我的JTree组件。
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree.getCellRenderer();
Icon closedIcon = new ImageIcon("closed.png");
Icon openIcon = new ImageIcon("open.png");
Icon leafIcon = new ImageIcon("leaf.png");
renderer.setClosedIcon(closedIcon);
renderer.setOpenIcon(openIcon);
renderer.setLeafIcon(leafIcon);    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接