软件开发

当前位置:首页 > 软件开发

《Java核心技术高级特性》(第六章)(续)

6.3.3绘制节 点

在应用中可能会经常需要改变树构件绘制节点的方式,最常见的改变当然是为节点和叶节点选取不同的图标,其他一些改变可能涉及节点标签的字体或节点上的图像绘制等方面。所有这些改变都可以通过向树中安装-个新的树单元格绘制器来实现。在默认情况下,JTree 类使用DefaultTreeCel IRenderer对象来绘制每个节点。DefaultTreeCe11Renderer 类继承自JLabe1类,该标签包含节点图标和节点标签。

目注意:单元格绘制器并不能绘制用于展开或折叠子树的“把手”图标。这些把手是外观模式的一部分,建议最好不要试图改变它们。

可以通过以下三种方式定制显示外观:

●可以使用DefaultTreeCellRenderer改变图标、字体以及背景颜色。这些设置适用于树中所有节点。

●可以安装- -个继承了Defau1 tTreeCe11Renderer类的绘制器,用于改变每个节点的图标、字体以及背景颜色。

●可以安装-一个实现了TreeCe1 1Renderer接口的绘制器,为每个节点绘制自定义的图像。

让我们逐个研究这几种可能。最简单的定制方法是构建-一个 DefaultTreeCellRenderer对象,改变图标,然后将它安装到树中:

DefutTreelRenderer renderer = new DefultTelRenderer0;
renderer. setLeafIcon(new InagelonC"bu-6al19if)); // used for leaf nodes
renderer. setClosedIcon(new ImageIcon(" red-bal1.gifr)); // used for collapsed nodes
renderer. setOpenIcon(new InagleIm("l1l1o-all.gig1)); // used for expanded nodes
tresetCel1Renderer(renderer);

可以在图6-32中看到运行效果。我们只是使用“球”图标作为占位符,这里假设你的用户界面设计者会为你的应用提供合适的图标。

我们不建议改变整棵树中的字体或背景颜色,因为这实际上是外观设置的职责所在。

不过,改变树中个别节点的字体,以突显某些节点还是很有用的。如果仔细观察图6-32,你会看到抽象类是设成斜体字的。

为了改变单个节点的外观,需要安装一个树单元格绘制 器。树单元格绘制器与我们在本章前一节讨论的列表单元格绘制器很相似。TreeCel1Renderer接口只有下面这个单一方法:

Component getreel1RendererComponent(JTree tree, 0bject value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus)

DefaultTreeCe1 1Renderer类的getTreeCe1 1RendererComponent方法返回的是this,换句话说,就是一个标签( DefaultTreeCel1Renderer类继承了JLabe1 类)。如果要定制一个构件,需要继承DefaultTreeCel1Renderer类。按照以下方式覆盖getTreeCellRendererComponent方法:调用超类中的方法,以便准备标签的数据,然后定制标签属性,最后返回this。

class MrTeel1Renderer extends DfultTeelRenderer
{
public Component grtreelRendererComponent(JTree tree, 0bject value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus)
Component comp = srere.erteeelRenererComomentree value, selected,
expanded, 1eaf, rom, hasFocus);
Defaul tMutableTreeNode node = (DefaultMutablereeNode) value;
1ook at node.gtUser0bject0;
Font font = appropriate font;
comp.setFont(font);
return comp;
}
};

❹警告: getTreeCe11 RendererComponent方法的value参数是节点对象,而不是用户对象!请记住,用户对象是Defau1 tMutab1 eTreeNode的一个特性,而JTree可以包含任意类型的节点。如果树使用的是Def aultMutableTreeNode节点,那么必须在第二个步骤中获取这个用户对象,正如我们在上一个代码示例中所做的那样。

❹警告: DefaultTreeCe11Renderer 为所有节点使用的是相同的标签对象,仅仅是为每个节点改变标签文本而已。如果想为某个特定节点更改字体,那么必须在该方法再次调用的时候将它设置回默认值。否则,随后的所有节点都会以更改过的字体进行绘制!见程序清单6-14中的程序代码,看看它是怎样将字体恢复到其默认值的。

我们没有给出有关用来绘制任意图形的树单元格绘制器的示例。如果你需要这个功能,可以参考程序清单6-4中的列表单元格绘制器;它们用到的技术完全相似。

根据Class对象有无ABSTRACT修饰符,程序清单6-14中的C1 assNameTreeCel 1Renderer将类名设置为标准字体或斜体字体。我们不想设置成特殊的字体,因为我们不想改变通常用于显示标签的任何字体外观。因此,我们使用来自于标签本的字体以及从它衍生而来的- -

个斜体字体。请回忆- -下,全部的调用只返回一个共享的单- -的JLabel对象。因此,我们需要保存初始字体,并在下一次调用gettreeCe1 1RendererC omponent方法时将其恢复为初始值。

同时,注意- -下我们是如何改变C1assTreeF r ame构造器中的节点图标的。

API javax.swing.tree DefaultMutableTreeNode 1.2

●Enumeration breadthF irs tEnumeration( )

●Enumeration depthF irstEnumeration( )

●Enumeration pre0rderEnumeration( )

●Enumerati on pos torderEnumerati on( )

返回枚举对象,用于按照某种特定顺序访问树模型中所有节点的。在广度优先遍历中,

先访问离根节点更近的子节点,再访问那些离根节点远的节点。在深度优先遍历中,

先访问-一个节点的所有子节点,然后再访问它的兄弟节点。postOrderEnumeration

方法与depthF irstEnumeration基本上相似。除了先访问父节点,后访问子节点之

外,先序遍历和后序遍历基本上-样。

API javax. swing.tree. TreeCelRenderer 1.2

●Component getTreeCe1 1 RendererC omponent(JTree tree, object value,

boolean selected, boolean expanded, boolean 1eaf, int row, boolean

hasF ocus )

返回一个paint方法被调用的构件,以便绘制树的一个单元格。

参数: tree

包含要绘制节点的树

value .

要绘制的节点

se1 ected

如果该节点是当前选定的节点,则为true

expanded

如果该节点的子节点可见,则为true

1eaf

如果该节点应该显示为叶节点,则为true

row

显示包含该节点的那行

hasF ocus

如果当前选定的节点拥有输人焦点,则为true

API javax. swing .tree. DefaultTreeCellRenderer 1.2

●void setL eafIcon( Icon icon )

●void setopenIcon( Icon 1 con)

●void setC1osedIcon(Icon icon)

设置叶节点、展开节点以及折叠节点的显示图标。


相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~