用纯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>