12.10.4 使用DefaultTreeCellRenderer改变节点外观

12.10.4 使用DefaultTreeCellRenderer改变节点外观

对比图12.38和图12.41所示的两棵树,不难发现图12.38所示的树更美观,因为图12.38所示的树节点的图标非常丰富,而图12.41所示的树节点的图标太过于单一
实际上,JTree也可以改变树节点的外观,包括改变节点的图标、字体等,甚至可以自由绘制节点外观。为了改变树节点的外观,可以通过为树指定自己的CellRenderer来实现,JTree默认使用DefaultTreeCelIRenderer来绘制每个节点。DefaultTreeCellRendererJLabel的子类,该JLabel包含了该节点的图标和文本。

如何改变树节点的外观样式

改变树节点的外观样式,可以有如下三种方式。

  1. 使用DefaultTreeCellRenderer直接改变节点的外观,这种方式可以改变整棵树所有节点的字体颜色和图标
  2. JTree指定DefaultTreeCellRenderer的扩展类对象作为JTree的节点绘制器,该绘制器负责为不同节点使用不同的字体、颜色和图标。通常使用这种方式来改变节点的外观。
  3. JTree指定一个实现TreeCellRenderer接口的节点绘制器,该绘制器可以为不同的节点自由绘制任意内容,这是最复杂但最灵活的节点绘制器。

使用DefaultTreeCellRenderer直接改变节点的外观

第一种方式最简单,但灵活性最差,因为它会改变整棵树所有节点的外观。在这种情况下,JTree的所有节点依然使用相同的图标,相当于整体替换了JTree中节点的所有默认图标。用户指定的节点图标未必就比JTree默认的图标美观。

DefaultTreeCellRenderer提供了如下几个方法来修改节点的外观

  • setBackgroundNonSelectionColor(ColorNewColor:设置用于非选定节点的背景颜色。
  • setBackgroundSelection Color( Color new Color):设置节点在选中状态下的背景颜色。
  • set Selection Color( Color newColor):设置选中状态下节点的边框颜色。
  • setclosedIcon( Icon newIcon):设置处于折叠状态下非叶子节点的图标。
  • setFont( Font font):设置节点文本的字体。
  • setleaficon( Icon newSon):设置叶子节点的图标。
  • setOpenIcon( con newson):设置处于展开状态下非叶子节点的图标。
  • settextNon Selection color( Color new Color):设置绘制非选中状态下节点文本的颜色
  • set TextSelection Color( Color new Color):设置绘制选中状态下节点文本的颜色

程序 直接使用DefaultTreeCellRenderer来改变树节点的外观

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class ChangeAllCellRender {
JFrame jf = new JFrame("改变所有节点的外观");
JTree tree;
// 定义几个初始节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
DefaultMutableTreeNode guangdong = new DefaultMutableTreeNode("广东");
DefaultMutableTreeNode guangxi = new DefaultMutableTreeNode("广西");
DefaultMutableTreeNode foshan = new DefaultMutableTreeNode("佛山");
DefaultMutableTreeNode shantou = new DefaultMutableTreeNode("汕头");
DefaultMutableTreeNode guilin = new DefaultMutableTreeNode("桂林");
DefaultMutableTreeNode nanning = new DefaultMutableTreeNode("南宁");

public void init() {
// 通过add()方法建立树节点之间的父子关系
guangdong.add(foshan);
guangdong.add(shantou);
guangxi.add(guilin);
guangxi.add(nanning);
root.add(guangdong);
root.add(guangxi);
// 以根节点创建树
tree = new JTree(root);
// 创建一个DefaultTreeCellRender对象
DefaultTreeCellRenderer cellRender = new DefaultTreeCellRenderer();
// 设置非选定节点的背景色。
cellRender.setBackgroundNonSelectionColor(new Color(220, 220, 220));
// 设置节点在选中状态下的背景颜色。
cellRender.setBackgroundSelectionColor(new Color(140, 140, 140));
// 设置选中状态下节点的边框颜色。
cellRender.setBorderSelectionColor(Color.BLACK);
// 设置处于折叠状态下非叶子节点的图标。
cellRender.setClosedIcon(new ImageIcon("icon/close.gif"));
// 设置节点文本的字体。
cellRender.setFont(new Font("SansSerif", Font.BOLD, 16));
// 设置叶子节点的图标。
cellRender.setLeafIcon(new ImageIcon("icon/leaf.png"));
// 设置处于展开状态下非叶子节点的图标。
cellRender.setOpenIcon(new ImageIcon("icon/open.gif"));
// 设置绘制非选中状态下节点文本的颜色。
cellRender.setTextNonSelectionColor(new Color(255, 0, 0));
// 设置绘制选中状态下节点文本的颜色。
cellRender.setTextSelectionColor(new Color(0, 0, 255));
tree.setCellRenderer(cellRender);
// 设置是否显示根节点的“展开/折叠”图标,默认是false
tree.setShowsRootHandles(true);
// 设置节点是否可见,默认是true
tree.setRootVisible(true);
jf.add(new JScrollPane(tree));
jf.pack();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}

public static void main(String[] args) {
new ChangeAllCellRender().init();
}
}

上面程序中的粗体字代码创建了一个DefaultTreeCellRenderer对象,并通过该对象改变了JTree中所有节点的字体、颜色和图标。运行上面程序,会看到如图12.44所示的效果。

从图12.44中可以看出,JTree中的所有节点全部被改变了,相当于完全替代了JTree中所有节点的默认图标、字体和颜色。但所有的叶子节点依然保持相同的外观,所有的非叶子节点也保持相同的外观。这种改变依然不能满足更复杂的需求,例如,如果需要不同类型的节点呈现出不同的外观,则不能直接使用DefaultTreeCellRenderer来改变节点的外观,可以采用扩展DefaultTreeCellrenderer的方式来实现该需求

如何修改展开折叠图标

不要试图通过TreeCellRenderer来改变表示节点展开/折叠的图标,因为该图标是由Metal风格决定的。如果需要改变该图标,则可以考虑改变该JTree的外观风格