Ext+Dwr动态树(增删改)

来源:互联网 发布:warframe端口 编辑:程序博客网 时间:2024/05/06 23:01

效果展示:

1.增加节点

 

2.删除节点

3.修改节点

 

技术分析:

   利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样DWR(根据Java类来动态生成JavaScrip代码).

   树是一个我们日常用的组件,EXT给我们提供了一个非常好用的树控件,对于传统HTML页面完全靠手编写代码是非常困难的,因为要编写许多JS代码,还要实现AJAX功能,使用EXT编写树我们的工作将简单方便许多.

   Ext.ux.DWRTreeLoader 是对树加载器 Ext.tree.TreeLoader 的扩展 ,实现了通过DWR直接调用后台JAVA类方法,将树结点返回到前台,除此之外,还支持对树进行查找时,将查找参数直接传给后台JAVA类方法.

 

具体JS代码实现:

[javascript] view plaincopyprint?
  1. // 全局路径  
  2. var basePath = "http://localhost:8080/exttree";  
  3. if(typeof(glbRootPath) != "undefined"){  
  4.     basePath = glbRootPath;  
  5. }  
  6. // 扩展窗体  
  7. FormEditWin = function(){  
  8.     var curFormWin;  
  9.     return {  
  10.         width : 600,  
  11.         height : 400,  
  12.         showAddDirWin : function(parentNode) {  
  13.             // 显示添加子目录窗口  
  14.             var number = parentNode.indexOf(parentNode.lastChild) + 1;  
  15.             var editpage = basePath  
  16.                     + "/navigateedit?parentId="  
  17.                     + parentNode.id + "&leaf=0&number=" + number;  
  18.             var window = this.createWin("windirnew""新建目录节点", editpage, function() {  
  19.                 parentNode.reload();  
  20.             });  
  21.             window.show();  
  22.         },  
  23.         showAddLeafWin : function(parentNode) {  
  24.             // 显示添加子叶子节点窗口  
  25.             var number = parentNode.indexOf(parentNode.lastChild) + 1;  
  26.             var editpage = basePath  
  27.                     + "/navigateedit?parentId="  
  28.                     + parentNode.id + "&leaf=1&number=" + number;  
  29.             var window = this.createWin("winleafnew""新建叶子节点", editpage, function() {  
  30.                 parentNode.reload();  
  31.             });  
  32.             window.show();  
  33.         },  
  34.         showEditDirWin : function(node) {  
  35.             // 显示目录编辑窗口  
  36.             var editpage = basePath  
  37.                     + "/navigateedit?id=" + node.id;  
  38.             var window = this.createWin("win" + node.id, node.text, editpage, function() {  
  39.                 var nodeparent = node.parentNode;  
  40.                 var tree = node.getOwnerTree();  
  41.                 nodeparent.on("expand"function(pnode) {  
  42.                     tree.getNodeById(node.id).select();  
  43.                 }, this, {  
  44.                     single : true  
  45.                 });  
  46.                 node.parentNode.reload();  
  47.             });  
  48.             window.show();  
  49.         },  
  50.         showEditLeafWin : function(node) {  
  51.             // 显示叶子节点编辑窗口  
  52.             var editpage = basePath  
  53.                     + "/navigateedit?id=" + node.id;  
  54.             var window = this.createWin("win" + node.id, node.text, editpage, function() {  
  55.                 var nodeparent = node.parentNode;  
  56.                 var tree = node.getOwnerTree();  
  57.                 nodeparent.on("expand"function(pnode) {  
  58.                     tree.getNodeById(node.id).select();  
  59.                 }, this, {  
  60.                     single : true  
  61.                 });  
  62.                 node.parentNode.reload();  
  63.             });  
  64.             window.show();  
  65.         },  
  66.         createWin : function(winId, winTitle, iframePage, closeFun) {  
  67.             // 供各类型窗口创建时调用  
  68.             var win = Ext.getCmp(winId);  
  69.             if (!win) {  
  70.                 win = new Ext.Window({  
  71.                     id : winId,  
  72.                     title : "菜单编辑窗口-" + winTitle,  
  73.                     width : this.width,  
  74.                     height : this.height,  
  75.                     maximizable : true,  
  76.                     modal : true,  
  77.                     html : "<iframe width='100%' height='100%' frameborder='0' src='"  
  78.                             + iframePage + "'></iframe>"  
  79.                 });  
  80.                 this.reloadNavNode = closeFun;  
  81.             }  
  82.             curFormWin = win;  
  83.             return win;  
  84.         },  
  85.         reloadNavNode : function() {  
  86.         },  
  87.         close : function() {  
  88.             if(curFormWin){  
  89.                 curFormWin.close();  
  90.             }  
  91.         }  
  92.     }  
  93. }();  
  94.   
  95. // 导航树  
  96. NavTree = function(){  
  97.     var nav;  
  98.     var navEditor;  
  99.     var leafMenu;  
  100.     var dirMenu;  
  101.     var loader;  
  102.     var root;  
  103.     var removeFlag = false;  
  104.     var titleChangeFlag = false;  
  105.     var nodeSelected;  
  106.     var mgr;  
  107.     return {  
  108.         init : function(){  
  109.             if(!mgr){  
  110.                 Ext.Msg.alert("警告提示","请先通过NavTree.setMgr()设置mgr");  
  111.                 return;  
  112.             }  
  113.             if(!loader){  
  114.                 loader = new Ext.tree.TreeLoader({  
  115.                     url : basePath + '/navigatejson'  
  116.                 });  
  117.                 loader.on('beforeload'function(treeloader, node) {  
  118.                     treeloader.baseParams = {  
  119.                         id : node.id,  
  120.                         method : 'tree'  
  121.                     };  
  122.                 }, this);  
  123.             }  
  124.             if(!root){  
  125.                 root = new Ext.tree.AsyncTreeNode({  
  126.                     id : '0',  
  127.                     text : "系统菜单"  
  128.                 });  
  129.             }  
  130.             if(!nav){  
  131.                 nav = new Ext.tree.TreePanel({  
  132.                     title : "左部导航",  
  133.                     width : 232,  
  134.                     autoScroll : true,  
  135.                     animate : true,  
  136.                     loader : loader,  
  137.                     root : root,  
  138.                     enableDD : true,  
  139.                     listeners : {  
  140.                         'click' : function(node, event) {  
  141.                             if (!node.isLeaf()) {  
  142.                                 // 为目录节点时,点击不进入链接  
  143.                                 event.stopEvent();  
  144.                             }  
  145.                         }  
  146.                     }  
  147.                 });  
  148.                 //事件: 添加右键菜单  
  149.                 nav.on("contextmenu"this.showTreeMenu);  
  150.                 //事件: 当节点文本改变时触发 异步更新标题  
  151.                 nav.on("textchange"function(node, newText, oldText) {  
  152.                     if (!titleChangeFlag && newText != oldText) {  
  153.                         mgr.ajaxUpdateTitle(node.id, newText, function(success) {  
  154.                             if (!success) {  
  155.                                 Ext.Msg.show({  
  156.                                     title : "操作失败!",  
  157.                                     msg : "菜单修改失败!",  
  158.                                     buttons : Ext.Msg.OK,  
  159.                                     icon : Ext.MessageBox.ERROR  
  160.                                 });  
  161.                                 titleChangeFlag = true;  
  162.                                 node.setText(oldText);  
  163.                                 titleChangeFlag = false;  
  164.                             }  
  165.                         });  
  166.                     }  
  167.                 });  
  168.                 //事件: 当节点移动时触发  
  169.                 nav.on("movenode"function(tree, node, oldParent, newParent, index) {  
  170.                     mgr.ajaxMoveNode(node.id, oldParent.id, newParent.id, index);  
  171.                 });  
  172.                 //事件: 当节点删除时触发  
  173.                 nav.on("remove"function(tree, parentNode, node) {  
  174.                     if (removeFlag) {  
  175.                         mgr.ajaxRemoveNode(node.id);  
  176.                     }  
  177.                 });  
  178.             }  
  179. /*  事件:  节点选中单击编辑    
  180.             if(!navEditor){ 
  181.                 navEditor = new Ext.tree.TreeEditor(nav, { 
  182.                     allowBlank : false, 
  183.                     ignoreNoChange : true, 
  184.                     completeOnEnter : true, 
  185.                     blankText : '标题不能为空', 
  186.                     selectOnFocus : true 
  187.                 }); 
  188.             }  */  
  189.             this.setLeafMenu();// 设置叶子菜单  
  190.             this.setDirMenu();// 设置目录菜单  
  191.         },  
  192.         setMgr : function(manager){  
  193.             mgr = manager;  
  194.         },  
  195.         getMgr : function(){  
  196.             return mgr;  
  197.         },  
  198.         // 设置叶子菜单  
  199.         setLeafMenu: function(){  
  200.             if(!leafMenu){  
  201.                 leafMenu = new Ext.menu.Menu({  
  202.                     items : [{  
  203.                         text : "修改标题",  
  204.                         handler : function() {  
  205.                             navEditor = new Ext.tree.TreeEditor(nav, {  
  206.                                 allowBlank : false,  
  207.                                 ignoreNoChange : true,  
  208.                                 completeOnEnter : true,  
  209.                                 blankText : '标题不能为空',  
  210.                                 selectOnFocus : true  
  211.                             });  
  212.                             navEditor.triggerEdit(nodeSelected);  
  213.                         }  
  214.                     }, "-", {  
  215.                         text : "编辑",  
  216.                         handler : function() {  
  217.                             FormEditWin.showEditLeafWin(nodeSelected);  
  218.                         }  
  219.                     }, "-", {  
  220.                         text : "删除",  
  221.                         handler : this.delTreeItemComfirm  
  222.                     }]  
  223.                 });  
  224.             }  
  225.         },  
  226.         // 设置目录菜单  
  227.         setDirMenu: function(){  
  228.             if(!dirMenu){  
  229.                 dirMenu = new Ext.menu.Menu({  
  230.                     items : [{  
  231.                         text : "修改标题",  
  232.                         handler : function() {  
  233.                             navEditor = new Ext.tree.TreeEditor(nav, {  
  234.                                 allowBlank : false,  
  235.                                 ignoreNoChange : true,  
  236.                                 completeOnEnter : true,  
  237.                                 blankText : '标题不能为空',  
  238.                                 selectOnFocus : true  
  239.                             });  
  240.                             navEditor.triggerEdit(nodeSelected);  
  241.                         }  
  242.                     }, "-", {  
  243.                         text : "编辑",  
  244.                         handler : function() {  
  245.                             FormEditWin.showEditDirWin(nodeSelected);  
  246.                         }  
  247.                     }, "-", {  
  248.                         text : "添加叶子节点",  
  249.                         handler : function() {  
  250.                             FormEditWin.showAddLeafWin(nodeSelected);  
  251.                         }  
  252.                     }, "-", {  
  253.                         text : "添加目录节点",  
  254.                         handler : function() {  
  255.                             FormEditWin.showAddDirWin(nodeSelected);  
  256.                         }  
  257.                     }, "-", {  
  258.                         text : "删除",  
  259.                         handler : this.delTreeItemComfirm  
  260.                     }]  
  261.                 });  
  262.             }  
  263.         },  
  264.         showTreeMenu : function(node, e){  
  265.             nodeSelected = node;  
  266.             nodeSelected.select();  
  267.             if (node.isLeaf()) {  
  268.                 // 显示叶子节点菜单  
  269.                 leafMenu.showAt(e.getPoint());  
  270.             } else {  
  271.                 // 显示目录节点菜单  
  272.                 dirMenu.showAt(e.getPoint());  
  273.             }  
  274.         },  
  275.         delTreeItemComfirm : function(){  
  276.             Ext.Msg.confirm("确认删除""确定要删除所选节点吗?"function(btn) {  
  277.                 if (btn == "yes") {  
  278.                     NavTree.delTreeItem();  
  279.                 }  
  280.             });  
  281.         },  
  282.         delTreeItem : function(){  
  283.             if (nodeSelected != nav.getRootNode()) {  
  284.                 removeFlag = true;  
  285.                 nodeSelected.remove();  
  286.                 removeFlag = false;  
  287.             } else {  
  288.                 Ext.Msg.alert("警告""不能删除树的根节点!");  
  289.             }  
  290.         },  
  291.         show : function(){  
  292.             nav.render(Ext.getBody());  
  293.             nav.getRootNode().toggle();  
  294.         }  
  295.     }  
  296. }();  
  297.   
  298. // 文档加载完毕执行  
  299. Ext.onReady(function(){  
  300.     Ext.BLANK_IMAGE_URL = "../scripts/ext/resources/images/default/s.gif";  
  301.     if(typeof(NavigateManager)=="undefined"){  
  302.         Ext.Msg.alert("警告提示","请先设置DWR,并实例化NavigateManager");  
  303.     }else{  
  304.         NavTree.setMgr(NavigateManager);  
  305.         NavTree.init();  
  306.         NavTree.show();  
  307.     }  
  308. });  

 

