示例效果图
示例源码
这里以菜单为例,来展示 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.gethostpagebase "menu/treenodes.json";
//构建requestbuilder
requestbuilder builder = new requestbuilder(requestbuilder.get, url);
//创建httpproxy
httpproxy> proxy = new httpproxy>(builder);
//jsonreader
jsonreader> reader = new jsonreader>(modeltype);
//加载数据
proxy.load(reader, null, new asynccallback>() {
public void onsuccess(list result) {
//树节点
list treenodes = treenodeutil.modeldatas2treenodes(result);
//面板类节点
list panels = new arraylist();
//根类节点
list roots = new arraylist();
//叶子类节点
list leafs = new arraylist();
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 panels, list roots, list leafs){
for(treenode panelnode : panels){
//面板类节点面板
contentpanel panel = new contentpanel();
//设置面板类节点标题
panel.setheadinghtml(panelnode.gettext());
treestore store = new treestore();
treepanel tree = new treepanel(store);
//树结构内容显示文本
tree.setdisplayproperty(itreenode.text);
//面板类节点的孩子节点(根类节点)
list panelnodechildren = haschildrennode(panelnode, roots);
if(panelnodechildren.size() > 0){
//迭代根类节点
for(treenode root : panelnodechildren){
//根类节点的孩子节点(叶子节点)
list 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 haschildrennode(treenode node, list nodes){
list children = new arraylist();
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 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 treenodes;
private list buildtreenodes(){
list treenodes = new arraylist();
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 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 modeldatas2treenodes(list modeldatas){
list treenodes = new arraylist();
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 treenodes2modeldatas(list treenodes){
list modeldatas = new arraylist();
for(treenode treenode : treenodes){
modeldatas.add(treenode2modeldata(treenode));
}
return modeldatas;
}
}
treenode
package fan.tutorial.client.model;
public class treenode implements comparable {
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";
}