要想JTree显示带图片的节点,其目的就是改变JTree的渲染器,也就是调用JTree中setCellRenderer(TreeCellRenderer x),而默认的DefaultTreeCellRenderer没有这个功能,于是我就去继承这个类并重写它的getTreeCellRendererComponent方法,示例如下:
步骤一,继承DefaultTreeCellRenderer类并重写方法(当然这一步可以写在最后):
import java.awt.Component;
import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
public class IconNodeRendereer extends DefaultTreeCellRenderer {
private static final long serialVersionUID = -3494723715969483744L;
//下面这个方法重写请自己查看API各个参数的意思
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);
//IconTreeNode是重写的继承DefaultMutableTreeNode的带图片的节点
Icon icon = ((IconTreeNode) value).getIcon();
//StringValue是value调用toString()后的转来的描述性文字,所以在节点中包装的对象应自己重写toString方法来实现自己想要的结果
String stringValue = tree.convertValueToText(value, sel, expanded, leaf, row, hasFocus);
//为什么可以设置图片和文字?因为DefaultTreeCellRenderer继承了JLabel它的渲染结果就是可以显示图片和文字,当然如果自己想要也可以显示超链接(这个在此不描述,后来再补上在JLabel上实现超链接)
setText(stringValue);
setIcon(icon);
return this;
}//end of getTreeCellRendererComponent
}
步骤二:节点封装对象的描写
public class User {
private String name;
private Icon icon;
//ImageManager是我自己写的一个用来获取Icon的类,这个你可以不管,只要穿进去的参数是Icon就可以了
public static final Icon defaultIcon = ImageManager.getIcon("Cat.png");
public User( String name, Icon icon) {
super();
this.name = name;
this.icon = icon;
}
public User(String name){//对于没有传Icon的就赋予默认Icon
this(name,defaultIcon);
}
public String toString() {//重写自己的toString方法
//由于TreeCellRenderer extends JLabel所以可以使用html标签用来修饰,以至于在JTree中显示自己预设文字的效果
return "<html><br/><strong><font color='red'>"+getName()+"</font></strong></html>";
}
public Icon getIcon() {
return icon;
}
public void setIcon(Icon icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
步骤三:节点的封装,是继承DefaultMutableTreeNode
import javax.swing.Icon;
public class IconTreeNode extends DefaultMutableTreeNode {
private static final long serialVersionUID = -8044774991176225332L;
protected Icon icon;
protected User user;
public IconTreeNode(User user) {//包装对象为User实例的结点的构造方法
this(user, true);
}
public IconTreeNode(User user, boolean allowsChildren) {//allowsChildren也就是准不准许有孩子节点
super(user, allowsChildren);
this.user = user;
this.icon = user.getIcon();
}
public void setIcon(Icon icon) {
this.icon = icon;
}
public Icon getIcon() {
return icon;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
步骤四:测试类的实现
import java.awt.BorderLayout;
public class IconTreeTest extends JFrame{
private static final long serialVersionUID = 6808299663145549457L;
private JTree tree;
private JPanel pnlMain = new JPanel();
private JButton btnAdd = new JButton("添加叶子");
private DefaultTreeModel treeModel=null;
private DefaultMutableTreeNode nodeRoot = new DefaultMutableTreeNode("all");
public IconTreeTest(){
init();
}//end of constructor
public void init() {
pnlMain.setLayout(new BorderLayout());
//先创建User实例
User user1 = new User("Andy",ImageManager.getIcon("girl01.png"));
User user2 = new User("花花",ImageManager.getIcon("stoneman.png"));
//将User实例封装成TreeNode
IconTreeNode node1 = new IconTreeNode(user1);
IconTreeNode node2 = new IconTreeNode(user2);
nodeRoot.add(node1);
nodeRoot.add(node2);
//下面构造JTree
tree = new JTree(nodeRoot);
//设置根Root不可见
tree.setRootVisible(false);
//设置渲染器
DefaultTreeCellRenderer ceeRender = new IconNodeRendereer();
tree.setCellRenderer(ceeRender);
//下面这一行获取JTree的模型,为了在JButton中实现动态添加而预设的,也可以在JButton的事件响应中再写
treeModel=(DefaultTreeModel)tree.getModel();
pnlMain.add(tree);
pnlMain.add(btnAdd,BorderLayout.SOUTH);
setContentPane(pnlMain);
setSize(400,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//添加事件监听实现动态添加节点
btnAdd.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
User newUser;
//ImageManager这个类请看User中的说明,这个是自己实现的,只要能获取到Icon就可以了
newUser = new User("Andy",ImageManager.getIcon("greenman.png"));
IconTreeNode newNode = new IconTreeNode(newUser);
treeModel.insertNodeInto(newNode,nodeRoot,nodeRoot.getChildCount());
}
});
}//end of init()
public static void main(String[] args){
IconTreeTest test = new IconTreeTest();
test.setLocationRelativeTo(null);
test.setVisible(true);
}
}
=====================================================================上面分了4个类文件,渲染器自己就写得很简单,是因为想要的功能就这么多--------显示图片,上面的功能就算完成了,给大家参考。