部门关系的ext树的实现

通常我们利用ext树显示部门信息的时候,需要显示部门的关联关系或者是上下级关系,那么,我们就需要传给ext树固定格式的json,下面我们就进行json的拼装。

首先我们假定A部门是B部门的上级部门

我们利用面向对象的原理创建一个简单的树节点对象,如下:

package pojo;

/**
 * ext树节点
 * 
 * @author huang
 * 
 */
public class StoreTreeNode {

    private String id;

    private Boolean leaf = false;

    private String text;

    private String parentId;

    private Boolean expended = false;

    private Boolean checked = false;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Boolean getLeaf() {
        return leaf;
    }

    public void setLeaf(Boolean leaf) {
        this.leaf = leaf;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Boolean getExpended() {
        return expended;
    }

    public void setExpended(Boolean expended) {
        this.expended = expended;
    }

    public Boolean getChecked() {
        return checked;
    }

    public void setChecked(Boolean checked) {
        this.checked = checked;
    }

}

接着创建一个节点的封装类:

package pojo;

import java.util.HashSet;
import java.util.Set;

/**
 * 节点对象封装
 * 
 * @author huang
 * 
 */
public class StoreTreeNodeOM {

    private Set<StoreTreeNodeOM> set = new HashSet<StoreTreeNodeOM>();

    private StoreTreeNode node;

    public StoreTreeNodeOM(Set<StoreTreeNodeOM> set, StoreTreeNode node) {
        this.set = set;
        this.node = node;
    }

    public StoreTreeNodeOM(StoreTreeNode node) {
        this.node = node;
    }

    public StoreTreeNodeOM() {
    }

    public String id() {
        return this.node.getId();
    }

    /**
     * 根据id返回子节点
     * 
     * @param id
     * @return
     */
    public StoreTreeNode getChildNode(String id) {
        StoreTreeNode s = null;
        if (set.size() > 0) {
            for (StoreTreeNodeOM om : set) {
                if (om.id().equals(id)) {
                    s = om.getNode();
                }
            }
        }
        return s;
    }

    /**
     * 添加子节点
     * 
     * @param om
     */
    public void insertChild(StoreTreeNodeOM om) {
        this.set.add(om);
    }

    public Set<StoreTreeNodeOM> getSet() {
        return set;
    }

    public void setSet(Set<StoreTreeNodeOM> set) {
        this.set = set;
    }

    public StoreTreeNode getNode() {
        return node;
    }

    public void setNode(StoreTreeNode node) {
        this.node = node;
    }

}

节点的封装类含有当前的节点信息以及子节点信息。

下面是如何将所有的对象都转换为节点树:

package utils;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import pojo.StoreTreeNode;
import pojo.StoreTreeNodeOM;
import annotation.NodeId;
import annotation.NodeText;

/**
 * ext树工具
 * 
 * @author huang
 * 
 */
public class StoreUtil {

