:D 新学Ztree,由于网上没有现成的例子,走了很多弯路,最后在ZtreeAPI的指点下终于完成了Ztree简单功能的使用,鉴于网上没有完整或注释很少的例子,现在把我的代码分享下,这个例子用到mysql数据库和struts2框架还有谷歌的GSON,所以用的时候确认有没有少了mysql的驱动包和struts2,gson的架包,好了,下面是完整的代码。
首先,ztree对应的POJO:
接着基础DAO:
用户DAO:
读取配置文件的帮助类:
配置文件config.properties:
下面是STRUTS2配置文件:
接着ACTION:
WEB.XML:
最后JSP页面:
哦,对了还有测试数据库 :D :D
就这么多了,写的不好多见谅,其实看在线的ZTREE API挺好的,只是对于javascript不太好的同学可能会感到无从下手,所以给个小小的建议,把Ztree看成个java类,可以看到他有属性,有方法,这样好理解点!Ztree的功能蛮强大的,就是在异步交互提交动态参数这有点不方便。
首先,ztree对应的POJO:
/**
* 学习ztree,POJO
* @author Dream.YangLong
* Time:2012/12/23
*/
public class Ztree {
private String id;
private String pId;
private String name;
private String isParent;
private String file;
public Ztree() {
super();
this.isParent="false";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getpId() {
return pId;
}
public void setpId(String pId) {
this.pId = pId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIsParent() {
return isParent;
}
public void setIsParent(String isParent) {
this.isParent = isParent;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
}
接着基础DAO:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import dao.StringUtil;
public class DAO {
private String db_driver;
private String db_url;
private String db_user;
private String db_pass;
private Connection conn;
private PreparedStatement pst;
private ResultSet set;
public DAO() {
super();
db_driver = StringUtil.config("db_driver");
db_url =StringUtil.config("db_url");
db_user = StringUtil.config("db_user");
db_pass = StringUtil.config("db_pass");
try {
Class.forName(db_driver);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 建立连接
*/
public Connection getConnection(){
try {
conn = DriverManager.getConnection(db_url,db_user,db_pass );
}catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/*
* 执行DML操作
*/
public void executeDML(String sql,Object ...param) throws SQLException{
getConnection();
pst=conn.prepareStatement(sql);
if(param!=null){
for(int i=0;i<param.length;i++){
pst.setObject(i+1, param[i]);
}
}
pst.execute();
}
/*
* 执行SQL语句得到结果集合
*/
public ResultSet executeQuery(String sql,Object ...param){
getConnection();
try {
pst=conn.prepareStatement(sql);
if(param!=null){
for(int i=0;i<param.length;i++){
pst.setObject(i+1, param[i]);
}
}
set=pst.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return set;
}
/*
* 关闭通道
*/
public void closeAll(){
try {
if(set!=null){
set.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(pst!=null){
pst.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public PreparedStatement getPst() {
return pst;
}
public void setPst(PreparedStatement pst) {
this.pst = pst;
}
public ResultSet getSet() {
return set;
}
public void setSet(ResultSet set) {
this.set = set;
}
}
用户DAO:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import bean.Ztree;
/**
* 学习ztree,dao
* @author Dream.YangLong
* Time:2012/12/23
*/
public class UserDao extends DAO{
/*
* 注册新节点方法,Bean驱动
*/
public boolean addNode(Ztree zTree){
boolean flag=true;
String sql="insert into nodes(id,name,pid,isparent,url) " +
" values(?,?,?,?,?)";
try {
this.executeDML(sql, zTree.getId(),zTree.getName(),zTree.getpId(),
zTree.getIsParent(),zTree.getFile());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag=false;
}
return flag;
}
/*
* 查找节点方法,bean驱动
*/
public ArrayList<Ztree> getSubNodes(Ztree zTree){
ArrayList<Ztree> allNodes=new ArrayList<Ztree>();
String querySql="select * from " +
"nodes " +
"where pid=?";
try {
ResultSet nodeSet=this.executeQuery(querySql,zTree.getId());
while(nodeSet.next()){
Ztree zt=new Ztree();
zt.setId(nodeSet.getString("id"));
zt.setName(nodeSet.getString("name"));
zt.setpId(nodeSet.getString("pid"));
zt.setIsParent(nodeSet.getString("isparent"));
//为实现url的框架跳转,跳转target在页面用Onclick函数处理,ztree的url在POJO中为file
zt.setFile(nodeSet.getString("url"));
allNodes.add(zt);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
this.closeAll();
}
return allNodes;
}
}
读取配置文件的帮助类:
import java.util.ResourceBundle;
public class StringUtil {
static ResourceBundle rb=ResourceBundle.getBundle("config");//加载资源文件
/**
*
* @param key 指定配置文件内容常量名字
* @return 对应值
*/
public static String config(String key){
String result=null;
try {
result=rb.getString(key);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static int parseInt(String str){
int result=0;
try {
result=Integer.parseInt(str);
} catch (NumberFormatException e) {
e.printStackTrace();
System.out.println("格式化异常!");
}
return result;
}
}
配置文件config.properties:
db_driver=com.mysql.jdbc.Driver
db_url=jdbc\:mysql\:\//127.0.0.1\:3306\/ztree
db_user=root
db_pass=root
下面是STRUTS2配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.action.extension" value="action,do"></constant>
<package name="action" namespace="" extends="struts-default">
<action name="TestAction" class="action.TestAction">
<!-- 下面result为测试跳转使用,ztree并未使用 -->
<result name="testZTreePage">clickme.html</result>
</action>
</package>
</struts>
接着ACTION:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import bean.Ztree;
import com.google.gson.Gson;
import dao.UserDao;
/**
* 学习Ztree struts2,JDBC整合Action
* @author Dream.YangLong
* Time:2012/12/23
*/
public class TestAction {
private UserDao userdao=new UserDao();
public String getNodes(){
//获取request对象
HttpServletRequest request=ServletActionContext.getRequest();
//获取AJAX请求参数
String id=request.getParameter("id");
String pId=request.getParameter("pId");
//生成驱动Bean,为页面当前被点击节点,即将要获取节点的父节点
Ztree pZtree=new Ztree();
pZtree.setId(id);
pZtree.setpId(pId);
System.out.println("提交的参数:"+id+":"+pId);
//生成JSON转换辅助对象
Gson gson = new Gson();
//获取子节点
List<Ztree> nodes=userdao.getSubNodes(pZtree);
//转换为JSON数据格式
String subNodes=gson.toJson(nodes);
System.out.println("服务器端生成的JSON数据为:"+subNodes);
//获取response对象
HttpServletResponse response = ServletActionContext.getResponse();
//返回页面的信息为utf-8编码,不加这个提示信息就会变成乱码
response.setCharacterEncoding("utf-8");
//返回页面的信息为html/text格式,不加这个返回页面的信息就会是整个页面
response.setContentType("html/text");
//将信息通过ajax返回
PrintWriter out = null;
try {
out = response.getWriter();
out.print(subNodes);
out.flush();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
WEB.XML:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>ztree.jsp</welcome-file>
</welcome-file-list>
</web-app>
最后JSP页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<HTML>
<HEAD>
<TITLE> ZTREE DEMO </TITLE>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="css/zTreeStyle/zTreeStyle.css" type="text/css">
<style>
body {
background-color: white;
margin:0; padding:0;
text-align: center;
}
div, p, table, th, td {
list-style:none;
margin:0; padding:0;
color:#333; font-size:12px;
font-family:dotum, Verdana, Arial, Helvetica, AppleGothic, sans-serif;
}
#testIframe {margin-left: 10px;}
</style>
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="js/jquery.ztree.core-3.5.js"></script>
<SCRIPT type="text/javascript" >
<!--
//var ztreeObj;//树对象
//初始化目录节点,可进入页面由ACTION传值过来。静态的在用字符串作为id时,要用""或''包起来,否则不能识别
var zNodes =[
{id:1, pId:0, name:"渠道酬金管理目录",open:true},
{id:101, pId:1, name:"目录1", isParent:true, open:false},
{id:102, pId:1, name:"目录2", isParent:true, open:false},
{id:103, pId:1, name:"目录3", isParent:true, open:false}
];
var setting = {
view: {
dblClickExpand: false,//双击节点时,是否自动展开父节点的标识
showLine: true,//显示下划线
selectedMulti: false,//设置是否允许同时选中多个节点。
expandSpeed: 400//"slow"//节点展开速度
},
data: {
simpleData: {//是否为简单数据类型JSON
enable:true,
idKey: "id",//使用简单必须标明的的节点对应字段
pIdKey: "pId",//使用简单必须标明的的父节点对应字段
rootPId:null//根
}
},
async: {
enable: true,//异步加载
//请求地址,可用function动态获取
url:"TestAction!getNodes.action",
contentType:"application/x-www-form-urlencoded",//按照标准的 Form 格式提交参数
autoParam:["id", "pId"],//提交的节点参数,可用“id=xx”取请求提交时的别名
//otherParam:{"otherParam":"zTreeAsyncTest"},//提交的其他参数,json的形式
dataType:"json",//返回数据类型
type:"post",//请求方式
dataFilter: null//数据过滤
},
callback: {
onClick:reLoadOpenURL,//节点被点击时调用的函数
onAsyncError: onAsyncError,//异步加载失败调用的函数
//onExpand: zTreeOnExpand,//用于捕获节点被展开的事件回调函数
beforeExpand: zTreeBeforeExpand,//用于捕获父节点展开之前的事件回调函数,并且根据返回值确定是否允许展开操作
}
};
//如果是父节点不处理,如果是子节点,打开对应的连接
function reLoadOpenURL(event, treeId, treeNode){
//alert(treeNode.tId + ", " + treeNode.name+","+treeNode.id);
var zTree = $.fn.zTree.getZTreeObj(treeId);
if (treeNode.isParent) {//如果是父节点
//zTree.reAsyncChildNodes(treeNode, "refresh",false);//异步刷新,清空后加载,加载后打开
if(treeNode.open){//父节点为展开状态,折叠父节点
//alert(treeNode.open);
zTree.expandNode(treeNode,false,true,true,false);
//expandNode参数说明:节点,展开(true)/折叠(false),是否影响子孙节点,是否设置焦点,是否触发beforeExpand/onExpand或beforeCollapse/onCollapse事件回调函数
}
else{//父节点是折叠的
if(treeNode.id!=1)zTreeBeforeExpand(treeId, treeNode);//如果不是根节点(本例根节点为1),则强制异步刷新子节点数据
else
zTree.expandNode(treeNode,true,false,true,false);//如果是根节点则展开
}
return false;
} else {//不是父节点,打开对应链接
$("#testIframe").attr("src",treeNode.file + ".html");
return true;
}
}
//用于捕获父节点展开之前的事件回调函数,并且根据返回值确定是否允许展开操作 ,false不代开
function zTreeBeforeExpand(treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj(treeId);
if (treeNode.isParent&&treeNode.id!="1") {
zTree.reAsyncChildNodes(treeNode, "refresh");//异步刷新,清空后加载,加载后打开,需要不打开加参数true
return false;//使用了异步强行加载,如果用true,节点展开将不会按照expandSpeed属性展开,false将按照设定速度展开
}
else {
return true;
}
};
//用于捕获节点被展开后的事件回调函数
function zTreeOnExpand(event, treeId, treeNode) {
alert(treeNode.tId + ", " + treeNode.name);
};
//数据过滤方法,如后台数据已确认无误可直接返回数据,不需注册此回调函数
function filter(treeId, parentNode, childNodes) {
if (!childNodes) return null;
return childNodes;
}
//异步加载失败时调用的方法
function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
alert("加载失败!");
}
//初始化树
$(document).ready(function(){
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
});
/**
function callOnClick(event,treeId, treeNode) {
var zTree = $.fn.zTree.getZTreeObj(treeId);
if (treeNode.isParent) {//如果是父节点
//zTree.reAsyncChildNodes(treeNode, "refresh",false);//异步刷新,清空后加载,加载后打开
if(treeNode.open){//父节点为展开状态,折叠父节点
//alert(treeNode.open);
zTree.expandNode(treeNode,false,true,true,false);
//expandNode参数说明:节点,展开(true)/折叠(false),是否影响子孙节点,是否设置焦点,是否触发beforeExpand/onExpand或beforeCollapse/onCollapse事件回调函数
}
else{//父节点是折叠的
if(treeNode.id!=1)zTreeBeforeExpand(treeId, treeNode);//如果不是根节点(本例根节点为1),则强制异步刷新子节点数据
else
zTree.expandNode(treeNode,true,false,true,false);//如果是根节点则展开
}
return false;
} else {//不是父节点,打开对应链接
$(parent.document).find('#testFrame').attr('src', treeNode.file + ".html");
return true;
}
}
*/
//-->
</SCRIPT>
</HEAD>
<BODY>
<TABLE border=0 height=600px align=left width="100%">
<TR>
<TD colspan="2" STYLE="WIDTH: 100%;HEIGHT: 100PX;"><input type="hidden" name="author" value="BeiFangUniversity.09Software.YangLong"></TD>
</TR>
<TR>
<TD width=160px align=left valign=top style="BORDER-RIGHT: #999999 1px dashed">
<ul id="treeDemo" class="ztree" style="width:225px; overflow:auto;"></ul>
</TD>
<TD width=770px align=left valign=top>
<IFRAME ID="testIframe" Name="testIframe" FRAMEBORDER=0 SCROLLING=AUTO width=100% height=600px SRC=""></IFRAME>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
哦,对了还有测试数据库 :D :D
CREATE DATABASE `ztree` /*!40100 DEFAULT CHARACTER SET utf8 */;
DROP TABLE IF EXISTS `nodes`;
CREATE TABLE `nodes` (
`id` varchar(30) NOT NULL,
`pid` varchar(30) default '0',
`name` varchar(50) default NULL,
`isparent` varchar(50) default NULL,
`url` varchar(100) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `nodes` (`id`,`pid`,`name`,`isparent`,`url`) VALUES ('1011a','101','目录1.1','false','clickme');
INSERT INTO `nodes` (`id`,`pid`,`name`,`isparent`,`url`) VALUES ('1012a','101','目录1.2','false','clickme');
INSERT INTO `nodes` (`id`,`pid`,`name`,`isparent`,`url`) VALUES ('1021a','102','目录2.1','false','clickme');
INSERT INTO `nodes` (`id`,`pid`,`name`,`isparent`,`url`) VALUES ('1022a','102','目录2.2','false','clickme');
就这么多了,写的不好多见谅,其实看在线的ZTREE API挺好的,只是对于javascript不太好的同学可能会感到无从下手,所以给个小小的建议,把Ztree看成个java类,可以看到他有属性,有方法,这样好理解点!Ztree的功能蛮强大的,就是在异步交互提交动态参数这有点不方便。