随笔-126  评论-247  文章-5  trackbacks-0

示例效果图


示例源码

这里以菜单为例,来展示 TreePanel 的使用。

TreeExample

package fan.tutorial.client.ui.tree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.extjs.gxt.ui.client.data.HttpProxy;
import com.extjs.gxt.ui.client.data.JsonReader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelType;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.layout.AccordionLayout;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import fan.tutorial.client.commons.TreeNodeUtil;
import fan.tutorial.client.model.ITreeNode;
import fan.tutorial.client.model.TreeNode;
import fan.tutorial.client.model.TreeNode.NodeType;
import fan.tutorial.server.value.Constant;

public class TreeExample extends ContentPanel {
    
    public TreeExample() {
        
        //设置面板标题
        setHeadingHtml("Tree Example");
        //设置面板宽度高度
        setSize(250, 400);
        //设置面板布局
        setLayout(new AccordionLayout());

        //创建ModelType
        ModelType modelType = new ModelType();
        //设置根名称(与json数据根名称要保持一致, 否则无法正确的解析数据)
        modelType.setRoot(Constant.RESULT);
        //添加需要使用到的字段域, 未被添加的字段域无法使用
        modelType.addField(ITreeNode.ID);
        modelType.addField(ITreeNode.TEXT);
        modelType.addField(ITreeNode.NODE_TYPE);
        modelType.addField(ITreeNode.PRIOR_LEVEL);
        modelType.addField(ITreeNode.PARENT_NODE_ID);

        //Spring MVC Controller 请求地址
        String url = GWT.getHostPageBaseURL() + "menu/treenodes.json";
        //构建RequestBuilder
        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
        //创建HttpProxy
        HttpProxy<List<ModelData>> proxy = new HttpProxy<List<ModelData>>(builder);
        //JsonReader
        JsonReader<List<ModelData>> reader = new JsonReader<List<ModelData>>(modelType);
        //加载数据
        proxy.load(reader, nullnew AsyncCallback<List<ModelData>>() {
            public void onSuccess(List<ModelData> result) {
                //树节点
                List<TreeNode> treeNodes = TreeNodeUtil.modelDatas2TreeNodes(result);
                //面板类节点
                List<TreeNode> panels = new ArrayList<TreeNode>();
                //根类节点
                List<TreeNode> roots = new ArrayList<TreeNode>();
                //叶子类节点
                List<TreeNode> leafs = new ArrayList<TreeNode>();
                for(TreeNode node : treeNodes){
                    if(node.getNodeType().ordinal() == NodeType.PANEL.ordinal()){
                        panels.add(node);
                    }else if(node.getNodeType().ordinal() == NodeType.ROOT.ordinal()){
                        roots.add(node);
                    }else{
                        leafs.add(node);
                    }
                }
                //排序面板类节点
                Collections.sort(panels);
                //渲染树节点
                onRender(panels, roots, leafs);
                //渲染完成之后重新渲染面板内容
                layout(true);
            }
            public void onFailure(Throwable caught) {
                
            }
        });
    }

    //渲染树节点
    private void onRender(List<TreeNode> panels, List<TreeNode> roots, List<TreeNode> leafs){
        for(TreeNode panelNode : panels){
            //面板类节点面板
            ContentPanel panel = new ContentPanel();
            //设置面板类节点标题
            panel.setHeadingHtml(panelNode.getText());
            TreeStore<ModelData> store = new TreeStore<ModelData>();
            TreePanel<ModelData> tree = new TreePanel<ModelData>(store);
            //树结构内容显示文本
            tree.setDisplayProperty(ITreeNode.TEXT);
            //面板类节点的孩子节点(根类节点)
            List<TreeNode> panelNodeChildren = hasChildrenNode(panelNode, roots);
            if(panelNodeChildren.size() > 0){
                //迭代根类节点
                for(TreeNode root : panelNodeChildren){
                    //根类节点的孩子节点(叶子节点)
                    List<TreeNode> rootNodeChildren = hasChildrenNode(root, leafs);
                    ModelData modelData = TreeNodeUtil.treeNode2ModelData(root);
                    if(rootNodeChildren.size() > 0){
                        //添加根类节点
                        store.add(modelData, true);
                        //迭代叶子节点
                        for(TreeNode leaf : rootNodeChildren){
                            ModelData m = TreeNodeUtil.treeNode2ModelData(leaf);
                            //添加叶子节点
                            store.add(modelData, m, false);
                        }
                    }else{
                        //添加根类节点
                        store.add(modelData, false);
                    }
                    //展开节点
                    tree.setExpanded(modelData, true);
                }
            }
            //为面板节点添加树节点
            panel.add(tree);
            //添加面板节点到容器
            add(panel);
        }
    }
    
