前面已经把树的基本使用、树的事件和树的数据取得写完了,并看了一个Sun提供的最简单的树的例子,这一专题我们讲两个方面,一个是使用树的Renderer和Editor构造一棵我们自己的树;一个树使用SwingWorker完成一棵资源管理器树的加载.
先看渲染的例子:
我们为我们的树增加了可用与否、可见与否和节点图片的属性,当然你也可以自己添加想要的属性,比如顺序等.
整个实现的过程很清晰,也不复杂,我们首先实现我们自己的TreeNode,它继承于DefaultMutableTreeNode,我们在里面添加自己的属性;然后是实现树的节点的Renderer和Editor,在Renderer里我们设置可用也否,选择状态,节点图片等;在Editor里我们设置树的容器布局.最后构造树时使用setRenderer和setEditor就可以了,需要注意的是如果仅仅是呈现,设置Renderer就可以了,如果除了呈现还有操作的话,必须都要设置.
先看我们自己的TreeNode类, 继承于DefaultMutableTreeNode,
/**
* the tree node that I rewrite it.
*/
publicclass MyTreeNode extends DefaultMutableTreeNode {
我们添加了属性:
/** is select or not. */
privatebooleanisSelected = false;
节点的选择状态
/** is enable. */
privatebooleanenabled = false;
节点使用与否
/** is visible or not. */
privatebooleanisVisible = false;
节点可见与否
/** it's icon. */
private Icon icon = null;
/** icon name. */
private String iconName = null;
节点图片和图片名字
然后是构造函数,我们初始化属性,或使用默认的:
public MyTreeNode() {
this(null, true, false, true, true, null);
}
public MyTreeNode(Object userObject, boolean allowsChildren,
boolean isSelected, boolean enabled, boolean isVisible, Icon icon) {
super(userObject, allowsChildren);
this.isSelected = isSelected;
this.enabled = enabled;
this.isVisible = isVisible;
this.icon = icon;
setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTI
ON);
}
然后就是一些设置和取得属性的方法,这个类就相当于一个Bean.
然后就是Rnederer了,我们这里继承于DefaultTreeCellRenderer
publicclass MyTreeRenderer extends DefaultTreeCellRenderer {
然后复写它的getTreeCellRendererComponent方法:
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
然后设置节点的属性:
首先是显示文本:
String stringValue = tree.convertValueToText(value, sel, expanded, leaf, row, hasFocus);
setText(stringValue);
然后是可用与否:
boolean nodeIsEnabled = ((MyTreeNode) value).isEnabled();
boolean isEnabled = (treeIsEnabled && nodeIsEnabled);
setEnabled(isEnabled);
然后是是图片
Icon icon = ((MyTreeNode) value).getIcon();
setIcon(icon);
还有一些基本的属性,比如背景色等:
setForeground(getTextSelectionColor());
再来需要看的类就是Editor了,它继承于DefaultTreeCellEditor:
publicclass MyCellEditor extends DefaultTreeCellEditor {
因为我们使用的是JLabel作为显示控件,所以我们的主要实现是布局处理,对于事件可以不需要考虑.我们复习了DefaultTreeCellEditor的默认布局:
/**
* Container responsible for placing the editingComponent.
*/
privateclass MyEditorContainer extends
DefaultTreeCellEditor.EditorContainer {
复写它的doLayout方法:
@Override
publicvoid doLayout() {
取得节点的边缘和大小:
r = tree.getBounds(r);
eSize.width = r.width - (offset * n);
editingComponent.setLocation(offset, 0);
设置节点的位置和大小:
setSize(new Dimension(eSize.width + offset, cSize.height));
最后就是使用了,很简单和以前一样,直接使用JTree的设置方法就可以了:
MyTreeRenderer renderer = new MyTreeRenderer();
tree.setCellRenderer(renderer);
tree.setEditable(true);
tree.setCellEditor(new MyCellEditor(tree,
(DefaultTreeCellRenderer) tree.getCellRenderer()));