servlet 配置:

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.4"   
  3.     xmlns="http://java.sun.com/xml/ns/j2ee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
  6.     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  7.   <servlet>  
  8.         <servlet-name>navigatejson</servlet-name>  
  9.         <servlet-class>  
  10.             com.demo.navigate.web.NavigateJsonServlet  
  11.         </servlet-class>  
  12.     </servlet>  
  13.     <servlet>  
  14.         <servlet-name>navigateedit</servlet-name>  
  15.         <servlet-class>  
  16.             com.demo.navigate.web.NavigateEditServlet  
  17.         </servlet-class>  
  18.     </servlet>  
  19.     <servlet>  
  20.         <servlet-name>navigatesave</servlet-name>  
  21.         <servlet-class>  
  22.             com.demo.navigate.web.NavigateSaveServlet  
  23.         </servlet-class>  
  24.     </servlet>  
  25.     <servlet-mapping>  
  26.         <servlet-name>navigatejson</servlet-name>  
  27.         <url-pattern>/navigatejson</url-pattern>  
  28.     </servlet-mapping>  
  29.     <servlet-mapping>  
  30.         <servlet-name>navigateedit</servlet-name>  
  31.         <url-pattern>/navigateedit</url-pattern>  
  32.     </servlet-mapping>  
  33.     <servlet-mapping>  
  34.         <servlet-name>navigatesave</servlet-name>  
  35.         <url-pattern>/navigatesave</url-pattern>  
  36.     </servlet-mapping>  
  37.     <servlet>  
  38.         <servlet-name>dwr-invoker</servlet-name>  
  39.         <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>  
  40.         <init-param>  
  41.             <param-name>debug</param-name>  
  42.             <param-value>true</param-value>  
  43.         </init-param>  
  44.         <init-param>  
  45.             <param-name>  
  46.                 allowGetForSafariButMakeForgeryEasier  
  47.             </param-name>  
  48.             <param-value>true</param-value>  
  49.         </init-param>  
  50.         <load-on-startup>1</load-on-startup>  
  51.     </servlet>  
  52.     <servlet-mapping>  
  53.         <servlet-name>dwr-invoker</servlet-name>  
  54.         <url-pattern>/dwr/*</url-pattern>  
  55.     </servlet-mapping>  
  56.     <welcome-file-list>  
  57.         <welcome-file>index.jsp</welcome-file>  
  58.     </welcome-file-list>  
  59. </web-app>  


DWR配置:

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr//dwr20.dtd">  
  3.   
  4. <dwr>  
  5.     <allow>  
  6.         <create javascript="NavigateManager" creator="new">  
  7.             <param name="class"  
  8.                 value="com.demo.navigate.service.NavigateManager">  
  9.             </param>  
  10.             <include method="ajaxUpdateTitle" />  
  11.             <include method="ajaxRemoveNode" />  
  12.             <include method="ajaxMoveNode" />  
  13.         </create>  
  14.     </allow>  
  15. </dwr>  


servlet程序:

[java] view plaincopyprint?
  1. package com.demo.navigate.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import com.demo.navigate.model.Navigate;  
  12. import com.demo.navigate.service.NavigateManager;  
  13.   
  14. @SuppressWarnings("serial")  
  15. public class NavigateSaveServlet extends HttpServlet {  
  16.       
  17.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         this.doPost(request, response);  
  20.     }  
  21.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  22.             throws ServletException, IOException {  
  23.         NavigateManager navigateManager = new NavigateManager();  
  24.         Navigate obj = null;  
  25.         request.setCharacterEncoding("UTF-8");  
  26.         String id = request.getParameter("id");  
  27.         String number = request.getParameter("number");  
  28.         String parentId = request.getParameter("parentId");  
  29.         String leaf = request.getParameter("leaf");  
  30.         String title = request.getParameter("title");  
  31.         String url = request.getParameter("url");  
  32.           
  33.         if(null != id && !"".equals(id)){  
  34.             obj = navigateManager.get(id);  
  35.             if(obj == null){  
  36.                 RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/error.jsp");  
  37.                 dispatcher.forward(request, response);  
  38.                 return;  
  39.             }  
  40.         }else{  
  41.             obj = new Navigate();  
  42.             obj.setLeaf(new Integer(leaf));  
  43.             obj.setParentId(new Integer(parentId));  
  44.         }  
  45.         obj.setNumber(new Integer(number));  
  46.         obj.setTitle(title);  
  47.         obj.setUrl(url);  
  48.         if(null != id && !"".equals(id)){  
  49.             navigateManager.update(obj);  
  50.         }else{  
  51.             navigateManager.save(obj);  
  52.         }  
  53.         RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/success.jsp");  
  54.         dispatcher.forward(request, response);        
  55.     }  
  56.   
  57. }  
[java] view plaincopyprint?
  1. package com.demo.navigate.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import com.demo.navigate.service.NavigateManager;  
  12.   
  13. @SuppressWarnings("serial")  
  14. public class NavigateJsonServlet extends HttpServlet {  
  15.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  16.             throws ServletException, IOException {  
  17.         this.doPost(request, response);  
  18.     }  
  19.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  20.             throws ServletException, IOException {  
  21.   
  22.         NavigateManager navigateManager = new NavigateManager();  
  23.         request.setAttribute("list", navigateManager.getChildrenById(new Integer(request.getParameter("id"))));  
  24.         RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/console-json.jsp");  
  25.         dispatcher.forward(request, response);  
  26.     }  
  27.   
  28. }  
[java] view plaincopyprint?
  1. package com.demo.navigate.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.RequestDispatcher;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import com.demo.navigate.model.Navigate;  
  12. import com.demo.navigate.service.NavigateManager;  
  13.   
  14. @SuppressWarnings("serial")  
  15. public class NavigateEditServlet extends HttpServlet {  
  16.       
  17.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         this.doPost(request, response);  
  20.     }  
  21.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  22.             throws ServletException, IOException {  
  23.         String idstr = request.getParameter("id");  
  24.         String parentId = request.getParameter("parentId");  
  25.         String leaf = request.getParameter("leaf");  
  26.         String number = request.getParameter("number");  
  27.         Navigate obj = null;  
  28.         if(null != idstr){  
  29.             NavigateManager navigateManager = new NavigateManager();  
  30.             obj = navigateManager.get(idstr);  
  31.         }else{  
  32.             obj = new Navigate();  
  33.             obj.setParentId(new Integer(parentId));  
  34.             obj.setLeaf(new Integer(leaf));  
  35.             obj.setNumber(new Integer(number));  
  36.         }  
  37.         request.setAttribute("obj", obj);  
  38.         RequestDispatcher dispatcher = request.getRequestDispatcher("/navigate/console-edit.jsp");  
  39.         dispatcher.forward(request, response);  
  40.     }  
  41. }  


service程序:

[java] view plaincopyprint?
  1. package com.demo.navigate.service;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. import com.demo.navigate.dao.NavigateDao;  
  7. import com.demo.navigate.model.Navigate;  
  8.   
  9. public class NavigateManager {  
  10.     private NavigateDao dao = NavigateDao.getInstanece();  
  11.     public Navigate get(Serializable id){  
  12.         return dao.get(id);  
  13.     }  
  14.     /** 
  15.      * 获得指定节点的所有儿子节点 
  16.      * @param id 
  17.      */  
  18.     @SuppressWarnings("unchecked")  
  19.     public List<Navigate> getChildrenById(Integer id){  
  20.         return dao.getChildrenById(id);  
  21.     }  
  22.     /** 
  23.      * 保存数据 
  24.      * @param obj  
  25.      */  
  26.     public void save(Navigate obj){  
  27.         dao.save(obj);  
  28.     }  
  29.     /** 
  30.      * 更新数据 
  31.      * @param obj  
  32.      */  
  33.     public void update(Navigate obj){  
  34.         dao.update(obj);  
  35.     }  
  36.     /** 
  37.      * 删除指定的一条数据 
  38.      * @param id 
  39.      */  
  40.     public void removeById(Integer id){  
  41.         dao.removeById(id);  
  42.     }  
  43.     /** 
  44.      * 异步更新标题 
  45.      * @param id 
  46.      * @param title 
  47.      * @return true-修改成功 false-修改失败 
  48.      */  
  49.     public Boolean ajaxUpdateTitle(Integer id,String title){  
  50.         return dao.ajaxUpdateTitle(id, title);  
  51.     }  
  52.     /** 
  53.      * 异步删除数据,包括其子孙节点 
  54.      * @param id 
  55.      * @param title 
  56.      */  
  57.     public void ajaxRemoveNode(Integer id){  
  58.         Navigate obj = dao.get(id);  
  59.         dao.downNode(obj.getParentId(), obj.getNumber(), -1);  
  60.         dao.ajaxRemoveNode(id);  
  61.     }  
  62.     /** 
  63.      * 异步移动指定节点 
  64.      * @param id    指定的节点的id 
  65.      * @param oldParentId   节点移动前所在的父节点 
  66.      * @param newParentId   节点移动后的目标父节点 
  67.      * @param nodeIndex     节点移动后的目标位置 
  68.      */  
  69.     public void ajaxMoveNode(int id, int oldParentId, int newParentId, int nodeIndex){  
  70.         dao.ajaxMoveNode(id, oldParentId, newParentId, nodeIndex);  
  71.     }  
  72. }  


