12.10.5 扩展DefaultTreeCellRenderer改变节点外观
DefaultTreeCellRenderer
实现类实现了TreeCellRenderer
接口,该接口里只有一个负责绘制JTree
节点的
getTreeCellRendererComponent()
方法:
方法 |
描述 |
Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) |
Sets the value of the current tree cell to value. |
如果读者还记得前面介绍的绘制JList
的列表项外观的内容,应该对该方法非常熟悉,与Listcellrenderer
接口类似的是,getTreeCellRendererComponent()
方法返回一个Component
对象,该对象就是JTree
的节点组件。
DefaultTreeCellRenderer
类继承了JLabel
,实现getTreeCellRendererComponent
方法时返回this
,即返回一个特殊的JLabel
对象。如果需要根据节点内容来改变节点的外观,则可以再次扩展DefaultTreeCellRenderer
类,并再次重写它提供的getTreeCellRendererComponent
方法。
程序 数据库对象导航树
下面程序模拟了一个数据库对象导航树,程序可以根据节点的类型来绘制节点的图标。在本程序中为了给每个节点指定节点类型,程序不再使用String
作为节点数据,而是使用NodeData
来封装节点数据,并重写了NodeData
的toString
方法。
使用Object
类型的对象来创建TreeNode
对象时,DefaultTreeCellRenderer
默认使用该对象的toString
方法返回的字符串作为该节点的标签。
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| import java.awt.*; import javax.swing.*; import javax.swing.tree.*;
public class ExtendsDefaultTreeCellRenderer { JFrame jf = new JFrame("根据节点类型定义图标"); JTree tree; DefaultMutableTreeNode root = new DefaultMutableTreeNode(new NodeData(DBObjectType.ROOT, "数据库导航")); DefaultMutableTreeNode salaryDb = new DefaultMutableTreeNode(new NodeData(DBObjectType.DATABASE, "公司工资数据库")); DefaultMutableTreeNode customerDb = new DefaultMutableTreeNode(new NodeData(DBObjectType.DATABASE, "公司客户数据库")); DefaultMutableTreeNode employee = new DefaultMutableTreeNode(new NodeData(DBObjectType.TABLE, "员工表")); DefaultMutableTreeNode attend = new DefaultMutableTreeNode(new NodeData(DBObjectType.TABLE, "考勤表")); DefaultMutableTreeNode contact = new DefaultMutableTreeNode(new NodeData(DBObjectType.TABLE, "联系方式表")); DefaultMutableTreeNode id = new DefaultMutableTreeNode(new NodeData(DBObjectType.INDEX, "员工ID")); DefaultMutableTreeNode name = new DefaultMutableTreeNode(new NodeData(DBObjectType.COLUMN, "姓名")); DefaultMutableTreeNode gender = new DefaultMutableTreeNode(new NodeData(DBObjectType.COLUMN, "性别"));
public void init() { root.add(salaryDb); root.add(customerDb); salaryDb.add(employee); salaryDb.add(attend); customerDb.add(contact); employee.add(id); employee.add(name); employee.add(gender); tree = new JTree(root); tree.setCellRenderer(new MyRenderer()); tree.setShowsRootHandles(true); tree.setRootVisible(true); try { UIManager.setLookAndFeel("com.sun.java.swing.plaf." + "windows.WindowsLookAndFeel"); } catch (Exception ex) { } SwingUtilities.updateComponentTreeUI(tree); jf.add(new JScrollPane(tree)); jf.pack(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); }
public static void main(String[] args) { new ExtendsDefaultTreeCellRenderer().init(); } }
class NodeData { public int nodeType; public String nodeData;
public NodeData(int nodeType, String nodeData) { this.nodeType = nodeType; this.nodeData = nodeData; }
public String toString() { return nodeData; } }
interface DBObjectType { int ROOT = 0; int DATABASE = 1; int TABLE = 2; int COLUMN = 3; int INDEX = 4; }
class MyRenderer extends DefaultTreeCellRenderer { ImageIcon rootIcon = new ImageIcon("icon/root.gif"); ImageIcon databaseIcon = new ImageIcon("icon/database.gif"); ImageIcon tableIcon = new ImageIcon("icon/table.gif"); ImageIcon columnIcon = new ImageIcon("icon/column.gif"); ImageIcon indexIcon = new ImageIcon("icon/index.gif");
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); DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; NodeData data = (NodeData) node.getUserObject(); ImageIcon icon = null; switch (data.nodeType) { case DBObjectType.ROOT: icon = rootIcon; break; case DBObjectType.DATABASE: icon = databaseIcon; break; case DBObjectType.TABLE: icon = tableIcon; break; case DBObjectType.COLUMN: icon = columnIcon; break; case DBObjectType.INDEX: icon = indexIcon; break; } this.setIcon(icon); return this; } }
|
上面的程序中码强制JTree
使用自定义的节点绘制器:MyRenderer
,该节点绘制器继承了DefaultTreeCellRenderer
类,并重写了getTreeCellRendererComponent()
方法。该节点绘制器重写该节点时根据节点的nodeType
属性改变其图标。运行上面程序,会看到如图12.45所示的效果。
从图12.45中可以看出,JTree
中表示节点展开、折叠的图标已经改为了“+”和“-”,这是因为本程序强制JTree
使用了Windows
风格。