用纯java自定义自己的树形菜单
small_ding的专栏
<o:p></o:p>
<o:p> </o:p>
1.定义每个树节点信息的类<o:p></o:p>
package BSC.tree;
import java.io.*;
import java.util.*;
/**
* <p>一个树节点对像 </p>
* <p>构造一个树节点对像 </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>上海佳杏 </p>
* @author 丁小龙
* @version 1.0
*/
<o:p> </o:p>
public class clsTreeNode implements Serializable {
/**<o:p></o:p>
* 根据指定参数构造一个新的 clsTreeNode 节点<o:p></o:p>
*<o:p></o:p>
* @param name 节点内在名字 (在整个棵树中必须是唯一的)<o:p></o:p>
* @param icon 节点可见时相对于图像目录的完整图橡文件的路径名<o:p></o:p>
* @param label 节点可见时的标签内容<o:p></o:p>
* @param action 当前所选择节点的对应的超级链接,若为空没有超级链接<o:p></o:p>
* @param target 超级链接所对应的窗口对象,若为空为当前窗口<o:p></o:p>
* @param expanded 节点是否展开?
*/
public clsTreeNode(String name,
String icon, String label,
String action, String target,
boolean expanded, String domain) {
<o:p> </o:p>
super();
this.name = name;
this.icon = icon;
this.label = label;
this.action = action;
this.target = target;
this.expanded = expanded;
this.domain = domain;
<o:p> </o:p>
}
protected String labelcolor="#0000FF";
public String getLabelColor()
{
return this.labelcolor;
}
public void setLabelColor(String color)
{
if(color!=null)
this.labelcolor=color;
}<o:p></o:p>
<o:p> </o:p>
// ----------------------------------------------------- 实体变量<o:p></o:p>
<o:p> </o:p>
<o:p> </o:p>
/**<o:p></o:p>
* 当前节点的子节点集,他们按一定的顺序显示, in the<o:p></o:p>
*/
protected Vector children = new Vector();
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
/**<o:p></o:p>
* 假如节点被选择将直接被超级链接所控制<o:p></o:p>
*/
protected String action = null;
<o:p> </o:p>
public String getAction() {
return (this.action);
}
<o:p> </o:p>
/**
* 节点的域.
*/
protected String domain = null;
<o:p> </o:p>
public String getDomain() {
return (this.domain);
}
<o:p> </o:p>
/**
* 节点当前是否被展开?
*/
protected boolean expanded = false;
<o:p> </o:p>
public boolean isExpanded() {
return (this.expanded);
}
<o:p> </o:p>
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
<o:p> </o:p>
<o:p> </o:p>
/**
*节点可见时相对于图像目录的完整图橡文件的路径名
*/
protected String icon = null;
<o:p> </o:p>
public String getIcon() {
return (this.icon);
}
<o:p> </o:p>
<o:p> </o:p>
/**
*节点可见时的标签内容.
*/
protected String label = null;
<o:p> </o:p>
public String getLabel() {
return (this.label);
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 是否当前父节点的子节点集中的最后一个节点
*/
protected boolean last = false;
<o:p> </o:p>
public boolean isLast() {
return (this.last);
}
<o:p> </o:p>
void setLast(boolean last) {
this.last = last;
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 是否为叶节点 ?
*/
public boolean isLeaf() {
synchronized (children) {
return (children.size() < 1);
}
}
<o:p> </o:p>
public int getChildCount()
{
return children.size() ;
}
/**
*节点内在名字 (在整个棵树中必须是唯一的)
*/
protected String name = null;
<o:p> </o:p>
public String getName() {
return (this.name);
}<o:p></o:p>
<o:p> </o:p>
<o:p> </o:p>
/**<o:p></o:p>
* 当前节点的父节点,若为空为则为根节点.<o:p></o:p>
*/
protected clsTreeNode parent = null;
<o:p> </o:p>
public clsTreeNode getParent() {
return (this.parent);
}
<o:p> </o:p>
void setParent(clsTreeNode parent) {
this.parent = parent;
if (parent == null)
width = 1;
else
width = parent.getWidth() + 1;
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 节点当前是否被选择
*/
protected boolean selected = false;
<o:p> </o:p>
public boolean isSelected() {
return (this.selected);
}
<o:p> </o:p>
public void setSelected(boolean selected) {
this.selected = selected;
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 超级链接所对应的窗口对象,若为空为当前窗口
*/
protected String target = null;
<o:p> </o:p>
public String getTarget() {
return (this.target);<o:p></o:p>
}<o:p></o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
/**<o:p></o:p>
* 节点的可显示宽度(如果节点为可见的).<o:p></o:p>
* 如果节点不可见,则计算出的宽度为最直接的父节点<o:p></o:p>
*/
protected int width = 0;
<o:p> </o:p>
public int getWidth() {
return (this.width);
}
<o:p> </o:p>
<o:p> </o:p>
// --------------------------------------------------------- Public Methods
<o:p> </o:p>
<o:p> </o:p>
/**
* 添加一个新的子结点的<o:p></o:p>
*<o:p></o:p>
* @param child 新子节点
*
* @如果这个新子结点的名字不是唯一的则抛出 IllegalArgumentException 异常
*/
public void addChild(clsTreeNode child)
throws IllegalArgumentException {
<o:p> </o:p>
tree.addNode(child);
child.setParent(this);
synchronized (children) {
int n = children.size();
if (n > 0) {
clsTreeNode node = (clsTreeNode) children.get(n - 1);
node.setLast(false);
}
child.setLast(true);
children.add(child);
}
<o:p> </o:p>
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 通过指定位置加入一个子节点
*
* @param offset 相对0的位移
* @param child 欲加入的子节点
*
* @如果这个新子结点的名字不是唯一的则抛出 IllegalArgumentException 异常
*/
public void addChild(int offset, clsTreeNode child)
throws IllegalArgumentException {
<o:p> </o:p>
tree.addNode(child);
child.setParent(this);
synchronized (children) {
children.add(offset, child);
}
<o:p> </o:p>
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 返回子节点集
*/
public clsTreeNode[] findChildren() {
<o:p> </o:p>
synchronized (children) {
clsTreeNode results[] = new clsTreeNode[children.size()];
return ((clsTreeNode[]) children.toArray(results));
}
<o:p> </o:p>
}
/**
* 整棵树的描述对像
*/
protected clsTreeControl tree = null;
<o:p> </o:p>
public clsTreeControl getTree() {
return (this.tree);
}
<o:p> </o:p>
public void setTree(clsTreeControl tree) {
this.tree = tree;
}
<o:p> </o:p>
public void setLabel(String label) {
this.label = label;
}
<o:p> </o:p>
/**
*从树中移出自己
*/
public void remove() {
<o:p> </o:p>
if (tree != null) {
tree.removeNode(this);
}
<o:p> </o:p>
}
<o:p> </o:p>
<o:p> </o:p>
/**
* 从指定位置中删除一个子节点
* @param offset 基于0 存在位置
*/
public void removeChild(int offset) {
<o:p> </o:p>
synchronized (children) {
clsTreeNode child =
(clsTreeNode) children.get(offset);
tree.removeNode(child);
child.setParent(null);
children.remove(offset);
}
<o:p> </o:p>
}
<o:p> </o:p>
<o:p> </o:p>
// -------------------------------------------------------- Package Methods
<o:p> </o:p>
<o:p> </o:p>
/**
*删除指定子节点,但必须是存在的<o:p></o:p>
*
* @param child 要被删除的节点
*/
void removeChild(clsTreeNode child) {
<o:p> </o:p>
if (child == null) {
return;
}
synchronized (children) {
int n = children.size();
for (int i = 0; i < n; i++) {
if (child == (clsTreeNode) children.get(i)) {
children.remove(i);
return;
}
}
}
<o:p> </o:p>
}
<o:p> </o:p>
<o:p> </o:p>
}
2.定义控制树节点信息的类
ackage BSC.tree;
import java.io.Serializable;
import java.util.HashMap;
/**
* <p>一棵树的完整数据结构描述,它能通过clsDrawTree类来绘制</p>
* <p> 树的每个结点通过TreeControlNode类实例来描述</P>
* <p>Copyright: Copyright (c) 2003</p>
* <p>上海佳杏 </p>
* @author 丁小龙
* @version 1.0
*/
<o:p> </o:p>
public class clsTreeControl implements Serializable {
<o:p> </o:p>
<o:p> </o:p>
// ----------------------------------------------------------- 构造方法<o:p></o:p>
<o:p> </o:p>
<o:p> </o:p>
/**<o:p></o:p>
* 在没有预先确定的根节点构造一个新实体<o:p></o:p>
*/
public clsTreeControl() {
<o:p> </o:p>
super();
setRoot(null);
<o:p> </o:p>
}<o:p></o:p>
<o:p> </o:p>
<o:p> </o:p>
/**<o:p></o:p>
* 通过指定的根节点构造一个新实体<o:p></o:p>
*
* @param root 根节点
*/
public clsTreeControl(clsTreeNode root) {
<o:p> </o:p>
super();
setRoot(root);
<o:p> </o:p>
}
<o:p> </o:p>
<o:p> </o:p>
// ----------------------------------------------------- 实体变量
<o:p> </o:p>
<o:p> </o:p>
/**
*按键入的名字来描述这棵树的节点集合
*/
protected HashMap registry = new HashMap();
<o:p> </o:p>
<o:p> </o:p>
/**
* 最近被选择的节点
*/
protected clsTreeNode selected = null;
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>