    /**
     * 对象转换为Ext树节点
     * 
     * @param object
     * @return
     */
    public static StoreTreeNode objectToStoreTree_child(Object object,
            Object parent, Boolean inhert) {

        StoreTreeNode storeTreeNode = new StoreTreeNode();
        try {
            storeTreeNode.setText((String) EntityUtil.fieldValue(object,
                    NodeText.class, inhert));
            storeTreeNode.setId((String) EntityUtil.fieldValue(object,
                    NodeId.class, inhert));
            if (parent != null) {
                storeTreeNode.setParentId((String) EntityUtil.fieldValue(
                        parent, NodeId.class, inhert));
                storeTreeNode.setLeaf(false);
            }
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return storeTreeNode;
    }

    /**
     * 查找所有父节点
     * 
     * @param nodes
     * @return
     */
    public static Set<StoreTreeNode> parentStoreTreeNodes(
            Collection<StoreTreeNode> nodes) {
        Set<StoreTreeNode> set = new HashSet<StoreTreeNode>();
        for (StoreTreeNode s : nodes) {
            String parentId = s.getParentId();
            if (parentId != null) {
                for (StoreTreeNode n : nodes) {
                    if (parentId.equals(n.getId())) {
                        set.add(n);
                    }
                }
            }
        }
        return set;
    }

    /**
     * 获取子节点最多及深度最高的父节点
     * 
     * @param nodes
     * @return
     */
    public static Set<StoreTreeNode> parentStoreTreeNodes_top(
            Collection<StoreTreeNode> nodes) {
        Set<StoreTreeNode> parents = parentStoreTreeNodes(nodes);
        if (parents.size() == 0) {
            return (Set<StoreTreeNode>) nodes;
        } else {
            return parentStoreTreeNodes_top(parents);
        }
    }

    /**
     * 根据父节点返回所有子节点
     * 
     * @param parent
     * @param nodes
     * @return
     */
    public static Set<StoreTreeNode> childStoreNodes(StoreTreeNode parent,
            Collection<StoreTreeNode> nodes) {
        Set<StoreTreeNode> set = new HashSet<StoreTreeNode>();
        if (nodes.size() > 0) {
            for (StoreTreeNode s : nodes) {
                String parentId = s.getParentId();
                if (parentId != null) {
                    if (parentId.equals(parent.getId())) {
                        set.add(s);
                    }
                }
            }
        }
        return set;
    }

    /**
     * 返回所有节点的封装
     * 
     * @param nodes
     * @return
     */
    public static Set<StoreTreeNodeOM> storeTree_Desc(
            Collection<StoreTreeNode> nodes) {
        Set<StoreTreeNode> parentNodes_top = parentStoreTreeNodes_top(nodes);
        Set<StoreTreeNodeOM> oms = new HashSet<StoreTreeNodeOM>();
        for (StoreTreeNode s : parentNodes_top) {
            oms.add(parentOM(new StoreTreeNodeOM(s), nodes));
        }
        return oms;
    }

    /**
     * 从父节点依次向下遍历
     * 
     * @param parent
     * @param nodes
     * @return
     */
    public static StoreTreeNodeOM parentOM(StoreTreeNodeOM parent,
            Collection<StoreTreeNode> nodes) {
        Set<StoreTreeNode> childs = childStoreNodes(parent.getNode(), nodes);
        if (childs.size() > 0) {
            for (StoreTreeNode n : childs) {
                StoreTreeNodeOM o = parentOM(new StoreTreeNodeOM(n),
                        childStoreNodes(n, nodes));
                parent.insertChild(o);
            }
        }
        return parent;
    }

    /**
     * 根据封装过的父节点获取所有未封装过的所有树节点
     * 
     * @param parent
     * @return
     */
    public static Set<StoreTreeNode> storeTreeNodes(StoreTreeNodeOM parent) {
        Set<StoreTreeNode> set = new HashSet<StoreTreeNode>();
        set.add(parent.getNode());
        Set<StoreTreeNodeOM> oms = parent.getSet();
        if (oms.size() > 0) {
            for (StoreTreeNodeOM om : oms) {
                set.addAll(storeTreeNodes(om));
            }
        }
        return set;
    }

    /**
     * 获取所有节点树
     * 
     * @param nodes
     * @return
     */
    public static Set<StoreTreeNodeOM> storeTreeNodeOMs(
            Collection<StoreTreeNode> nodes) {
        Set<StoreTreeNodeOM> firstSet = storeTree_Desc(nodes);
        Set<StoreTreeNode> nodeSet = new HashSet<StoreTreeNode>();
        for (StoreTreeNodeOM om : firstSet) {
            nodeSet.addAll(storeTreeNodes(om));
        }
        nodes.removeAll(nodeSet);
        if (nodes.size() > 0) {
            firstSet.addAll(storeTreeNodeOMs(nodes));
        }
        return firstSet;
    }

    /**
     * 将所有的树转换为json对象
     * 
     * @param nodes
     * @return
     */
    public static Set<JSONObject> storeTreeNodeJSON(
            Collection<StoreTreeNode> nodes) {
        Set<JSONObject> set = new HashSet<JSONObject>();
        Set<StoreTreeNodeOM> oms = storeTreeNodeOMs(nodes);
        if (oms.size() > 0) {
            for (StoreTreeNodeOM om : oms) {
                set.add(storeTreeNodeJSON(om));
            }
        }
        return set;
    }

    /**
     * 将单棵树转换为json对象
     * 
     * @param om
     * @return
     */
    public static JSONObject storeTreeNodeJSON(StoreTreeNodeOM om) {
        JSONObject json = new JSONObject();
        json.put("id", om.getNode().getId());
        json.put("text", om.getNode().getText());
        json.put("checked", om.getNode().getChecked());
        json.put("expended", true);
        Set<StoreTreeNodeOM> childrens = om.getSet();
        if (childrens.size() > 0) {
            json.put("leaf", false);
            JSONArray array = new JSONArray();
            for (StoreTreeNodeOM o : childrens) {
                JSONObject j = storeTreeNodeJSON(o);
                array.add(j);
            }
            json.put("children", array);
        } else {
            json.put("leaf", true);
        }
        return json;
    }
package utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 实体的工具类
 * 
 * @author huang
 * 
 */
public class EntityUtil {

    /**
     * 返回树节点含有指定注解的属性名称
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    private static String fieldName(Object object, Class anno, Boolean inhert) {
        String name = "";
        Class clazz = object.getClass();
        List<Field> fields = new ArrayList<Field>();
        Field[] fs1 = clazz.getDeclaredFields();
        if (inhert == true) {
            Field[] fs = clazz.getSuperclass().getDeclaredFields();
            for (Field f : fs) {
                fields.add(f);
            }
            for (Field f : fs1) {
                fields.add(f);
            }
        } else {
            for (Field f : fs1) {
                fields.add(f);
            }
        }
        if (fields.size() > 0) {
            for (Field f : fields) {
                if (f.isAnnotationPresent(anno)) {
                    name = f.getName();
                    break;
                }
            }
        }
        return name;
    }

    /**
     * 获取属性的方法
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    private static String fieldMethod(Object object, Class anno, Boolean inhert) {
        String methodName = "get"
                + fieldName(object, anno, inhert).substring(0, 1).toUpperCase()
                + fieldName(object, anno, inhert).substring(1);
        return methodName;
    }

    /**
     * 返回属性的值
     * 
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    @SuppressWarnings("unchecked")
    public static Object fieldValue(Object object, Class anno, Boolean inhert)
            throws SecurityException, NoSuchMethodException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException {
        Class clazz = object.getClass();
        String idMethod = fieldMethod(object, anno, inhert);
        Method method = clazz.getMethod(idMethod);
        Object value = method.invoke(object) == null ? "" : method
                .invoke(object);
        return value;
    }
}

在我们的实体上标识注解

    @Id
    @GenericGenerator(name = "idGenerator", strategy = "uuid")
    @GeneratedValue(generator = "idGenerator")
    @Column(name = "id", unique = true, nullable = false)
    @NodeId
    protected String id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(unique = false, nullable = false)
    protected java.util.Date createDate;

    @Column(nullable = false)
    @NodeText
    private String name;
package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NodeId {

}
package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NodeText {

}

前台如下所示:

var storeTree_depart_all = Ext.create('Ext.data.TreeStore', {
        autoLoad : false,
        root : {
            text : '公司部门',
            id : 'root',
            expanded : true,
            leaf : false,
            checked : false
        },
        folderSort : true
    });
                        xtype : 'button',
                        text : '选择上级部门',
                        anchor : '30%',
                        handler : function() {

                            storeTree_depart_all.setProxy({
                                type : 'ajax',
                                url : 'depart_getAll.do'
                            });
                            storeTree_depart_all.load();

                            var treePanel = new Ext.FormPanel({
                                width : 502,
                                height : 500,
                                x : 300,
                                y : 30,
                                floating : true,
                                draggable : true,
                                closable : true,
                                renderTo : 'depart_base_data',
                                title : '部门列表',
                                layout : 'column',
                                items : [{
                                    xtype : 'treepanel',
                                    id : 'tree',
                                    store : storeTree_depart_all,
                                    width : 500,
                                    height : 430,
                                    autoScroll : true,
                                    rootVisible : false,
                                    viewConfig : {
                                        plugins : {
                                            ptype : 'treeviewdragdrop',
                                            appendOnly : true
                                        }
                                    }
                                }],
                                buttons : [{
                                    text : '确认',
                                    type : 'submit',
                                    handler : function() {
                                        var checkedNodes = Ext.getCmp('tree')
                                                .getChecked();
                                        Ext.getCmp('superDepartId')
                                                .setValue(checkedNodes[0]
                                                        .get('id'));
                                        Ext.getCmp('superDepartName')
                                                .setValue(checkedNodes[0]
                                                        .get('text'));
                                        treePanel.close();
                                    }
                                }]
                            });

                        }
                    
    /**
     * 获取部门树
     */
    public void getAll() {
        List list = this.service
                .find("select d, s from Depart d left outer join d.supperDepart s order by d.createDate desc");
        Set<StoreTreeNode> nodes = new HashSet<StoreTreeNode>();
        for (Object o : list) {
            Object[] l = (Object[]) o;
            StoreTreeNode node = StoreUtil.objectToStoreTree_child(l[0], l[1],
                    true);
            nodes.add(node);
        }
        JSONArray jsonArray = new JSONArray();
        for (JSONObject j : StoreUtil.storeTreeNodeJSON(nodes)) {
            jsonArray.add(j);
        }
        System.out.println(jsonArray);
        JsonResult.json(jsonArray.toString(), servletResponse, null);
    }
package action;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

public class JsonResult {

    public static void json(String json, HttpServletResponse servletResponse,
            String contentType) {
        if (json != null) {
            if (contentType == null || contentType.equals("")) {
                servletResponse.setContentType("text/html");
            }
            servletResponse.setCharacterEncoding("UTF-8");
            try {
                servletResponse.getWriter().write(json);
                servletResponse.flushBuffer();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

}

搞了半天不知道怎么组织语言,算了,上代码,如果有人看的话,请多提些意见

截图如下:

json格式如下:

[{"id":"ff8080813788fe0701378900b68c0001","text":"软件开发部","checked":false,"expended":true,"leaf":false,"children":[{"id":"4028804937b1a7ac0137b1c1965a0002","text":"预警项目组","checked":false,"expended":true,"leaf":true},{"id":"4028807637d0bcab0137d0c9c4580001","text":"中信项目组","checked":false,"expended":true,"leaf":true},{"id":"4028804937b1a7ac0137b1b4a2400001","text":"洛川项目组","checked":false,"expended":true,"leaf":true}]},{"id":"4028804937b13cf00137b1429ed70003","text":"人事管理","checked":false,"expended":true,"leaf":false,"children":[{"id":"4028804937b1a7ac0137b2ea138c0004","text":"人员信息采集部","checked":false,"expended":true,"leaf":true}]},{"id":"4028804937b13cf00137b14388780004","text":"公关部","checked":false,"expended":true,"leaf":true}]

可以无限制进行扩展树结构

最近刚毕业,有时间把练手的代码发上来,做个备忘录

原文地址:https://www.cnblogs.com/tatame/p/2552541.html