xtree使用感受
xtree很方便,静态树,如果项目的树状结构是固定的,那么用xtree就可以满足,当然也可以选择dtree,这也是一个不错的树实现 。看看api和例子,就能很好的写出这些树
xtree项目下面还有一个xloadtree,这个是动态树,也比较好用,是根据xml文件动态生成节点的。咱们主要说说这个xloadtree动态树
xloadtree是根据xml文件来生成的,xml可以是实体的文本也可以是IO流的形式,这点很重要,因为有的时候你不知道项目中需要生成哪些节点,或者根本不让你生成xml文件,这个时候就需要用IO流的方式来解决
1.载入xloadtree的JS脚本和CSS脚本:
<script language="javascript" src="js/xtree.js" charset="UTF-8"></script>
<script language="JavaScript" src="js/xmlextras.js" charset="UTF-8"></script>
<script language="javascript" src="js/xloadtree.js" charset="UTF-8"></script>
<link rel="stylesheet" type="text/css" href="css/xtree.css">
路径都有写对了,配对自己项目的路径。
------
还有需要用到jstl的core,也就是c:标记,所以还要导入c标记
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
------
2. 在需要显示树的地方写上如下代码:
<script type="text/javascript">
webFXTreeConfig.rootIcon = "parametersearch/images/xp/folder.png";
webFXTreeConfig.openRootIcon = "parametersearch/images/xp/openfolder.png";
webFXTreeConfig.folderIcon = "parametersearch/images/xp/folder.png";
webFXTreeConfig.openFolderIcon = "parametersearch/images/xp/openfolder.png";
webFXTreeConfig.fileIcon = "parametersearch/images/xp/file.png";
webFXTreeConfig.lMinusIcon = "parametersearch/images/xp/Lminus.png";
webFXTreeConfig.lPlusIcon = "parametersearch/images/xp/Lplus.png";
webFXTreeConfig.tMinusIcon = "parametersearch/images/xp/Tminus.png";
webFXTreeConfig.tPlusIcon = "parametersearch/images/xp/Tplus.png";
webFXTreeConfig.iIcon = "parametersearch/images/xp/I.png";
webFXTreeConfig.lIcon = "parametersearch/images/xp/L.png";
webFXTreeConfig.tIcon = "parametersearch/images/xp/T.png";
webFXTreeConfig.blankIcon = "parametersearch/images/xp/blank.png"
<c:import url="tree.do?method=tree"></c:import>
</script>
这段代码,大部分是为xp系统显示的树状的图标而设计的。最后的一行代码,是为了发送一个请求,我现在只知道用<c:import>标签(别忘了页面开头要加上标签的引用),注意在这标签里面是没办法用变量的形式的(谁有解决的办法可以拿出来,大家分享一下),url参数请求了一个action
这个action产生了一段JS代码,主要和这段JS连接起来,组成一个新的JS代码,这样就可以完成树的结构
3.那么现在就建立接受请求的action类,这里用的一个DispatchAction类,比较方便。
public ActionForward tree(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setContentType("text/xml;charset=UTF-8");
Format format = Format.getCompactFormat();
format.setEncoding("UTF-8");
format.setIndent("/t");
//获得所有厂商节点
List<ParameterDirectory> list = pds.searchFullType();
StringBuffer sb = new StringBuffer();
sb.append("var tree = new WebFXTree('厂商');");
sb.append("tree.setBehavior('classic');");
for(ParameterDirectory pd : list){
sb.append("var tree_"+pd.getFc_id()+" = new WebFXLoadTree('"+pd.getFc_name()+"','parametersearch/tree.do?method=searchParameter_subTree&upid="+pd.getFc_id()+"');");
sb.append("tree.add(tree_"+pd.getFc_id()+");");
}
sb.append("document.write(tree);");
PrintWriter pout = response.getWriter();
String treeStr = sb.toString();
pout.println(sb.toString());
pout.flush();
pout.close();
return null;
}
解释一下:开头是方法名,通过不同的参数调用不同的action。
内部:a:前4行是定义返回请求的类型,并定义一个格式(可能还有其他代码,这里不说,从网上找找,拼凑一下)
b:接下来就是通过service的方法获得一个List集合,这个集合就是根下的第一层节点,
c:建立一个StringBuffer类,准备用来拼接字符串,生成JSP页面中想要的JS代码。
d:先new一个根。一般命名为tree,其他名字也可以,后面的参数是要显示在页面的名字。这个是根。选择一个经典的浏览模式这是为了显示好看
e:开始循环这个List,把需要显示的属性提出来。写在StringBuffer对象中。定义格式可以参考上面代码或看看API,实例中,new一个webFxLoadTree,变量名为了区分,使用了“tree_id号”的形式。参数1是名字,参数2是连接XML地址或产生的IO流
f:每一个tree_id对象,都要加入到这个根中(tree),即tree.add(tree_id);
g:最后写出这个树,doucument.write(tree);
h:通过response获得PrintWriter对象,向外部写。flush,关闭。
i:最后return一个空,为了避免报错,action方法都需要返回一个ActionForward对象。
4,最后说说XML的组成。API中已经说的很详细了。我说点别的,就是组成xml的流传给需要的节点。看实例,接上一段代码的。注意上一段代码的aciton请求,会来到这里,并携带了一个upid这个参数。
public ActionForward searchParameter_subTree(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setContentType("text/xml;charset=UTF-8");
Format format = Format.getCompactFormat();
format.setEncoding("UTF-8");
format.setIndent("/t");
Document doc = new Document(new Element("tree"));
String upid = request.getParameter("upid");
//获得该厂商下面所有参数设置(子节点)
List<ParameterDirectory> list = pds.findRoot_SubNode(upid);
PrintWriter pout = response.getWriter();
for(ParameterDirectory pd : list){
Element tree = doc.getRootElement();
Element inner = new Element("tree").setAttribute("text",pd.getFc_name());
inner.setAttribute("src","parametersearch/tree.do?method=searchParameterTree&itemid="+pd.getFc_id());
tree.addContent(inner);
}
XMLOutputter outp = new XMLOutputter(format);
outp.output(doc, pout);
pout.flush();
pout.close();
return null;
}
前几行一样。
根据DTD的格式组装xml,使用的JDOM的技术
a:new出Document对象,并定义根元素tree
b:使用Document对象获得根节点元素
c:new 出新的元素tree。并添加属性text,属性值为对象的名字
d:在为该元素添加属性src,属性值还是一个请求的地址,这个地址返回一个xml流,(还有一个属性是action,这个没写,这个属性的属性值是一个地址,或是js函数名)
e:找一个xml的输出流的类,把这个xml输出出去。
*********************************************************
几个郁闷点:
1.路径可能会出现偏差,因为页面上有两段代码。
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<base href="<%=basePath%>">
这两段代码为href赋予了默认的地址。应该是web应用的路径。但是这个有时候会和xtree的js,css,dwr的js的地址发生冲突,需要调试,或手写更改路径。
2.(已解决)树可以改成没有根节点的形式,如下代码:可以生成没有根节点的树,每个节点都是根节点,但是天生就是打开状态,不美观,不知道如何解决。
public ActionForward tree(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setContentType("text/xml;charset=UTF-8");
Format format = Format.getCompactFormat();
format.setEncoding("UTF-8");
format.setIndent("/t");
//获得所有厂商节点
List<ParameterDirectory> list = pds.searchFullType();
StringBuffer sb = new StringBuffer();
// sb.append("var tree = new WebFXTree('厂商');");
// sb.append("tree.setBehavior('classic');");
for(ParameterDirectory pd : list){
sb.append("var tree_"+pd.getFc_id()+" = new WebFXLoadTree('"+pd.getFc_name()+"','parametersearch/tree.do?method=searchParameter_subTree&upid="+pd.getFc_id()+"');");//如果使用树形结构节点样式的,就使用new WebFXLoadTreeItem(..)的声明方式
sb.append("tree_"+pd.getFc_id()+".open=false;");//加入这句话,展开状态为假,表示不展开
sb.append("document.write(tree_"+pd.getFc_id()+");");
// sb.append("tree.add(tree_"+pd.getFc_id()+");");
}
// sb.append("document.write(tree);");
PrintWriter pout = response.getWriter();
String treeStr = sb.toString();
pout.println(sb.toString());
pout.flush();
pout.close();
return null;
}
3.不知道如何创建出一个灵活的动态树,可以不用手动的控制节点还是叶子。
4.前台页面的<c:import>中没办法使用变量,如果哪位大侠知道,请告诉我一下。