通常我们利用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}]
可以无限制进行扩展树结构
最近刚毕业,有时间把练手的代码发上来,做个备忘录