我创建了一个JTree,即使有多个根节点(这对我来说很难,因为它是我的第一个JTree),并且已经准备好(我想)更进一步;一个细胞去世者。
我尝试为每个节点设置一个图标,它工作正常。现在我正在尝试检查它是什么类型的节点(不仅是叶子和分支),并构建我想要的图像的文件名的字符串。 isKlas()
现在总是返回true,所以应该是klas_fold.png或klas_unfold.png。但getTreeCellRendererComponent()
仅部分执行,因为文件路径永远不会打印,也没有更改任何图标,它始终是默认值!
这是我的代码:
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
public class RATree extends JTree {
private static final long serialVersionUID = -3855798479619346917L;
public RATree(Object[] top) {
super(top);
MyRenderer renderer = new MyRenderer();
this.setCellRenderer(renderer);
setBorder(BorderFactory.createRaisedBevelBorder());
}
protected ImageIcon createImageIcon(String path) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
class MyRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
TreeItem node;
String fileName = "";
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
try {
node = (TreeItem) value;
}
catch (ClassCastException ex)
{
ex.printStackTrace();
return this;
}
if(node.isKlas()) {
fileName += "klas_";
}
if(expanded) {
fileName += "unfold.png";
this.setIcon(createImageIcon("../bin/" + fileName));
}
else {
fileName += "fold.png";
this.setIcon(createImageIcon("../bin/" + fileName));
}
System.out.println("fileName: " + fileName); //Doesn't get executed, or at least, I can't see it.
return this;
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Short, Self Contained, Correct (Compilable), Example");
Object[] root = {new TreeItem("name", "someURL"), new TreeItem("name", "someUrl")};
f.add(new RATree(root));
f.setSize(100,100);
f.setVisible(true);
}
}
是的,这是一个内部阶级。
谢谢!
修改
我发现这是一个让事情搞砸的ClassCastException。但这很奇怪,因为我像这样初始化树:new JTree({new TreeItem("params"), new TreeItem("params")});
。所以我应该能够将它们从Object转换回TreeItem? (TreeItem是我的一个类。它扩展了DefaultMutableTreeNode)。
答案 0 :(得分:4)
1)您是否尝试通知TreeModel TreeModel.nodeChanged(node);
值已更改
2)将Icon(s)
直接放到TreeModel上,而不是在TreeCellRenderer
内重新创建
3)来自JTree
的{{1}}(JTable
,JList
和JList
}分享相同的concept as Renderer for JTable
答案 1 :(得分:4)
我自己解决了!我认为Object value
是我放在JTree中的TreeItem,但它是另一回事。我通过这样做得到了TreeItem(就像在mKorbel提供的自定义树的显示链接中一样):
TreeItem node = (TreeItem) ((DefaultMutableTreeNode)value).getUserObject();
答案 2 :(得分:2)
我很高兴你找到了try-catch部分。要解决此问题,请确保您没有提供除TreeItem实例之外的任何其他DefaultTreeModel。您应该将此行System.out.println(value.getClass())
放在catch块中。
此外,您应该考虑创建一个图标实例,而不是每次展开或折叠树节点时都创建一个新实例。