最近尝试用extjs来展示树状菜单。着实花了一番功夫。树状菜单的菜单项需要动态加载,而目前版本的extjs中只支持JSON格式的数据。查了一些资 料,决定使用struts2的json-plugin。首先按照例子做了一个,但是结果就是不成功,界面上只出来了一个js中生成的root节点,不能加 载从后台生成的数据。研究后发现是数据格式有问题。使用json-plugin生成的数据格式如下:
{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}
而extjs需要的数据格式如下:
[{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}]
区别很小,就只相差最外面的两个方括号。但是少了这两个方括号,在json中,含义迥然不同,前者表示一个对象,而后者表示一个数组。而extjs中 tree的dataloader需要的数据必须是一个数组。而这样的数据格式是json-plugin自动生成的,无法改变。所以,我最后放弃了json -plugin,转而使用json-lib来解决这个问题。
1. 下载json-lib, http://json-lib.sourceforge.net/
2. lib目录下的jar文件清单:
commons-beanutils-1.7.0.jar
commons-collections-3.2.jar
commons-digester-1.6.jar
commons-lang-2.3.jar
commons-logging-1.1.jar
dom4j-1.6.1.jar
ezmorph-1.0.4.jar
freemarker-2.3.8.jar
json-lib-2.2.1-jdk15.jar
log4j-1.2.13.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xml-apis-1.0.b2.jar
xwork-2.0.4.jar
首先配置web.xml
然后是struts.xml
3. 树的节点模型(省略了getter,setter)
4. action
5. menu.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="menuString" escape="false"/>
6. html页面和js
我使用的就是extjs的example中的reorder.html和reorder.js,更改了reorder.js中treeloader的dataurl: menus.action
js:
{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}
而extjs需要的数据格式如下:
[{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}]
区别很小,就只相差最外面的两个方括号。但是少了这两个方括号,在json中,含义迥然不同,前者表示一个对象,而后者表示一个数组。而extjs中 tree的dataloader需要的数据必须是一个数组。而这样的数据格式是json-plugin自动生成的,无法改变。所以,我最后放弃了json -plugin,转而使用json-lib来解决这个问题。
1. 下载json-lib, http://json-lib.sourceforge.net/
2. lib目录下的jar文件清单:
commons-beanutils-1.7.0.jar
commons-collections-3.2.jar
commons-digester-1.6.jar
commons-lang-2.3.jar
commons-logging-1.1.jar
dom4j-1.6.1.jar
ezmorph-1.0.4.jar
freemarker-2.3.8.jar
json-lib-2.2.1-jdk15.jar
log4j-1.2.13.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xml-apis-1.0.b2.jar
xwork-2.0.4.jar
首先配置web.xml
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><?xmlversion="1.0"encoding="UTF-8"?>
<web-appversion="2.4"xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
<web-appversion="2.4"xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
然后是struts.xml
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constantname="struts.devMode"value="true"/>
<constantname="struts.i18n.encoding"value="UTF-8"/>
<packagename="person"extends="struts-default">
<actionname="menus"method="execute"class="com.lab.MenuAction">
<result>/menu.jsp</result>
</action>
</package>
</struts>
<!DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constantname="struts.devMode"value="true"/>
<constantname="struts.i18n.encoding"value="UTF-8"/>
<packagename="person"extends="struts-default">
<actionname="menus"method="execute"class="com.lab.MenuAction">
<result>/menu.jsp</result>
</action>
</package>
</struts>
3. 树的节点模型(省略了getter,setter)
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->publicclassMenu{
privateintid;
privateStringtext;
privatebooleanleaf;
privateStringcls;
privateList<Menu>children;
}
privateintid;
privateStringtext;
privatebooleanleaf;
privateStringcls;
privateList<Menu>children;
}
4. action
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->packagecom.lab;
importjava.util.ArrayList;
importjava.util.List;
importnet.sf.json.JSONArray;
publicclassMenuAction{
privateStringmenuString;
privateList<Menu>menus;
publicStringexecute(){
menus=newArrayList<Menu>();
Menubenz=newMenu();
benz.setText("Benz");
benz.setCls("folder");
benz.setLeaf(false);
benz.setId(10);
menus.add(benz);
List<Menu>benzList=newArrayList<Menu>();
benz.setChildren(benzList);
Menumenu;
menu=newMenu();
menu.setText("S600");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(11);
benzList.add(menu);
menu=newMenu();
menu.setText("SLK200");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(12);
benzList.add(menu);
Menubmw=newMenu();
bmw.setText("BMW");
bmw.setCls("folder");
bmw.setLeaf(false);
bmw.setId(20);
menus.add(bmw);
List<Menu>bmwList=newArrayList<Menu>();
bmw.setChildren(bmwList);
menu=newMenu();
menu.setText("325i");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(21);
bmwList.add(menu);
menu=newMenu();
menu.setText("X5");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(22);
bmwList.add(menu);
JSONArrayjsonObject=JSONArray.fromObject(menus);
try{
menuString=jsonObject.toString();
}catch(Exceptione){
menuString="ss";
}
return"success";
}
publicStringgetMenuString(){
returnmenuString;
}
publicvoidsetMenuString(StringmenuString){
this.menuString=menuString;
}
}
importjava.util.ArrayList;
importjava.util.List;
importnet.sf.json.JSONArray;
publicclassMenuAction{
privateStringmenuString;
privateList<Menu>menus;
publicStringexecute(){
menus=newArrayList<Menu>();
Menubenz=newMenu();
benz.setText("Benz");
benz.setCls("folder");
benz.setLeaf(false);
benz.setId(10);
menus.add(benz);
List<Menu>benzList=newArrayList<Menu>();
benz.setChildren(benzList);
Menumenu;
menu=newMenu();
menu.setText("S600");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(11);
benzList.add(menu);
menu=newMenu();
menu.setText("SLK200");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(12);
benzList.add(menu);
Menubmw=newMenu();
bmw.setText("BMW");
bmw.setCls("folder");
bmw.setLeaf(false);
bmw.setId(20);
menus.add(bmw);
List<Menu>bmwList=newArrayList<Menu>();
bmw.setChildren(bmwList);
menu=newMenu();
menu.setText("325i");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(21);
bmwList.add(menu);
menu=newMenu();
menu.setText("X5");
menu.setCls("file");
menu.setLeaf(true);
menu.setId(22);
bmwList.add(menu);
JSONArrayjsonObject=JSONArray.fromObject(menus);
try{
menuString=jsonObject.toString();
}catch(Exceptione){
menuString="ss";
}
return"success";
}
publicStringgetMenuString(){
returnmenuString;
}
publicvoidsetMenuString(StringmenuString){
this.menuString=menuString;
}
}
5. menu.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="menuString" escape="false"/>
6. html页面和js
我使用的就是extjs的example中的reorder.html和reorder.js,更改了reorder.js中treeloader的dataurl: menus.action
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=iso-8859-1">
<title>ReorderTreePanel</title>
<linkrel="stylesheet"type="text/css"href="extjs/resources/css/ext-all.css"/>
<!--GC-->
<!--LIBS-->
<scripttype="text/javascript"src="extjs/adapter/ext/ext-base.js"></script>
<!--ENDLIBS-->
<scripttype="text/javascript"src="extjs/ext-all.js"></script>
<scripttype="text/javascript"src="reorder.js"></script>
<!--CommonStylesfortheexamples-->
<linkrel="stylesheet"type="text/css"href="extjs/resources/css/example.css"/>
</head>
<body>
<scripttype="text/javascript"src="../examples.js"></script><!--EXAMPLES-->
<h1>DragandDroporderinginaTreePanel</h1>
<p>Thisexampleshowsbasicdraganddropnodemovinginatree.Inthisimplementationtherearenorestrictionsand
anythingcanbedroppedanywhereexceptappendingtonodesmarked"leaf"(thefiles).<br></p>
<p>Dragalongtheedgeofthetreetotriggerautoscrollingwhileperformingadraganddrop.</p>
<p>Inordertodemonstratedraganddropinsertionpoints,sortingwas<b>not</b>enabled.</p>
<p>ThedataforthistreeisasynchronouslyloadedwithaJSONTreeLoader.</p>
<p>Thejsisnotminifiedsoitisreadable.See<ahref="reorder.js">reorder.js</a>.</p>
<divid="tree-div"style="overflow:auto;height:300px;width:250px;border:1pxsolid#c3daf9;"></div>
</body>
</html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=iso-8859-1">
<title>ReorderTreePanel</title>
<linkrel="stylesheet"type="text/css"href="extjs/resources/css/ext-all.css"/>
<!--GC-->
<!--LIBS-->
<scripttype="text/javascript"src="extjs/adapter/ext/ext-base.js"></script>
<!--ENDLIBS-->
<scripttype="text/javascript"src="extjs/ext-all.js"></script>
<scripttype="text/javascript"src="reorder.js"></script>
<!--CommonStylesfortheexamples-->
<linkrel="stylesheet"type="text/css"href="extjs/resources/css/example.css"/>
</head>
<body>
<scripttype="text/javascript"src="../examples.js"></script><!--EXAMPLES-->
<h1>DragandDroporderinginaTreePanel</h1>
<p>Thisexampleshowsbasicdraganddropnodemovinginatree.Inthisimplementationtherearenorestrictionsand
anythingcanbedroppedanywhereexceptappendingtonodesmarked"leaf"(thefiles).<br></p>
<p>Dragalongtheedgeofthetreetotriggerautoscrollingwhileperformingadraganddrop.</p>
<p>Inordertodemonstratedraganddropinsertionpoints,sortingwas<b>not</b>enabled.</p>
<p>ThedataforthistreeisasynchronouslyloadedwithaJSONTreeLoader.</p>
<p>Thejsisnotminifiedsoitisreadable.See<ahref="reorder.js">reorder.js</a>.</p>
<divid="tree-div"style="overflow:auto;height:300px;width:250px;border:1pxsolid#c3daf9;"></div>
</body>
</html>
js:
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->/*
*ExtJSLibrary2.0.1
*Copyright(c)2006-2008,ExtJS,LLC.
*licensing@extjs.com
*
*http://extjs.com/license
*/
Ext.onReady(function(){
//shorthand
varTree=Ext.tree;
vartree=newTree.TreePanel({
el:'tree-div',
autoScroll:true,
animate:true,
enableDD:true,
containerScroll:true,
loader:newTree.TreeLoader({
dataUrl:'http://localhost:8080/lab/menus.action'
})
});
//settherootnode
varroot=newTree.AsyncTreeNode({
text:'ExtJS',
draggable:false,
id:'source'
});
tree.setRootNode(root);
//renderthetree
tree.render();
root.expand();
});
*ExtJSLibrary2.0.1
*Copyright(c)2006-2008,ExtJS,LLC.
*licensing@extjs.com
*
*http://extjs.com/license
*/
Ext.onReady(function(){
//shorthand
varTree=Ext.tree;
vartree=newTree.TreePanel({
el:'tree-div',
autoScroll:true,
animate:true,
enableDD:true,
containerScroll:true,
loader:newTree.TreeLoader({
dataUrl:'http://localhost:8080/lab/menus.action'
})
});
//settherootnode
varroot=newTree.AsyncTreeNode({
text:'ExtJS',
draggable:false,
id:'source'
});
tree.setRootNode(root);
//renderthetree
tree.render();
root.expand();
});