12.10.6 实现TreeCellRenderer改变节点外观
这种方式是最灵活的方式,程序实现TreeCellRenderer
接口时同样需要实现getTreeCellRendererComponent()
方法,该方法可以返回任意类型的组件,该组件将作为JTree
的节点。通过这种方式可以最大程度地改变JTree
的节点外观。
与前面实现ListCellRenderer
接口类似的是,本实例程序同样通过扩展JPanel
来实现TreeCellRenderer
,实现TreeCellRenderer
的方式与前面实现ListCellRenderer
的方式基本相似,所以读者将会看到一个完全不同的JTree
程序 实现TreeCellRenderer改变节点外观
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
| import java.awt.*; import javax.swing.*; import javax.swing.tree.*;
public class CustomTreeNode { JFrame jf = new JFrame("定制树的节点"); JTree tree; DefaultMutableTreeNode friends = new DefaultMutableTreeNode("我的好友"); DefaultMutableTreeNode qingzhao = new DefaultMutableTreeNode("李清照"); DefaultMutableTreeNode suge = new DefaultMutableTreeNode("苏格拉底"); DefaultMutableTreeNode libai = new DefaultMutableTreeNode("李白"); DefaultMutableTreeNode nongyu = new DefaultMutableTreeNode("弄玉"); DefaultMutableTreeNode hutou = new DefaultMutableTreeNode("虎头");
public void init() { friends.add(qingzhao); friends.add(suge); friends.add(libai); friends.add(nongyu); friends.add(hutou); tree = new JTree(friends); tree.setShowsRootHandles(true); tree.setRootVisible(true); tree.setCellRenderer(new ImageCellRenderer()); jf.add(new JScrollPane(tree)); jf.pack(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); }
public static void main(String[] args) { new CustomTreeNode().init(); } }
class ImageCellRenderer extends JPanel implements TreeCellRenderer { private ImageIcon icon; private String name; private Color background; private Color foreground;
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { icon = new ImageIcon("icon/" + value + ".gif"); name = value.toString(); background = hasFocus ? new Color(140, 200, 235) : new Color(255, 255, 255); foreground = hasFocus ? new Color(255, 255, 3) : new Color(0, 0, 0); return this; }
public void paintComponent(Graphics g) { int imageWidth = icon.getImage().getWidth(null); int imageHeight = icon.getImage().getHeight(null); g.setColor(background); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(foreground); g.drawImage(icon.getImage(), getWidth() / 2 - imageWidth / 2, 10, null); g.setFont(new Font("SansSerif", Font.BOLD, 18)); g.drawString(name, getWidth() / 2 - name.length() * 10, imageHeight + 30); }
public Dimension getPreferredSize() { return new Dimension(80, 80); } }
|
上面程序中的粗体字代码设置JTree
对象使用定制的节点绘制器:ImageCellRenderer
,该节点绘制器实现了TreeCellRenderer
接口的getTreeCellRendererComponent()
方法,该方法返回thi
,也就是一个特殊的JPanel
对象,这个特殊的JPanel
重写了paintComponent()
方法,重新绘制了JPanel
的外观—根据节点数据来绘制图标和文本。运行上面程序,会看到如图12.46所示的树。
这看上去似乎不太像一棵树,但可从每个节点前的连接线、表示节点的展开/折叠的图标中看出这依然是一棵树。