model程序:


 

[java] view plaincopyprint?
  1. package com.demo.navigate.model;  
  2.   
  3. public class Navigate {  
  4.     private Integer id;  
  5.     private Integer parentId;  
  6.     private String title;  
  7.     private Integer number;  
  8.     private Integer leaf;  
  9.     private String url;  
  10.     public Integer getId() {  
  11.         return id;  
  12.     }  
  13.     public void setId(Integer id) {  
  14.         this.id = id;  
  15.     }  
  16.     public Integer getParentId() {  
  17.         return parentId;  
  18.     }  
  19.     public void setParentId(Integer parentId) {  
  20.         this.parentId = parentId;  
  21.     }  
  22.     public String getTitle() {  
  23.         return title;  
  24.     }  
  25.     public void setTitle(String title) {  
  26.         this.title = title;  
  27.     }  
  28.     public Integer getNumber() {  
  29.         return number;  
  30.     }  
  31.     public void setNumber(Integer number) {  
  32.         this.number = number;  
  33.     }  
  34.     public Integer getLeaf() {  
  35.         return leaf;  
  36.     }  
  37.     public void setLeaf(Integer leaf) {  
  38.         this.leaf = leaf;  
  39.     }  
  40.     public String getUrl() {  
  41.         return url;  
  42.     }  
  43.     public void setUrl(String url) {  
  44.         this.url = url;  
  45.     }     
  46. }  


