朝花夕拾 之 Java+JavaScript构建自己的超级树

  但凡开发过web应用系统的人大概都有过类似的经历吧?构建一颗树(比如显示组织机构等),总之有上下级关系的数据用树形来显示效果应该都很不错的。 但是,很多情况下效果不太理想,比如级数(层熟)限制、比如显示效果、比如要给节点动态添加属性……
  在试过很多组件后我发现,其实借助jsp和javascript,自己也可以写出类似的东西啊,而且效果也可以很不错的,呵呵 : )


  首先,VO对象(Tree中的节点对象)

package com.javer.test.tree;

/**
* VO对象(Tree中的节点对象)
* <p>Title: TreeVO</p>
* @author javer QQ:84831612
*/
public class TreeVO
implements java.io.Serializable
{
/** 编码 */
private java.lang.String code;

/** 名称 */
private java.lang.String name;

/** 上级编码 */
private java.lang.String superiorcode;

/** 是否末级(1:是;0:不是;默认:1) */
private int islast = 1;
public String getCode()
{
return code;
}

public void setCode(String code)
{
this.code = code;
}

public int getIslast()
{
return islast;
}

public void setIslast(int islast)
{
this.islast = islast;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public String getSuperiorcode()
{
return superiorcode;
}

public void setSuperiorcode(String superiorcode)
{
this.superiorcode = superiorcode;
}
}

  第二,业务处理类

在实际应用中自己写
/********************************************************
*********************************************************
*********************************************************
*********************************************************
*********************************************************
*********************************************************
*********************************************************/

  第三,最重要的JSP页面

<%--
Description:Tree页面
Author:Javer QQ:84831612
Date:2004-08-05
--%>
<%--
Javer于2004-11-02修改如下问题:
1. 点击文件关闭父节点后,树节点的排列顺序不对
--%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="com.javer.test.tree.TreeVO" %>
<%@ page import="java.util.HashMap,java.util.Vector" %>

<%!
HashMap hp = null;
%>

<%
if(request.getAttribute("tree") != null)
hp = (HashMap) request.getAttribute("tree");
else //为了演示,在页面中增加Tree的内容,实际应用中应该把它放到后台去处理
{
/**
* 为了演示 指定固定的值
* 实际应用中应该来自数据库、配置文件……
* 而且应该在后台进行处理 request.setAttribute("tree",hp);
*/
hp = new java.util.HashMap();
java.util.Vector v = new java.util.Vector();
TreeVO vo1 = new TreeVO();
vo1.setCode("01");
vo1.setName("01的名称");
v.add(vo1);
TreeVO vo2 = new TreeVO();
vo2.setCode("02");
vo2.setName("02的名称");
vo2.setIslast(0);
v.add(vo2);
hp.put("TreeRoot",v);
v = new java.util.Vector();
TreeVO vo3 = new TreeVO();
vo3.setCode("0201");
vo3.setName("0201的名称");
vo3.setIslast(0);
vo3.setSuperiorcode("02");
v.add(vo3);
TreeVO vo4 = new TreeVO();
vo4.setCode("0202");
vo4.setName("0202的名称");
vo4.setSuperiorcode("02");
v.add(vo4);
hp.put("02",v);
v = new java.util.Vector();
TreeVO vo5 = new TreeVO();
vo5.setCode("020101");
vo5.setName("020101的名称");
vo5.setSuperiorcode("0201");
v.add(vo5);
hp.put("0201",v);

request.setAttribute("TreeName","Javer's Tree演示");
}
%>

<%!
private void showChild(javax.servlet.jsp.JspWriter out,int layerIndex,TreeVO vo)
throws java.io.IOException
{
if(hp.containsKey(vo.getCode()))
{
//有子节点
Vector v = (Vector) hp.get(vo.getCode());
if(v == null)
return;
TreeVO[] objs = (TreeVO[]) v.toArray(new TreeVO[0]);
boolean haveChild = false;
for(int i=0;i<objs.length;i++)
{
haveChild = objs[i].getIslast()==0 && hp.containsKey(objs[i].getCode());
for(int j=0;j<layerIndex;j++)
{
out.print("&nbsp;&nbsp;");
}
out.println(" <img name=/"img"+objs[i].getCode()+"/" src=/"/images/menu_folder_"+((haveChild)?"open1":"closed")+".gif/"");
if(haveChild)
{
out.print(" οnclick=/"turnit(this,'"+objs[i].getCode()+"')/" style=/"cursor:hand/"");
}
out.println("/>");
out.println(" <span name=/"selstr"+objs[i].getCode()+"/" id=/"selstr"+objs[i].getCode()+"/" align=/"left/" class=/"TreeStyle/">");
if(!haveChild)
{
out.println("<input type=/"radio/" value=/""+objs[i].getCode()+"#"+objs[i].getName()+"/" name=/"myRadio/" ondblClick=/"confirmSel();/">");
}
out.println(objs[i].getName());
out.println(" </span>");
out.println("<div id=/"div"+objs[i].getCode()+"/" name=/"div"+objs[i].getCode()+"/" style=/"'DISPLAY:'/" width=/"100%/" valign=/"top/">");
if(objs[i].getIslast() == 0)
{
showChild(out,layerIndex+2,objs[i]);
}
out.println("</div>");
}
}
}
%>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Javer's Tree演示页面</title>
<link href="/index.css" rel="stylesheet" type="text/css">
<style type="text/css">
.unitTreeStyle {
font-size: 12px;
color: #000000;
text-decoration: none;
cursor:hand
}
</style>
<script>
//确定选择
function confirmSel()
{
var selStr = getSel();
if(!selStr)
{
return false;
}
else
{
alert("选中的节点编码#名称=" + selStr);
}
}
function getSel()
{
var radioObj = document.thisform.myRadio;
if(!radioObj)
return false;
var returnValue;
if(radioObj.length)
{
for(var i=0;i<radioObj.length;i++)
{
if(radioObj[i].checked)
{
returnValue = radioObj[i].value;
}
}
}
else
{
if(radioObj.checked)
{
returnValue = radioObj.value;
}
}
if(!returnValue)
{
alert("请先选择一个节点!");
return false;
}

return returnValue;
}
//打开、关闭节点
function turnit(imgObj,divID)
{
var divObj = document.all["div"+divID];
if(!divObj && !imgObj)
{
return false;
}
else
{
if(divObj.style.display == "")
{
divObj.style.display = "none";
}
else
{
divObj.style.display = "";
}
if(imgObj.src.indexOf("closed1")!=-1)
imgObj.src="/images/menu_folder_open1.gif";
else if(imgObj.src.indexOf("open1")!=-1)
imgObj.src="/images/menu_folder_closed1.gif";
}
}
</script>
</head>

<body class="bYellow">

<form method="post" name="thisform">

<table width="90%" border="0" align="center">
<tr>
<td>
<%
if(hp != null)
{
%>
<img name="imgTreeRoot" src="/images/menu_folder_<%=hp.containsKey("TreeRoot")?"open1":"closed"%>.gif" οnclick="turnit(this,'TreeRoot')" style="cursor:hand"/>
<span name="selstrTreeRoot" id="selstrTreeRoot" align="left" class="TreeStyle">
<%= request.getAttribute("TreeName")==null?"树的名称":request.getAttribute("TreeName") %>
</span><br>
<div id="divTreeRoot" name="divTreeRoot" style="DISPLAY:" width="100%" valign="top">
<%
Vector v = (Vector) hp.get("TreeRoot");
if(v != null)
{
TreeVO[] objs = (TreeVO[]) v.toArray(new TreeVO[0]);
boolean haveChild = false;
for(int i=0;i<objs.length;i++)
{
haveChild = objs[i].getIslast()==0 && hp.containsKey(objs[i].getCode());
%>
&nbsp;&nbsp;<img name="img<%=objs[i].getCode()%>" src="/images/menu_folder_<%=(haveChild)?"open1":"closed"%>.gif" <% if(haveChild){out.print("οnclick=/"turnit(this,'"+objs[i].getCode()+"')/" style=/"cursor:hand/"");}%>/>
<span name="selstr<%=objs[i].getCode()%>" id="selstr<%=objs[i].getCode()%>" align="left" class="TreeStyle">
<%
if(!haveChild)
{
%>
<input type="radio" value="<%=objs[i].getCode()%>#<%=objs[i].getName()%>" name="myRadio" οndblclick="confirmSel();">
<%
}
%>
<%= objs[i].getName() %>
</span><br>
<div id="div<%=objs[i].getCode()%>" name="div<%=objs[i].getCode()%>" style="DISPLAY:" width="100%" valign="top">
<%
if(haveChild)
{
//不是末级,显示子节点
showChild(out,2,objs[i]);
}
%>
</div>
<%
}
}
else
{
out.println("没有查询到任何记录,请重新查询!");
}
%>
<%
}
else
{
out.println("没有查询到任何记录,请重新查询!");
}
%>
</div>
</td>
</tr>
<tr>
<td class="fContent" align="right">
<input name="Button1" type="button" class="iButton" value="确 定-O" onClick="confirmSel();" accesskey="O">
<input name="Button3" type="button" class="iButton" value="取 消-C" onClick="window.close();" accesskey="C">
</td>
</tr>
</table>

</form>

</body>

</html>

  显示效果图(怎么样,是不是挺不错的?)

  当然,也可以把单选换成复选框;节点的图片也可以自己更换;总之,一切都可以自己定制,就算你想给节点加个右键菜单都没有问题,不信可以试试哦
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值