`

Ext.tree.TreePanel

阅读更多

转载:http://blog.csdn.net/tinyyys/archive/2009/03/2**027142.aspx

个人只是进行了测试,理解而已。原文中使用的数据库是SQL 2000的,而本人使用的是mysql,故做了一点点的更改。

【注意】:以下所有引用资源的路径都是根据自己的资源位置来配置的。

第一步:创建treePanel.html

Code:
  1. <!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <metahttp-equiv="Content-Type"content="text/html;charset=UTF-8">
  5. <title>测试Ext.tree.TreePanel</title>
  6. <linkrel="stylesheet"type="text/css"href="../static/lib/ext/resources/css/ext-all.css"/>
  7. <scripttype="text/javascript"src="../static/lib/ext/adapter/ext/ext-base.js"></script>
  8. <scripttype="text/javascript"src="../static/lib/ext/ext-all.js"></script>
  9. <linkrel="stylesheet"type="text/css"href="../style/comment.css"/>
  10. <scripttype="text/javascript"src="../js/treePanel.js"charset="utf-8"></script>
  11. <linkrel="shortcuticon"href="x.ico"/>
  12. </head>
  13. <body>
  14. <divid="tree-panel"style="overflow:auto;height:600px;width:200px;border:2pxsolid#c3daf9;"></div>
  15. </body>
  16. </html>

第二步:创建含Ext.onRready函数的treePanel.js文件

Code:
  1. Ext.onReady(function(){
  2. Ext.QuickTips.init();//浮动信息提示
  3. Ext.BLANK_IMAGE_URL='../static/lib/ext/resources/images/default/s.gif';//替换图片文件地址为本地
  4. //创建一个简写
  5. var_Tree=Ext.tree;
  6. //定义根节点的Loader
  7. var_treeloader=new_Tree.TreeLoader({
  8. //dataUrl:'tree.jsp'//这里可以不需要指定URL,在加载前事件响应里面设置
  9. });
  10. //添加一个树形面板
  11. var_treepanel=new_Tree.TreePanel({
  12. //renderTo:"tree_div",//如果使用renderTo,则不能使用setRootNode()方法,需要在TreePanel中设置root属性。
  13. el:'tree-panel',//将树形添加到一个指定的div中,非常重要!
  14. region:'west',
  15. title:'功能菜单',
  16. width:200,//面板宽度
  17. minSize:180,
  18. maxSize:250,
  19. split:true,
  20. autoHeight:false,
  21. frame:true,//美化界面
  22. //title:'可编辑和拖动的异步树',//标题
  23. //autoScroll:true,//自动滚动
  24. enableDD:true,//是否支持拖拽效果
  25. containerScroll:true,//是否支持滚动条
  26. rootVisible:true,//是否隐藏根节点,很多情况下,我们选择隐藏根节点增加美观性
  27. border:true,//边框
  28. animate:true,//动画效果
  29. loader:_treeloader//树加载
  30. });
  31. //异步加载根节点
  32. var_rootnode=new_Tree.AsyncTreeNode({
  33. id:'0',
  34. text:'家电品牌总类',
  35. draggable:false,//根节点不容许拖动
  36. expanded:true
  37. });
  38. //为tree设置根节点
  39. _treepanel.setRootNode(_rootnode);
  40. //响应加载前事件,传递node参数
  41. _treepanel.on('beforeload',function(node){
  42. _treepanel.loader.dataUrl='tree.jsp?parentId='+node.id;//定义子节点的Loader
  43. });
  44. //渲染树形
  45. _treepanel.render();
  46. //展开节点,第一个参数表示是否级联展开子节点
  47. _rootnode.expand(false);
  48. //设置树的点击事件【测试点击事件不影响树的其他效果】
  49. var_treeClick=function(node,e){//contentPanel为定义的TabPanel
  50. if(node.isLeaf()){
  51. e.stopEvent();
  52. varn=contentPanel.getComponent(node.id);//通过node的id获取组件
  53. if(!n){//如果不存在则new一个出来
  54. varn=contentPanel.add({
  55. 'id':node.id,
  56. 'title':node.text,
  57. closable:true,
  58. autoLoad:{
  59. url:'tabFrame.jsp?url=grid.html',
  60. scripts:true
  61. }//通过autoLoad属性载入目标页,如果要用到脚本,必须加上scripts属性
  62. });
  63. }
  64. contentPanel.setActiveTab(n);
  65. }
  66. }
  67. //增加鼠标单击事件
  68. _treepanel.on('click',_treeClick);
  69. //定义右键菜单
  70. varrightClick=newExt.menu.Menu({
  71. id:'rightClickCont',
  72. items:[{
  73. id:'rMenu1',
  74. text:'添加节点',
  75. //增加菜单点击事件
  76. handler:function(){
  77. alert('添加节点的实现!');
  78. }
  79. },{
  80. id:'rMenu2',
  81. text:'编辑节点'
  82. },{
  83. id:'rMenu3',
  84. text:'删除节点'
  85. }]
  86. });
  87. //增加右键点击事件
  88. _treepanel.on('contextmenu',function(node,event){//声明菜单类型
  89. event.preventDefault();//阻止浏览器默认右键菜单显示
  90. rightClick.showAt(event.getXY());//取得鼠标点击坐标,展示菜单
  91. });
  92. /*
  93. *设置tree的节点放置函数此函数有一个很重要的参数对象ee对象有三个重要的属性,分别为dropNode,target,point
  94. *1.dropNode为在拖动时鼠标抓住的节点2.target为将要放置在某处的节点
  95. *3.point为被放置的状态,分别有append表示添加,above节点的上方,below节点的下方。
  96. *
  97. */
  98. _treepanel.on('nodedrop',function(e){
  99. if(e.point=='append'){
  100. alert('当前"'+e.dropNode.text+'"划到"'+e.target.text+'"里面!');
  101. }elseif(e.point=='above'){
  102. alert('当前"'+e.dropNode.text+'"放在了"'+e.target.text+'"上面!');
  103. }elseif(e.point=='below'){
  104. alert('当前"'+e.dropNode.text+'"放在了"'+e.target.text+'"下面!');
  105. }
  106. });
  107. //在原有的树形添加一个TreeEditor
  108. var_treeEditer=new_Tree.TreeEditor(_treepanel,{
  109. allowBlank:false
  110. });
  111. /*
  112. *为创建的treeEditer添加事件有两个事件最为常用,一个为beforestartedit另一个为complete
  113. *从名字就可以看出,beforestartedit事件是在编辑前的事件,因此可以通过它来判断那些节点可以编辑那些不可以。
  114. *complete为编辑之后的事件,在这里面可以添加很多事件,比如添加一个Ext.Ajax向后台传送修改的值等等。
  115. */
  116. _treeEditer.on("beforestartedit",function(_treeEditer){
  117. var_tempNode=_treeEditer.editNode;//将要编辑的节点
  118. if(_tempNode.isLeaf()){//这里设定叶子节点才容许编辑
  119. returntrue;
  120. }else{
  121. returnfalse;
  122. }
  123. });
  124. _treeEditer.on("complete",function(_treeEditer){
  125. Ext.Msg.alert("被修改为"+_treeEditer.editNode.text);
  126. });
  127. //(1)通过TabPanel控件的html属性配合<iframe>实现。该方法是利用
  128. //html属性中包含<iframe>的语法来调用另一个页面,具体见代码。
  129. //(2)通过TabPanel控件的autoLoad属性实现。该方法是利用autoLoad属性,它有很多参数,
  130. //其中有两个比较重要,url表示要载入的文件,scripts表示载入的文件是否含有脚本,该属性相当重要,
  131. //如果在新的页面中要创建Ext控件,必须指定该参数。该方法实现较前一个复杂,因为引入的文件不是一个完整的html文件,
  132. //有可能只是内容的一部分,但是资源占用较少,而且载入速度较快(它有一个载入指示)
  133. //添加第一个节点(html)
  134. _treepanel.root.appendChild(newExt.tree.TreeNode({
  135. id:'htmlPanel',
  136. text:'通过html打开',
  137. listeners:{
  138. 'click':function(node,event){
  139. event.stopEvent();
  140. varn=contentPanel.getComponent(node.id);
  141. if(!n){//判断是否已经打开该面板
  142. n=contentPanel.add({
  143. 'id':node.id,
  144. 'title':node.text,
  145. closable:true,//通过html载入目标页
  146. html:'<iframescrolling="auto"frameborder="0"width="100%"height="100%"src="grid.html"></iframe>'
  147. });
  148. }
  149. contentPanel.setActiveTab(n);
  150. }
  151. }
  152. }));
  153. //添加第二个节点(autoLoad)
  154. _treepanel.root.appendChild(newExt.tree.TreeNode({
  155. id:'autoLoadPanel',
  156. text:'通过autoLoad打开',
  157. listeners:{
  158. 'click':function(node,event){
  159. event.stopEvent();
  160. varn=contentPanel.getComponent(node.id);
  161. if(!n){////判断是否已经打开该面板
  162. n=contentPanel.add({
  163. 'id':node.id,
  164. 'title':node.text,
  165. closable:true,
  166. autoLoad:{
  167. url:'tabFrame.jsp?url=grid.html',
  168. scripts:true
  169. }//通过autoLoad属性载入目标页,如果要用到脚本,必须加上scripts属性
  170. });
  171. }
  172. contentPanel.setActiveTab(n);
  173. }
  174. }
  175. }));
  176. //右边具体功能面板区
  177. varcontentPanel=newExt.TabPanel({
  178. region:'center',
  179. enableTabScroll:true,
  180. activeTab:0,
  181. items:[{
  182. id:'homePage',
  183. title:'首页',
  184. autoScroll:true,
  185. //closable:true,
  186. html:'<divclass="tabPanel-treePanel">Tree控件和TabPanel控件结合功能演示</div>'
  187. }]
  188. });
  189. newExt.Viewport({
  190. layout:'border',//使用border布局
  191. defaults:{
  192. activeItem:0
  193. },
  194. items:[_treepanel,contentPanel]
  195. });
  196. });

其实这样子就可以运行了,只是动态加载的数据无法加载进去而已。以下是从后台数据库获取json格式数据的操作。

1)建立一个树节点的bean,封装一个树节点。

2)连接数据库,做相关操作之后,以json格式数据传回_treepanel.loader.dataUrl='tree.jsp?parentId='+node.id;//定义子节点的Loader。【实际上,就是一个字符串】

3)tree.jsp

Code:
  1. <%@pagelanguage="java"pageEncoding="utf-8"%>
  2. <jsp:useBeanclass="com.xxx.javabean.JSONTree"id="JSONTree"></jsp:useBean>
  3. <%
  4. StringparentId="";
  5. if(request.getParameter("parentId")!=null){
  6. parentId=request.getParameter("parentId").toString();
  7. }
  8. JSONTree.setparentId(parentId);
  9. %>
  10. <%=JSONTree.getJSONString()%>
Code:
  1. packagecom.xxx.javabean;
  2. /**
  3. *@authornothing2012
  4. *定义树节点的属性,包括节点ID、Text、图标、是否为叶子节点、是否展开等。
  5. */
  6. publicclassJSONTreeNode{
  7. privateStringid;//ID
  8. privateStringtext;//节点显示
  9. privateStringcls;//图标
  10. privatebooleanleaf;//是否叶子
  11. privateStringhref;//链接
  12. privateStringhrefTarget;//链接指向
  13. privatebooleanexpandable;//是否展开
  14. privateStringdescription;//描述信息
  15. publicStringgetId(){
  16. returnid;
  17. }
  18. publicvoidsetId(Stringid){
  19. this.id=id;
  20. }
  21. publicStringgetText(){
  22. returntext;
  23. }
  24. publicvoidsetText(Stringtext){
  25. this.text=text;
  26. }
  27. publicStringgetCls(){
  28. returncls;
  29. }
  30. publicvoidsetCls(Stringcls){
  31. this.cls=cls;
  32. }
  33. publicbooleanisLeaf(){
  34. returnleaf;
  35. }
  36. publicvoidsetLeaf(booleanleaf){
  37. this.leaf=leaf;
  38. }
  39. publicStringgetHref(){
  40. returnhref;
  41. }
  42. publicvoidsetHref(Stringhref){
  43. this.href=href;
  44. }
  45. publicStringgetHrefTarget(){
  46. returnhrefTarget;
  47. }
  48. publicvoidsetHrefTarget(StringhrefTarget){
  49. this.hrefTarget=hrefTarget;
  50. }
  51. publicbooleanisExpandable(){
  52. returnexpandable;
  53. }
  54. publicvoidsetExpandable(booleanexpandable){
  55. this.expandable=expandable;
  56. }
  57. publicStringgetDescription(){
  58. returndescription;
  59. }
  60. publicvoidsetDescription(Stringdescription){
  61. this.description=description;
  62. }
  63. }
Code:
  1. packagecom.xxx.javabean;
  2. importjava.sql.Connection;
  3. importjava.sql.DriverManager;
  4. importjava.sql.ResultSet;
  5. importjava.sql.SQLException;
  6. importjava.sql.Statement;
  7. importjava.util.ArrayList;
  8. importjava.util.List;
  9. importnet.sf.json.JSONArray;
  10. /*
  11. *@createbynothing2012
  12. */
  13. publicclassJSONTree{
  14. privateStringparentId;
  15. publicStringgetJSONString(){
  16. Connectioncon=null;
  17. Statementst=null;
  18. ResultSetrs=null;
  19. List<JSONTreeNode>treeNodeArray=null;
  20. //传一个父节点的ID过来
  21. StringSQLString="SELECT*FROMCategoriesWHEREparentId="
  22. +this.parentId+"ORDERBYcategoryId";
  23. try{
  24. Class.forName("com.mysql.jdbc.Driver");
  25. DriverManager.registerDriver(newcom.mysql.jdbc.Driver());
  26. StringDbConn="jdbc:mysql://localhost:3306/extjs";
  27. StringDbPass="root";
  28. con=DriverManager.getConnection(DbConn,"root",DbPass);
  29. st=con.createStatement();
  30. //查找所有拥有下级类别的类别ID//不同的记录属于同一个parentID,故使用groupby
  31. rs=st
  32. .executeQuery("SELECTparentIdFROMCategoriesWHEREparentId>0GroupByparentIdOrderByparentId");
  33. StringBufferparentIDBuffer=newStringBuffer();
  34. parentIDBuffer.append("|");
  35. while(rs.next()){
  36. parentIDBuffer.append(rs.getString("parentId"));
  37. parentIDBuffer.append("|");
  38. }
  39. //得到所有的parentcategoryId列表
  40. StringparentIDString=parentIDBuffer.toString();
  41. System.out.println(parentIDString);//测试|1|2|3|4|5|6|7|8|
  42. rs=st.executeQuery(SQLString);//第一次传进来的parentID是0
  43. treeNodeArray=newArrayList<JSONTreeNode>();
  44. while(rs.next()){
  45. JSONTreeNodetreeNode=newJSONTreeNode();
  46. StringcategoryId=rs.getString("categoryId");
  47. treeNode.setId(categoryId);
  48. treeNode.setText(rs.getString("categoryName"));
  49. treeNode.setDescription(rs.getString("description"));
  50. //treeNode.setHref("rightframe.jsp?categoryId="
  51. //+rs.getString("categoryId").toString());
  52. //treeNode.setHrefTarget("rightFrame");
  53. System.out.println(parentIDString.indexOf("|"+categoryId+"|"));//测试
  54. if(parentIDString.indexOf("|"+categoryId+"|")>=0)//父节点如果大于0说它在父节点中存在
  55. {
  56. treeNode.setCls("folder");
  57. treeNode.setLeaf(false);
  58. treeNode.setExpandable(false);
  59. }else//子节点
  60. {
  61. treeNode.setCls("file");
  62. treeNode.setLeaf(true);
  63. treeNode.setExpandable(false);
  64. }
  65. treeNodeArray.add(treeNode);
  66. }
  67. JSONArrayJsonArray=JSONArray.fromObject(treeNodeArray);//得到JSON数组
  68. System.out.println("返回的数据是:"+JsonArray.toString());
  69. returnJsonArray.toString();//返回JSON数据
  70. }catch(Exceptione){
  71. System.out.println("getJSONString()ofJSONTree.javathrows:"
  72. +e.toString());
  73. return"";
  74. }finally{
  75. try{
  76. if(con!=null&&!con.isClosed()){
  77. con.close();
  78. }
  79. }catch(SQLExceptione){
  80. //TODOAuto-generatedcatchblock
  81. e.printStackTrace();
  82. }
  83. }
  84. }
  85. publicStringgetparentId(){
  86. returnparentId;
  87. }
  88. publicvoidsetparentId(StringparentId){
  89. this.parentId=parentId;
  90. }
  91. }

效果图:

//需要导入的json-lib 包及其他包自行下载。测试完毕。

分享到:
评论
2 楼 zzhyq 2012-08-15  
有没有后台是ASHX 的呀
1 楼 693593336 2012-06-25  
  谢谢作者分享,正好用上

相关推荐

Global site tag (gtag.js) - Google Analytics