Dao程序:

[java] view plaincopyprint?
  1. package com.demo.navigate.dao;  
  2.   
  3. import java.io.Serializable;  
  4. import java.sql.Connection;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7. import java.sql.Statement;  
  8. import java.util.ArrayList;  
  9. import java.util.List;  
  10.   
  11. import com.demo.core.dao.DBConn;  
  12. import com.demo.navigate.model.Navigate;  
  13.   
  14. public class NavigateDao {  
  15.     private static NavigateDao dao;  
  16.     private NavigateDao(){        
  17.     }     
  18.     public static NavigateDao getInstanece(){  
  19.         if(null == dao){  
  20.             dao = new NavigateDao();  
  21.         }  
  22.         return dao;  
  23.     }  
  24.     /** 
  25.      * 获得指定ID的数据 
  26.      * @param id 
  27.      * @return 
  28.      */  
  29.     public Navigate get(Serializable id){  
  30.         Connection conection = null;  
  31.         Statement stmt = null;  
  32.         ResultSet rs = null;  
  33.         Navigate obj = null;  
  34.         try{  
  35.             conection = DBConn.getConnection();   
  36.             stmt = conection.createStatement();  
  37.             StringBuffer sql = new StringBuffer("select * from navigate where id = ");  
  38.             sql.append(id);  
  39.             rs = stmt.executeQuery(sql.toString());  
  40.             if(rs.next())  
  41.             {  
  42.                 obj = new Navigate();  
  43.                 obj.setId(rs.getInt("id"));  
  44.                 obj.setLeaf(rs.getInt("leaf"));  
  45.                 obj.setNumber(rs.getInt("number"));  
  46.                 obj.setParentId(rs.getInt("parentId"));  
  47.                 obj.setTitle(rs.getString("title"));  
  48.                 obj.setUrl(rs.getString("url"));  
  49.             }  
  50.         }catch(Exception e){  
  51.             e.printStackTrace();              
  52.         }finally{  
  53.             try{  
  54.                 if(rs != null) {  
  55.                     try {  
  56.                         rs.close();  
  57.                     } catch (SQLException e) {  
  58.                     }  
  59.                     rs = null;  
  60.                 }                 
  61.                 if (stmt != null) {  
  62.                     try {  
  63.                         stmt.close();  
  64.                     } catch (SQLException sqlex) {  
  65.                     }  
  66.                     stmt = null;  
  67.                 }  
  68.                 if (conection != null) {  
  69.                     try {  
  70.                         conection.close();  
  71.                     } catch (SQLException sqlex) {  
  72.                     }  
  73.                     conection = null;  
  74.                 }  
  75.             }catch(Exception e){  
  76.                 e.printStackTrace();  
  77.             }  
  78.         }  
  79.         return obj;  
  80.     }  
  81.       
  82.     /** 
  83.      * 获得指定节点的所有儿子节点 
  84.      * @param id 
  85.      */  
  86.     @SuppressWarnings("unchecked")  
  87.     public List<Navigate> getChildrenById(Integer id){  
  88.         List<Navigate> list = new ArrayList<Navigate>();  
  89.         Connection conection = null;  
  90.         Statement stmt = null;  
  91.         ResultSet rs = null;  
  92.         try{  
  93.             conection = DBConn.getConnection();   
  94.             stmt = conection.createStatement();  
  95.             StringBuffer sql = new StringBuffer("select * from navigate where parentId = ");  
  96.             sql.append(id);  
  97.             sql.append(" order by number,id");  
  98.             System.out.println("首页加载树SQL=="+sql.toString());  
  99.             rs = stmt.executeQuery(sql.toString());  
  100.             while(rs.next())  
  101.             {  
  102.                 Navigate obj = new Navigate();  
  103.                 obj.setId(rs.getInt("id"));  
  104.                 obj.setLeaf(rs.getInt("leaf"));  
  105.                 obj.setNumber(rs.getInt("number"));  
  106.                 obj.setParentId(rs.getInt("parentId"));  
  107.                 obj.setTitle(rs.getString("title"));  
  108.                 obj.setUrl(rs.getString("url"));  
  109.                 list.add(obj);  
  110.             }  
  111.         }catch(Exception e){  
  112.             e.printStackTrace();              
  113.         }finally{  
  114.             try{  
  115.                 if(rs != null) {  
  116.                     try {  
  117.                         rs.close();  
  118.                     } catch (SQLException e) {  
  119.                     }  
  120.                     rs = null;  
  121.                 }                 
  122.                 if (stmt != null) {  
  123.                     try {  
  124.                         stmt.close();  
  125.                     } catch (SQLException sqlex) {  
  126.                     }  
  127.                     stmt = null;  
  128.                 }  
  129.                 if (conection != null) {  
  130.                     try {  
  131.                         conection.close();  
  132.                     } catch (SQLException sqlex) {  
  133.                     }  
  134.                     conection = null;  
  135.                 }  
  136.             }catch(Exception e){  
  137.                 e.printStackTrace();  
  138.             }  
  139.         }  
  140.         return list;  
  141.     }  
  142.       
  143.     /** 
  144.      * 保存数据 
  145.      * @param obj  
  146.      */  
  147.     public void save(Navigate obj){  
  148.         StringBuffer sql = new StringBuffer("insert into navigate(parentId,title,leaf,number,url) values(");  
  149.         sql.append(obj.getParentId());  
  150.         sql.append(",'");  
  151.         sql.append(obj.getTitle());  
  152.         sql.append("',");  
  153.         sql.append(obj.getLeaf());  
  154.         sql.append(",");  
  155.         sql.append(obj.getNumber());  
  156.         sql.append(",'");  
  157.         sql.append(obj.getUrl());  
  158.         sql.append("')");  
  159.         this.bulkUpdate(sql.toString());  
  160.     }  
  161.       
  162.     /** 
  163.      * 更新数据 
  164.      * @param obj  
  165.      */  
  166.     public void update(Navigate obj){  
  167.         StringBuffer sql = new StringBuffer("update navigate set");  
  168.         sql.append(" parentId = ");  
  169.         sql.append(obj.getParentId());  
  170.         sql.append(",");  
  171.         sql.append(" title = '");  
  172.         sql.append(obj.getTitle());  
  173.         sql.append("',");  
  174.         sql.append(" leaf = ");  
  175.         sql.append(obj.getLeaf());  
  176.         sql.append(",");  
  177.         sql.append(" number = ");  
  178.         sql.append(obj.getNumber());  
  179.         sql.append(", url = '");  
  180.         sql.append(obj.getUrl());  
  181.         sql.append("' where id = ");  
  182.         sql.append(obj.getId());  
  183.         this.bulkUpdate(sql.toString());  
  184.     }  
  185.       
  186.     /** 
  187.      * 异步更新标题 
  188.      * @param id 
  189.      * @param title 
  190.      * @return true-修改成功 false-修改失败 
  191.      */  
  192.     public Boolean ajaxUpdateTitle(Integer id,String title){  
  193.         Boolean flag = false;  
  194.         Navigate obj = this.get(id);  
  195.         if(null != obj){  
  196.             StringBuffer sql = new StringBuffer("update navigate set");  
  197.             sql.append(" title = '");  
  198.             sql.append(title);  
  199.             sql.append("'");  
  200.             sql.append(" where id = ");  
  201.             sql.append(id);  
  202.             this.bulkUpdate(sql.toString());  
  203.             flag = true;  
  204.         }  
  205.         return flag;  
  206.     }  
  207.       
  208.     /** 
  209.      * 删除指定的一条数据 
  210.      * @param id 
  211.      */  
  212.     public void removeById(Integer id){  
  213.         StringBuffer sql = new StringBuffer("delete from navigate where id = ");  
  214.         sql.append(id);  
  215.         this.bulkUpdate(sql.toString());  
  216.     }  
  217.       
  218.     /** 
  219.      * 异步删除数据,包括其子孙节点 
  220.      * @param id 
  221.      * @param title 
  222.      */  
  223.     @SuppressWarnings("unchecked")  
  224.     public void ajaxRemoveNode(Integer id){  
  225.         List list = this.getChildrenById(id);  
  226.         for (Object object : list) {  
  227.             Navigate obj = (Navigate)object;  
  228.             ajaxRemoveNode(obj.getId());  
  229.         }  
  230.         this.removeById(id);  
  231.     }  
  232.       
  233.     /** 
  234.      * 移动指定节点 
  235.      * @param id    指定的节点的id 
  236.      * @param oldParentId   节点移动前所在的父节点 
  237.      * @param newParentId   节点移动后的目标父节点 
  238.      * @param nodeIndex     节点移动后的目标位置 
  239.      */  
  240.     public void ajaxMoveNode(int id, int oldParentId, int newParentId, int nodeIndex){  
  241.         Navigate obj = this.get(id);  
  242.         int minIndex = obj.getNumber().intValue();  
  243.         int maxIndex = nodeIndex;  
  244.         if(oldParentId == newParentId && minIndex != maxIndex){  
  245.             // 在同一个父节点下发生移动  
  246.             if(minIndex < maxIndex){  
  247.                 // 当要移动的节点的序号小于要移动到的目标序号,则下移  
  248.                 this.downNode(oldParentId, minIndex, maxIndex);  
  249.             }else if(minIndex > maxIndex){  
  250.                 // 当要移动的节点的序号大于要移动到的目标序号,则上移  
  251.                 maxIndex = minIndex;  
  252.                 minIndex = nodeIndex;  
  253.                 this.upNode(oldParentId, minIndex, maxIndex);  
  254.             }  
  255.             // 节点本身的序号设置成要移动到的目标序号  
  256.             obj.setNumber(nodeIndex);  
  257.             this.update(obj);  
  258.         }  
  259.         if(oldParentId != newParentId){  
  260.             // 在不同父节点下发生移动  
  261.             //1、相当于要移动的节点在原父节点下下移到最后再删除掉,因此要指定移动发生时节点所在的位置  
  262.             this.downNode(oldParentId, minIndex, -1);  
  263.             //2、相当于要移动的节点在新父节点下上移到指定的位置,因此需要指定要移动到的位置  
  264.             this.upNode(newParentId, maxIndex, -1);  
  265.             // 节点本身的序号设置成要移动到的目标序号  
  266.             obj.setNumber(nodeIndex);  
  267.             obj.setParentId(newParentId);  
  268.             this.update(obj);  
  269.         }  
  270.     }  
  271.     /** 
  272.      * 指定的节点下移 
  273.      * @param parentId  指定范围内要移动的节点的父节点 
  274.      * @param minIndex  指定节点移动发生时所在的位置 
  275.      * @param maxIndex  指定节点要移动到的目标位置 
  276.      */  
  277.     @SuppressWarnings("unchecked")  
  278.     public void downNode(int parentId, int minIndex, int maxIndex){  
  279.         // 指定的节点下移,意味着其范围内的节点各自减1  
  280.         StringBuffer sql = new StringBuffer("update navigate set number=number-1 where parentId = ");  
  281.         sql.append(parentId);  
  282.         if(maxIndex != -1){  
  283.             sql.append(" and number <= ");  
  284.             sql.append(maxIndex);  
  285.         }  
  286.         if(minIndex != -1){  
  287.             sql.append(" and number > ");  
  288.             sql.append(minIndex);  
  289.         }         
  290.         this.bulkUpdate(sql.toString());  
  291.     }  
  292.     /** 
  293.      * 指定的节点上移 
  294.      * @param parentId  指定范围内要移动的节点的父节点 
  295.      * @param minIndex  指定节点要移动到的目标位置 
  296.      * @param maxIndex  指定节点移动发生时所在的位置 
  297.      */  
  298.     @SuppressWarnings("unchecked")  
  299.     public void upNode(int parentId, int minIndex, int maxIndex){  
  300.         // 指定的节点上移,意味着其范围内的节点各自加1  
  301.         StringBuffer sql = new StringBuffer("update navigate set number=number+1 where parentId = ");  
  302.         sql.append(parentId);  
  303.         if(maxIndex != -1){  
  304.             sql.append(" and number < ");  
  305.             sql.append(maxIndex);  
  306.         }  
  307.         if(minIndex != -1){  
  308.             sql.append(" and number >= ");  
  309.             sql.append(minIndex);  
  310.         }  
  311.         this.bulkUpdate(sql.toString());  
  312.     }  
  313.     /** 
  314.      * 批量更新或删除操作 
  315.      * @param sql 
  316.      */  
  317.     public void bulkUpdate(String sql){  
  318.         Connection conection = null;  
  319.         Statement stmt = null;  
  320.         try{  
  321.             conection = DBConn.getConnection();   
  322.             stmt = conection.createStatement();  
  323.             stmt.executeUpdate(sql);  
  324.         }catch(Exception e){  
  325.             e.printStackTrace();              
  326.         }finally{  
  327.             try{          
  328.                 if (stmt != null) {  
  329.                     try {  
  330.                         stmt.close();  
  331.                     } catch (SQLException sqlex) {  
  332.                     }  
  333.                     stmt = null;  
  334.                 }  
  335.                 if (conection != null) {  
  336.                     try {  
  337.                         conection.close();  
  338.                     } catch (SQLException sqlex) {  
  339.                     }  
  340.                     conection = null;  
  341.                 }  
  342.             }catch(Exception e){  
  343.                 e.printStackTrace();  
  344.             }  
  345.         }  
  346.     }  
  347. }  