    //判断节点是否拥有孩子节点
    private List<TreeNode> hasChildrenNode(TreeNode node, List<TreeNode> nodes){
        List<TreeNode> children = new ArrayList<TreeNode>();
        if(nodes.size() > 0){
            for(TreeNode n : nodes){
                if(n.getParentNodeId() == node.getId()){
                    children.add(n);
                }
            }
        }
        if(children.size() > 0){
            //排序孩子节点
            Collections.sort(children);
        }
        return children;
    }
}
这里需要注意的是,取树节点数据这个过程是在异步回调方法里面完成的。在这期间内,页面上的 ContentPanel 是已经被渲染出来了的,但这个 ContentPanel 里面的内容是空的,什么都还没有,因为这时候异步回调方法还没有执行完成,自然是没有数据。在异步回调方法的最后不要忘记去调一下 layout(true),来重新渲染一次 ContentPanel,否则面板内容是空的。

TreeNodeController

package fan.tutorial.server.controller;

import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import fan.tutorial.server.commons.JsonUtil;
import fan.tutorial.server.service.DataService;
import fan.tutorial.server.value.Constant;

@Controller
@RequestMapping("/menu")
public class TreeNodeController {

    @Resource
    private DataService service;
    
    @RequestMapping("/treenodes")
    public String findTreeNodes(Model model){
        model.addAttribute(Constant.RESULT, JsonUtil.toJson(Constant.RESULT, service.findTreeNodes()));
        return Constant.RESULT_CODE;
    }
}

DataService

package fan.tutorial.server.service;

import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import fan.tutorial.client.model.TreeNode;
import fan.tutorial.server.value.Data;

@Service
public class DataService {
    
    @Resource
    private Data data;
    
    public List<TreeNode> findTreeNodes(){
        return data.getTreeNodes();
    }
}

Data

package fan.tutorial.server.value;

import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import fan.tutorial.client.model.TreeNode;
import fan.tutorial.client.model.TreeNode.NodeType;

@Component
public class Data {

    private List<TreeNode> treeNodes;
    
    private List<TreeNode> buildTreeNodes(){
        List<TreeNode> treeNodes = new ArrayList<TreeNode>();
        TreeNode usersManagementNode = new TreeNode("用户管理", NodeType.PANEL, 0);
        TreeNode goodsManagementNode = new TreeNode("商品管理", NodeType.PANEL, 1);
        TreeNode orderManagementNode = new TreeNode("订单管理", NodeType.PANEL, 2);
        treeNodes.add(usersManagementNode);
        treeNodes.add(goodsManagementNode);
        treeNodes.add(orderManagementNode);
        treeNodes.add(new TreeNode("系统用户管理", NodeType.ROOT, 0, usersManagementNode.getId()));
        treeNodes.add(new TreeNode("会员账号管理", NodeType.ROOT, 1, usersManagementNode.getId()));
        treeNodes.add(new TreeNode("在售商品", NodeType.ROOT, 2, goodsManagementNode.getId()));
        treeNodes.add(new TreeNode("下架商品", NodeType.ROOT, 3, goodsManagementNode.getId()));
        treeNodes.add(new TreeNode("缺货通知", NodeType.ROOT, 4, goodsManagementNode.getId()));
        treeNodes.add(new TreeNode("到货通知", NodeType.ROOT, 5, goodsManagementNode.getId()));
        treeNodes.add(new TreeNode("未确认订单", NodeType.ROOT, 6, orderManagementNode.getId()));
        treeNodes.add(new TreeNode("待发货订单", NodeType.ROOT, 7, orderManagementNode.getId()));
        treeNodes.add(new TreeNode("已发货订单", NodeType.ROOT, 8, orderManagementNode.getId()));
        treeNodes.add(new TreeNode("未付款订单", NodeType.ROOT, 9, orderManagementNode.getId()));
        treeNodes.add(new TreeNode("已完成订单", NodeType.ROOT, 10, orderManagementNode.getId()));
        this.treeNodes = treeNodes;
        return treeNodes;
    }

    public List<TreeNode> getTreeNodes() {
        return treeNodes == null ? buildTreeNodes() : treeNodes;
    }
}

TreeNodeUtil

package fan.tutorial.client.commons;

import java.util.ArrayList;
import java.util.List;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.data.ModelData;
import fan.tutorial.client.model.ITreeNode;
import fan.tutorial.client.model.TreeNode;
import fan.tutorial.client.model.TreeNode.NodeType;

