无为清净楼资源网 Design By www.qnjia.com
看了“使用hibernate实现树形结构无限级分类”这篇文章后,我也想将自己在所有开发的项目中使用的功能模块树的实现方法以及完整DEMO(含源码)贴出来和大家分享。其实在我的博客里是老早贴出来的,由于时间关系没好好整理。
功能模块树是几乎在每个项目里都要用到的东西,利用Dojo的好处就是可以实现树的子节点的动态加载,这在树节点很多的情况下是很有用的。
下载附件二dojotree.rar,解压后将dist\dojotree.war部署到应用服务器即可浏览DEMO,DEMO中内置HSQLDB数据库,启动时自动加载。DEMO运行截图见附件一。
一、tree.jsp主要代码
1、首先在head中导入Dojo库(dojo.js)和TreeWidget
<script>"text/javascript" src="/UploadFiles/2021-04-02/dojo.js"><script>"text/javascript">
dojo.require("dojo.widget.Tree");
dojo.require("dojo.widget.TreeNode");
dojo.require("dojo.widget.TreeSelector");
dojo.require("dojo.widget.TreeRPCController");
dojo.require("dojo.widget.TreeLoadingController");
dojo.require("dojo.widget.TreeContextMenu");
</script>
2、在body中放置TreeWidget,TreeLoadingController中的RPCUrl="treeServlet"为从后台获取数据的servlet名称,TreeNode中的expandLevel表示树初始张开级别
<div dojoType="TreeLoadingController" RPCUrl="treeServlet" widgetId="treeController" DNDController="create"><!--</span-->div>
<div dojoType="TreeSelector" widgetId="treeSelector"><!--</span-->div>
<div dojoType="Tree" DNDMode="between" selector="treeSelector" widgetId="bandTree" controller="treeController">
<div dojoType="TreeNode" title="root" widgetId="root" objectId="root" isFolder="true" childIconSrc="images/comm.gif" expandLevel="1"/>
3、建立TreeSelector事件处理函数
function treeSelectFired() {
// get a reference to the treeSelector and get the selected node
var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
var treeNode = treeSelector.selectedNode;
// get a reference to the songDisplay div
var hostDiv = document.getElementById("songDisplay");
var isFolder = treeNode['isFolder'];
//alert(isFolder);
if ( !isFolder) {
var song = treeNode['title'];
var url = treeNode['url'];
link(url);
} else {
}
}
4、将select事件处理函数关联到treeSelector
function init() {
//get a reference to the treeSelector
var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
//connect the select event to the function treeSelectFired()
dojo.event.connect(treeSelector,'select','treeSelectFired');
}
dojo.addOnLoad(init);
二、主要java代码及数据结构
1、Gnmk.java中tree的属性
private String id;
private String gnmkdm; //功能模块代码
private String gnmksm; //功能模块说明
private String gnmktb; //功能模块图标
private String gnmklj; //功能模块路径
private String gnmkmc; //功能模块名称
private String gnmksj; //功能模块上级代码
private String gnmkbz; //功能模块标志(‘N'为叶节点)
2、HSQLDB内存数据库加载SQL(db.sql)
CREATE TABLE GNMK (ID VARCHAR, GNMKDM VARCHAR, GNMKMC VARCHAR, GNMKLJ VARCHAR, GNMKTB VARCHAR, GNMKBZ VARCHAR, GNMKSJ VARCHAR);
INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780001', '01', '一级目录1', null, 'system.gif', 'Y', '');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0101', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '01');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0102', '二级目录2', 'cxtjAction.do', 'system.gif', 'N', '01');
INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780002', '02', '一级目录2', null, 'system.gif', 'Y', '');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0201', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '02');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0202', '二级目录2', 'cxtjAction.do', 'system.gif', 'Y', '02');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020201', '三级目录1', 'cxtjAction.do', 'system.gif', 'N', '0202');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020202', '三级目录2', 'cxtjAction.do', 'system.gif', 'N', '0202');
3、TreeServlet .java主要代码,在getGnmkByParent(String gnmksj)方法中可以实现自己的业务,DEMO中使用GnmkDAO
public class TreeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
System.out.println("action b=>" + action);
System.out.println("action b=>" + action);
String data = request.getParameter("data");
if (action.equalsIgnoreCase("getChildren")) {
JSONTokener jsonTokener = new JSONTokener(data);
JSONObject jsonObject = (JSONObject) jsonTokener.nextValue();
JSONObject parentNodeObject = (JSONObject) jsonObject.get("node");
response.setContentType("text/json; charset=gb2312");
PrintWriter out = response.getWriter();
out.write(getChildren(parentNodeObject));
} else {
}
}
private String getChildren(JSONObject parentNodeObject) {
JSONArray result = new JSONArray();
String parentObjectId = parentNodeObject.getString("objectId");// id 唯一
// String parentWidgetId = parentNodeObject.getString("widgetId");// dm
parentObjectId = parentObjectId.equalsIgnoreCase("root") ? ""
: parentObjectId;
System.out.println("parentObjectId=>" + parentObjectId);
// 获取子功能模块
List listGnmk = this.getGnmkByParent(parentObjectId);
System.out.println("listGnmk=>" + listGnmk.size());
if (listGnmk != null) {
Iterator itGnmk = listGnmk.iterator();
while (itGnmk.hasNext()) {
Gnmk qxgnmk = (Gnmk) itGnmk.next();
try {
JSONObject jsonGnmkObject = new JSONObject();
String gnmkbz = qxgnmk.getGnmkbz();
boolean isFolder = gnmkbz.equalsIgnoreCase("Y") ? true
: false;
jsonGnmkObject.put("title", qxgnmk.getGnmkmc());
jsonGnmkObject.put("isFolder", isFolder);
jsonGnmkObject.put("widgetId", qxgnmk.getGnmkdm());
jsonGnmkObject.put("objectId", qxgnmk.getGnmkdm());
jsonGnmkObject.put("childIconSrc", "images/"
+ qxgnmk.getGnmktb());
jsonGnmkObject.put("url", qxgnmk.getGnmklj());
result.put(jsonGnmkObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return result.toString();
}
private List getGnmkByParent(String gnmksj) {
GnmkDAO gnmkDao = new GnmkDAO();
return gnmkDao.getGnmkByParent(gnmksj);
}
}
三、关于DEMO的其它配置说明
1、实现javax.servlet.ServletContextListener接口的contextInitialized方法来加载HSQLDB及其数据,ContextListener.java主要代码
public void contextInitialized(ServletContextEvent event) {
try {
// load the driver
Class.forName("org.hsqldb.jdbcDriver");
// create the table and add sample data
InputStreamReader in = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("db.sql"));
BufferedReader reader = new BufferedReader(in);
DBUtils.setupDatabase(reader);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
2、web.xml相关配置
<listener>
<listener-class>
dojo.sample.ContextListener
<!--<span class="tag"--><!--</span-->listener-class>
<!--</span--
下载
功能模块树是几乎在每个项目里都要用到的东西,利用Dojo的好处就是可以实现树的子节点的动态加载,这在树节点很多的情况下是很有用的。
下载附件二dojotree.rar,解压后将dist\dojotree.war部署到应用服务器即可浏览DEMO,DEMO中内置HSQLDB数据库,启动时自动加载。DEMO运行截图见附件一。
一、tree.jsp主要代码
1、首先在head中导入Dojo库(dojo.js)和TreeWidget
<script>"text/javascript" src="/UploadFiles/2021-04-02/dojo.js"><script>"text/javascript">
dojo.require("dojo.widget.Tree");
dojo.require("dojo.widget.TreeNode");
dojo.require("dojo.widget.TreeSelector");
dojo.require("dojo.widget.TreeRPCController");
dojo.require("dojo.widget.TreeLoadingController");
dojo.require("dojo.widget.TreeContextMenu");
</script>
2、在body中放置TreeWidget,TreeLoadingController中的RPCUrl="treeServlet"为从后台获取数据的servlet名称,TreeNode中的expandLevel表示树初始张开级别
<div dojoType="TreeLoadingController" RPCUrl="treeServlet" widgetId="treeController" DNDController="create"><!--</span-->div>
<div dojoType="TreeSelector" widgetId="treeSelector"><!--</span-->div>
<div dojoType="Tree" DNDMode="between" selector="treeSelector" widgetId="bandTree" controller="treeController">
<div dojoType="TreeNode" title="root" widgetId="root" objectId="root" isFolder="true" childIconSrc="images/comm.gif" expandLevel="1"/>
3、建立TreeSelector事件处理函数
function treeSelectFired() {
// get a reference to the treeSelector and get the selected node
var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
var treeNode = treeSelector.selectedNode;
// get a reference to the songDisplay div
var hostDiv = document.getElementById("songDisplay");
var isFolder = treeNode['isFolder'];
//alert(isFolder);
if ( !isFolder) {
var song = treeNode['title'];
var url = treeNode['url'];
link(url);
} else {
}
}
4、将select事件处理函数关联到treeSelector
function init() {
//get a reference to the treeSelector
var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
//connect the select event to the function treeSelectFired()
dojo.event.connect(treeSelector,'select','treeSelectFired');
}
dojo.addOnLoad(init);
二、主要java代码及数据结构
1、Gnmk.java中tree的属性
private String id;
private String gnmkdm; //功能模块代码
private String gnmksm; //功能模块说明
private String gnmktb; //功能模块图标
private String gnmklj; //功能模块路径
private String gnmkmc; //功能模块名称
private String gnmksj; //功能模块上级代码
private String gnmkbz; //功能模块标志(‘N'为叶节点)
2、HSQLDB内存数据库加载SQL(db.sql)
CREATE TABLE GNMK (ID VARCHAR, GNMKDM VARCHAR, GNMKMC VARCHAR, GNMKLJ VARCHAR, GNMKTB VARCHAR, GNMKBZ VARCHAR, GNMKSJ VARCHAR);
INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780001', '01', '一级目录1', null, 'system.gif', 'Y', '');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0101', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '01');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830001', '0102', '二级目录2', 'cxtjAction.do', 'system.gif', 'N', '01');
INSERT INTO GNMK VALUES ('d098a59f0b765c30010b765d6b780002', '02', '一级目录2', null, 'system.gif', 'Y', '');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0201', '二级目录1', 'cxtjAction.do', 'system.gif', 'N', '02');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '0202', '二级目录2', 'cxtjAction.do', 'system.gif', 'Y', '02');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020201', '三级目录1', 'cxtjAction.do', 'system.gif', 'N', '0202');
INSERT INTO GNMK VALUES ('d098a59f0b765e68010b765fda830002', '020202', '三级目录2', 'cxtjAction.do', 'system.gif', 'N', '0202');
3、TreeServlet .java主要代码,在getGnmkByParent(String gnmksj)方法中可以实现自己的业务,DEMO中使用GnmkDAO
public class TreeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
System.out.println("action b=>" + action);
System.out.println("action b=>" + action);
String data = request.getParameter("data");
if (action.equalsIgnoreCase("getChildren")) {
JSONTokener jsonTokener = new JSONTokener(data);
JSONObject jsonObject = (JSONObject) jsonTokener.nextValue();
JSONObject parentNodeObject = (JSONObject) jsonObject.get("node");
response.setContentType("text/json; charset=gb2312");
PrintWriter out = response.getWriter();
out.write(getChildren(parentNodeObject));
} else {
}
}
private String getChildren(JSONObject parentNodeObject) {
JSONArray result = new JSONArray();
String parentObjectId = parentNodeObject.getString("objectId");// id 唯一
// String parentWidgetId = parentNodeObject.getString("widgetId");// dm
parentObjectId = parentObjectId.equalsIgnoreCase("root") ? ""
: parentObjectId;
System.out.println("parentObjectId=>" + parentObjectId);
// 获取子功能模块
List listGnmk = this.getGnmkByParent(parentObjectId);
System.out.println("listGnmk=>" + listGnmk.size());
if (listGnmk != null) {
Iterator itGnmk = listGnmk.iterator();
while (itGnmk.hasNext()) {
Gnmk qxgnmk = (Gnmk) itGnmk.next();
try {
JSONObject jsonGnmkObject = new JSONObject();
String gnmkbz = qxgnmk.getGnmkbz();
boolean isFolder = gnmkbz.equalsIgnoreCase("Y") ? true
: false;
jsonGnmkObject.put("title", qxgnmk.getGnmkmc());
jsonGnmkObject.put("isFolder", isFolder);
jsonGnmkObject.put("widgetId", qxgnmk.getGnmkdm());
jsonGnmkObject.put("objectId", qxgnmk.getGnmkdm());
jsonGnmkObject.put("childIconSrc", "images/"
+ qxgnmk.getGnmktb());
jsonGnmkObject.put("url", qxgnmk.getGnmklj());
result.put(jsonGnmkObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return result.toString();
}
private List getGnmkByParent(String gnmksj) {
GnmkDAO gnmkDao = new GnmkDAO();
return gnmkDao.getGnmkByParent(gnmksj);
}
}
三、关于DEMO的其它配置说明
1、实现javax.servlet.ServletContextListener接口的contextInitialized方法来加载HSQLDB及其数据,ContextListener.java主要代码
public void contextInitialized(ServletContextEvent event) {
try {
// load the driver
Class.forName("org.hsqldb.jdbcDriver");
// create the table and add sample data
InputStreamReader in = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("db.sql"));
BufferedReader reader = new BufferedReader(in);
DBUtils.setupDatabase(reader);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
2、web.xml相关配置
<listener>
<listener-class>
dojo.sample.ContextListener
<!--<span class="tag"--><!--</span-->listener-class>
<!--</span--
下载
无为清净楼资源网 Design By www.qnjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
无为清净楼资源网 Design By www.qnjia.com
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2024年11月19日
2024年11月19日
- 车载音乐最强享受《车载极致女声精选CD》[WAV分轨][1G]
- 童宇.2024-爱情万年历【TOUCH音乐】【FLAC分轨】
- 黄晓君.2010-丽风金典系列VOL.1.2CD【丽风】【WAV+CUE】
- 黄晓君.2011-丽风金典系列VOL.2【丽风】【WAV+CUE】
- 群星1992《天碟国语金曲精选》香港首版[WAV+CUE][1G]
- 萧敬腾《王妃》台湾首版[WAV分轨][1G]
- 陈奕迅2023《CHIN UP》EAS MUSIC[WAV+CUE][1.2G]
- 黄心懋《曾经有个女孩》滚石首版[WAV+CUE]
- 群星《车宴(紫银合金AQCD)》[原抓WAV+CUE]
- 小骆驼《草原狼》[正版CD抓轨WAV+CUE]
- 群星.2011-剧集金曲精选2CD【永恒】【WAV+CUE】
- 林忆莲.1996-夜太黑【滚石】【WAV+CUE】
- 方皓玟.2009-UNLOCKME【东亚】【WAV+CUE】
- 群星《2024好听新歌22》十倍音质 U盘音乐[WAV分轨]
- 林宥嘉《神秘嘉宾》引进版[WAV分轨][1G]