[java] view plaincopyprint?
  1. package com.demo.core.dao;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5.   
  6. public class DBConn {  
  7.   
  8.     private static  String url = "jdbc:mysql://localhost:3306/langsin";  
  9.     private static  String username = "root";  
  10.     private static  String password = "tiger";  
  11.     private static  String driver = "com.mysql.jdbc.Driver";  
  12.       
  13.     public static Connection getConnection(){  
  14.         Connection conn = null;  
  15.         try{  
  16.             Class.forName(driver);  
  17.             conn = DriverManager.getConnection(url,username,password);  
  18.         }catch(Exception e){  
  19.             e.printStackTrace();  
  20.         }  
  21.         return conn;  
  22.     }  
  23. }  


数据库脚本:

[sql] view plaincopyprint?
  1. create table navigate(  
  2. id int primary key auto_increment,  
  3. leaf int not null,  
  4. number int not null,  
  5. parentId int not null,  
  6. title varchar(50) not null,  
  7. url varchar(200) not null  
  8. );  


页面:

[html] view plaincopyprint?
  1. <%@ page contentType="text/html;charset=UTF-8" %>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %><html>  
  6. <head>  
  7.     <title>导航控制</title>  
  8.     <link rel="stylesheet" type="text/css" href="../scripts/ext/resources/css/ext-all.css">  
  9.     <script type="text/javascript" src="<%=basePath%>/scripts/ext/adapter/ext/ext-base.js"></script>  
  10.     <script type="text/javascript" src="<%=basePath%>/scripts/ext/ext-all.js"></script>  
  11.     <script type="text/javascript" src="<%=basePath%>/dwr/engine.js"></script>  
  12.     <script type="text/javascript" src="<%=basePath%>/dwr/util.js"></script>  
  13.     <script type="text/javascript" src="<%=basePath%>/dwr/interface/NavigateManager.js"></script>  
  14.     <script type="text/javascript">  
  15.          var glbRootPath = "<%=basePath%>";  
  16.     </script>  
  17.     <script type="text/javascript" src="<%=basePath%>/scripts/navigate/console-index.js"></script>  
  18. </head>  
  19. <body>  
  20. </body>  
  21. </html>