public class TreeNodeUtil {

    private TreeNodeUtil(){
        
    }
    
    public static TreeNode modelData2TreeNode(ModelData modelData){
        TreeNode node = new TreeNode();
        Double id = modelData.get(ITreeNode.ID);
        String text = modelData.get(ITreeNode.TEXT);
        Double priorLevel = modelData.get(ITreeNode.PRIOR_LEVEL);
        Double parentNodeId = modelData.get(ITreeNode.PARENT_NODE_ID);
        String type = modelData.get(ITreeNode.NODE_TYPE);
        NodeType nodeType = NodeType.valueOfString(type);
        node.setId(id.intValue());
        node.setText(text);
        node.setNodeType(nodeType);
        node.setPriorLevel(priorLevel.intValue());
        node.setParentNodeId(parentNodeId.intValue());
        return node;
    }
    
    public static List<TreeNode> modelDatas2TreeNodes(List<ModelData> modelDatas){
        List<TreeNode> treeNodes = new ArrayList<TreeNode>();
        for(ModelData modelData : modelDatas){
            treeNodes.add(modelData2TreeNode(modelData));
        }
        return treeNodes;
    }
    
    public static ModelData treeNode2ModelData(TreeNode treeNode){
        ModelData modelData = new BaseModelData();
        modelData.set(ITreeNode.ID, treeNode.getId());
        modelData.set(ITreeNode.TEXT, treeNode.getText());
        modelData.set(ITreeNode.PRIOR_LEVEL, treeNode.getPriorLevel());
        modelData.set(ITreeNode.PARENT_NODE_ID, treeNode.getParentNodeId());
        modelData.set(ITreeNode.NODE_TYPE, treeNode.getNodeType().getValue());
        return modelData;
    }
    
    public static List<ModelData> treeNodes2ModelDatas(List<TreeNode> treeNodes){
        List<ModelData> modelDatas = new ArrayList<ModelData>();
        for(TreeNode treeNode : treeNodes){
            modelDatas.add(treeNode2ModelData(treeNode));
        }
        return modelDatas;
    }
}

TreeNode

package fan.tutorial.client.model;

public class TreeNode implements Comparable<TreeNode> {

    private int id;
    private static int count;
    private String text;
    private NodeType nodeType;
    private int priorLevel;
    private int parentNodeId;
    private static final int NULL = -1;
    
    public TreeNode(){
        this.id = ++count;
    }
    
    public TreeNode(String text, NodeType nodetype, int priorLevel){
        this(text, nodetype, priorLevel, NULL);
    }
    
    public TreeNode(String text, NodeType nodetype, int priorLevel, int parentNodeId){
        this();
        this.text = text;
        this.nodeType = nodetype;
        this.priorLevel = priorLevel;
        this.parentNodeId = parentNodeId;
    }
    
    public enum NodeType {
        
        ROOT("ROOT"), LEAF("LEAF"), PANEL("PANEL");
        
        private final String value;
        
        private NodeType(String value){
            this.value = value;
        }

        public String getValue() {
            return value;
        }
        
        public static NodeType valueOfString(String value){
            if(value.equals("ROOT")){
                return ROOT;
            }else if(value.equals("LEAF")){
                return LEAF;
            }else if(value.equals("PANEL")){
                return PANEL;
            }
            return null;
        }

        @Override
        public String toString() {
            return value;
        }
    }

    @Override
    public int compareTo(TreeNode o) {
        return this.priorLevel > o.priorLevel ? 1 : -1;
    }

    public String getText() {
        return text;
    }

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

    public NodeType getNodeType() {
        return nodeType;
    }

    public void setNodeType(NodeType nodeType) {
        this.nodeType = nodeType;
    }

    public int getPriorLevel() {
        return priorLevel;
    }

    public void setPriorLevel(int priorLevel) {
        this.priorLevel = priorLevel;
    }

    public int getParentNodeId() {
        return parentNodeId;
    }

    public void setParentNodeId(int parentNodeId) {
        this.parentNodeId = parentNodeId;
    }

    public int getId() {
        return id;
    }

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

ITreeNode

package fan.tutorial.client.model;

public interface ITreeNode {

    String ID = "id";
    String TEXT = "text";
    String NODE_TYPE = "nodeType";
    String PRIOR_LEVEL = "priorLevel";
    String PARENT_NODE_ID = "parentNodeId";
}





  
posted on 2014-06-10 23:41 fancydeepin 阅读(1342) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: