`
davepkxxx
  • 浏览: 41008 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

自制栏目树 treeview

    博客分类:
  • Java
阅读更多
我的栏目树的值是存放在数据库里的,所以首先应该有一个JavaBean。

JavaBean:
package org.dave.tree.model;

import java.util.HashSet;
import java.util.Set;

/**
 * 栏目树节点
 * @author Dave
 */
public class Node {

	/**
	 * 唯一标示符
	 */
	private String nodeId;
	/**
	 * 节点名称
	 */
	private String nodeName;
	/**
	 * 节点类型,现在只有2个选择:1.folder/文件夹,2.link/链接
	 */
	private String nodeType;
	/**
	 * 链接
	 */
	private String uri;	
	
	/**
	 * 父节点
	 */
	private Node parentNode;
	/**
	 * 子结点
	 */
	private Set subNodes = new HashSet(0);

	public Node() {

	}

	public Node(String nodeId) {
		this.nodeId = nodeId;
	}

	public Node(String nodeId, String nodeName, String nodeType, String uri,
			Node parentNode, Set subNodes) {
		this.nodeId = nodeId;
		this.nodeName = nodeName;
		this.nodeType = nodeType;
		this.uri = uri;
		this.parentNode = parentNode;
		this.subNodes = subNodes;
	}

	public Node getParentNode() {
		return parentNode;
	}

	public void setParentNode(Node parentNode) {
		this.parentNode = parentNode;
	}

	public String getNodeId() {
		return nodeId;
	}

	public void setNodeId(String nodeId) {
		this.nodeId = nodeId;
	}

	public String getNodeName() {
		return nodeName;
	}

	public void setNodeName(String nodeName) {
		this.nodeName = nodeName;
	}

	public String getNodeType() {
		return nodeType;
	}

	public void setNodeType(String nodeType) {
		this.nodeType = nodeType;
	}

	public String getUri() {
		return uri;
	}

	public void setUri(String uri) {
		this.uri = uri;
	}

	public Set getSubNodes() {
		return subNodes;
	}

	public void setSubNodes(Set subNodes) {
		this.subNodes = subNodes;
	}

}


然后就是前台页面了:
<%@ page contentType="text/html; charset=utf-8"%>

<%@page import="java.util.Iterator"%>
<%@page import="java.util.List"%>
<%@page import="org.dave.tree.model.Node"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>栏目树</title>

		<script type="text/javascript">
			<!--
			
			/**
			 *初始化数据
			 */
			function loadData() {
				var nodes = new Array();
				var index = 0;
				
				<%
				for(Iterator iter = ((List)request.getAttribute("nodes")).iterator(); iter.hasNext();){
					Node node = (Node)iter.next();
				%>
				
				nodes[index++] = ["<%=node.getNodeId()%>", "<%=node.getNodeName()%>", "<%=node.getNodeType()%>", "<%=node.getUri()%>", "<%=node.getParentNode().getNodeId()%>"];
				
				<%
				}
				%>
				
				return nodes;
			}
			
			/**
			 *初始化栏目树
			 */
			function initTree(){
				var nodes = loadData();
				initNode(nodes, "", 0);
				reviseIcon();
				callbackNode();
			}
			
			/**
			 *初始化节点
			 *@param nodes 所有节点
			 *@param id 当前节点id
			 *@param num 位移量
			 */
			function initNode(nodes, id, num){
				var tree = document.getElementById("tree");
				
				for(var index = 0, count = 0; index < nodes.length; index++){
					if(nodes[index][4] == id){
						count++;
						var row = tree.insertRow(tree.rows.length);
						var cell = row.insertCell(0);
						cell.id = 0 + [index][0];
						
						if(subCount(id, nodes) == count){
							cell.innerHTML = initHtml(num, index, nodes, "L");
						}else{
							cell.innerHTML = initHtml(num, index, nodes, "T");
						}
						
						initNode(nodes, nodes[index][0], num + 1);
					}
				}
			}
			
			/**
			 *初始化节点内的html代码
			 *@param num 位移量
			 *@param index 本节点在所有节点里的序号
			 *@param nodes 所有节点
			 *@param shape 图标前缀,T or L,自己看看图标就知道有什么不同了。
			 */
			function initHtml(num, index, nodes, shape){
				var html = "";
				
				for(var count = 0; count < num; count++){
					html += "<img src='icon/tree/blank.png' align='absMiddle' />";
				}
				
				html += isEmpty(nodes[index][0], nodes, shape);
				html += "<img src='icon/tree/" + (nodes[index][2] == "folder" ? "open" : "link") + ".png' align='absmiddle' />";
				html += initLabel(index, nodes);
				
				return html;
			}
			
			/**
			 *初始化文字
			 *@param index 本节点在所有节点里的序号
			 *@param nodes 所有节点
			 */
			function initLabel(index, nodes){
				var label = "<"
				
				if(nodes[index][3] == ""){
					label += "span>&nbsp;" + nodes[index][1] + "</span>";
				}else{
					label += "a target='main' href='" + nodes[index][3] + "'>&nbsp;" + nodes[index][1] + "</a>";
				}
				
				return label;
			}
			
			/**
			 *判断本节点是否有子结点,并初始化展开图标
			 *@param id 当前节点id
			 *@param nodes 所有节点
			 *@param shape 图标前缀,T or L,自己看看图标就知道有什么不同了。
			 */
			function isEmpty(id, nodes, shape){
				var img = "<img src='icon/tree/";
				var icon = shape;
			
				for(var index = 0; index < nodes.length; index++){
					if(id == nodes[index][4]){
						icon += "minus";
						break;
					}
				}
				
				img += icon + ".png' align='absMiddle'";
				
				if(icon.indexOf("minus") > -1){
					img += " style='cursor: pointer;' onclick='changeStyle(this);'";
				}
				
				img += " />";
				
				return img;
			}
			
			/**
			 *计算有多少个子结点
			 *@param id 当前节点id
			 *@param nodes 所有节点
			 */
			function subCount(id, nodes){
				var count = 0;
			
				for(var index = 0; index < nodes.length; index++){
					if(nodes[index][4] == id){
						count++;
					}
				}
				
				return count;
			}
			
			/**
			 *修正节点前位移的图标
			 */
			function reviseIcon(){
				var rows = document.getElementById("tree").rows;
			
				for(var index = 1; index < rows.length; index++){
					var preChildNodes = rows[index - 1].cells[0].childNodes;
					var childNodes = rows[index].cells[0].childNodes;
					
					for(var count = 0; count < childNodes.length - 3; count++){
						var preImg = preChildNodes[count];
						var img = childNodes[count];
					
						if(preImg.src.indexOf("T") > -1 || preImg.src.indexOf("I") > -1){
							img.src = "icon/tree/I.png";
						}
					}
				}
			}
			
			/**
			 *点击展开图标时所触发的事件
			 *@param icon 当前图标
			 */
			function changeStyle(icon){
				changeIcon(icon);
				changeDisplay(icon.parentNode.parentNode.rowIndex);
			}
			
			/**
			 *改变文件夹图标
			 *@param icon 当前图标
			 */
			function changeIcon(icon){
				var folder = icon.parentNode.childNodes(icon.parentNode.childNodes.length - 2);
				
				if(folder.src.indexOf("folder") > -1){
					folder.src = "icon/tree/open.png";
				}else if(folder.src.indexOf("open") > -1){
					folder.src = "icon/tree/folder.png";
				}
				
				if(icon.src.indexOf("Tminus") > -1){
					icon.src = "icon/tree/Tplus.png";
				}else if(icon.src.indexOf("Tplus") > -1){
					icon.src = "icon/tree/Tminus.png";
				}else if(icon.src.indexOf("Lminus") > -1){
					icon.src = "icon/tree/Lplus.png";
				}else if(icon.src.indexOf("Lplus") > -1){
					icon.src = "icon/tree/Lminus.png";
				}
			}
			
			/**
			 *改变文件夹图标成指定图标
			 *@param icon 当前图标
			 *@param img 所要变成的图标
			 */
			function changeImg(icon, img){
				var folder = icon.parentNode.childNodes(icon.parentNode.childNodes.length - 2);
				
				if(folder.src.indexOf("link") < 0){
					if(img.indexOf("minus") > -1){
						folder.src = "icon/tree/open.png";
					}else if(img.indexOf("plus") > -1){
						folder.src = "icon/tree/folder.png";
					}
				}
				
				if(icon.src.indexOf("Tminus") > -1 || icon.src.indexOf("Tplus") > -1){
					icon.src = "icon/tree/T" + img + ".png";
				}else if(icon.src.indexOf("Lminus") > -1 || icon.src.indexOf("Lplus") > -1){
					icon.src = "icon/tree/L" + img + ".png";
				}
			}
			
			/**
			 *当前行在表格内的序号
			 *@param rowIndex 行号
			 */
			function changeDisplay(rowIndex){
				var tree = document.getElementById("tree");
				var baseCount = subStrNum(tree.rows[rowIndex].cells[0].innerHTML, "IMG");
			
				for(var index = rowIndex + 1; index < tree.rows.length;index++){
					var row = tree.rows[index];
					var count = subStrNum(row.cells[0].innerHTML, "IMG");
					
					if(count > baseCount){
						if(row.style.display == ""){
							row.style.display = "none";
							changeImg(row.cells[0].childNodes[row.cells[0].childNodes.length - 3], "minus");
						}else if(count == baseCount + 1){
							row.style.display = "";
							changeImg(row.cells[0].childNodes[row.cells[0].childNodes.length - 3], "plus");
						}
					}else{
						break;
					}
				}
			}
			
			/**
			 *计算一字符串在另一字符串内出现的次数
			 *@param arg 字符串
			 *@param subArg 另一字符串
			 */
			function subStrNum(arg, subArg){
				var count = 0
			
				for(; arg.indexOf(subArg) > -1; arg = arg.substr(arg.indexOf(subArg) + subArg.length)){
					count++;
				}
				
				return count;
			}
			
			/**
			 *当栏目树初始化完成时,收回所有展开的节点
			 */
			function callbackNode(){
				var rows = document.getElementById("tree").rows;
				
				for(var index = rows.length - 1; index >= 0; index--){
					rows[index].cells[0].childNodes[rows[index].cells[0].childNodes.length - 3].click();
				}
			}
			//-->
		</script>
	</head>

	<body onload="initTree();"
		style="width: 100%; height: 100%; float: left; border: 1px solid #99BEEF; background: #D2E4FC;">
		<table id="tree" cellpadding="0" cellspacing="0">
		</table>
	</body>
</html>


最后,就是几个图标了,我的图标放在webroot/icon/tree
  • 描述: 预览图
  • 大小: 15.7 KB
  • icon.rar (2.9 KB)
  • 描述: 所有图标的压缩包
  • 下载次数: 187
分享到:
评论
4 楼 david01205 2012-10-19  
不错,最近也在看栏目树,学习了。
3 楼 bobor_2008 2008-08-28  
mark
2 楼 guazi 2008-08-27  
isky 写道
不错   支持一下

不错,学习一下!
1 楼 isky 2008-08-27  
不错   支持一下

相关推荐

    水平树 Treeview自定义高级控件 菜单分级树形

    本文将深入探讨“水平树 Treeview自定义高级控件 菜单分级树形”的概念,以及如何在C#环境中实现这一功能。 `TreeView`控件通常以垂直布局显示数据,每一级节点可以通过展开或折叠来展示其子节点。然而,“水平树”...

    进化树treeview

    进化树treeview

    QML树控件TreeView的使用

    在Qt5.5之前是没有树控件的,我们在使用时用的是ListView来构造出一个树,Qt5.5之后的QML开发阶段,有了树控件TreeView,本篇着重记录QML的TreeView的使用(包括增加树节点和删除节点)。

    bootstrap treeview可搜索下拉树形

    Bootstrap Treeview是一款基于jQuery和Bootstrap库的插件,它提供了美观且功能丰富的树形视图。这个特定的压缩包文件包含了一个实现可搜索下拉树形功能的示例,这在许多Web应用中非常有用,比如用于导航菜单、组织...

    VB使用树形控件treeview

    在VB(Visual Basic)编程中,树形控件(TreeView)是一种常见的用户界面元素,用于显示层次结构的数据。它以节点的形式展现数据,每个节点可以有子节点,形成树状结构,非常适合用来表示目录结构、文件系统或者组织...

    用TreeView实现树菜单

    ### 使用TreeView实现树形菜单 在本篇内容中,我们将探讨如何使用ASP.NET中的`TreeView`控件来创建一个树形菜单系统。树形菜单在许多应用中都非常常见,尤其是在那些需要展示层级结构数据的应用中,例如网站导航、...

    treeview 树形列表

    在IT界,尤其是在GUI(图形用户界面)设计中,`TreeView`控件是一个常见的元素,它用于展示数据的层次结构,通常以树形的方式呈现。这个控件允许用户通过节点的展开和折叠来查看和操作多级数据。下面将详细阐述`...

    Unity TreeView树形菜单

    在Unity项目中,TreeView常用于创建可交互的树形菜单,用户可以通过展开和折叠节点来探索和操作数据。本教程将深入探讨Unity TreeView的实现、自定义和优化。 首先,我们要理解Unity TreeView的基本结构。一个...

    JQ TreeView树视图

    在给定的“JQ TreeView树视图”主题中,我们将探讨如何使用jQuery来创建一个动态加载数据的TreeView组件。 首先,`TreeView`是一种将层次结构数据以树状结构展示的UI元素,它常用于网站和应用中以展示目录结构、...

    TreeView树控件全攻略

    《TreeView树控件全攻略》是一份面向广大编程爱好者,特别是VC、VB、VFP、SQL程序员的重要参考资料。它深入浅出地介绍了TreeView控件的各个方面,帮助开发者更好地理解和运用这个常用的图形用户界面元素。 首先,...

    获取Ftp目录树并绑定到treeview

    当我们需要管理远程FTP服务器上的文件和目录结构时,一种常见的方法是通过构建目录树视图,也就是将FTP服务器的目录结构映射到类似Windows资源管理器那样的树形控件中,例如TreeView。这个"获取Ftp目录树并绑定到...

    C#treeview的常用操作和横向树

    本篇文章将深入探讨C# TreeView的常用操作,包括添加节点、查询节点、递归调用以及如何实现一个横向展示的树形结构。 1. **添加节点**:在C#中,我们可以通过`TreeNode`类来创建节点,并通过`TreeView`的`Nodes`...

    VB TreeView树形菜单(自定义展开菜单).rar

    VB6.0 自定义TreeView树形菜单(展开菜单),类似于实现多级菜单、展开菜单的功能,当然也可当作Tree树控菜单来使用。最终的功能预览图请参见测试截图所示。  Set a = TreeView1.Nodes.Add(, etvwFirst, 1, "第一个...

    纯HTML CSS JS目录树形框TreeView

    【纯HTML CSS JS目录树形框TreeView】是一种利用前端技术实现的交互式树状结构,主要用于展示层次化的数据。在不依赖任何外部JavaScript库的情况下,它仅通过HTML、CSS和JavaScript来创建。这样的设计使得代码更简洁...

    Treeview组件的使用方法.非常适合初学者.内附自制treeview组件代码

    4. 自制TreeView组件代码 虽然教程中没有提供完整的自定义TreeView组件代码,但根据上述操作,你可以创建一个自定义的TreeView组件,可能包含更复杂的逻辑,如事件处理、节点的动态加载等。自定义组件通常会扩展`...

    用TREEVIEW实现下拉菜单

    TREEVIEW控件是Windows Forms和ASP.NET中的一个常用控件,用于显示树形结构的数据。下面将详细讲解如何使用TREEVIEW控件实现下拉菜单。 一、数据库设计 在实现TREEVIEW控件之前,我们需要设计一个数据库来存储树...

    ASP.NET mvc tree 树 类似 TreeView 控件

    ASP.NET MVC中的树形结构(Tree)控件与ASP.NET中的TreeView控件相似,用于在Web应用程序中展示层级数据,例如目录结构、组织结构或分类系统。这些控件通过节点和子节点的关系来呈现数据,使得用户可以方便地浏览和...

    三状态树(Treeview)控件源代码

    标题中的"三状态树(Treeview)控件源代码"指的是一个C#编程项目,该项目创建了一个新的树形控件,它扩展了Windows Forms的`TreeView`控件,增加了第三个状态——部分选中。这个自定义控件允许用户选择单个节点,同时...

    qt qml treeview 树控件

    要实现递归树显示,我们需要定义一个自定义的树模型(`TreeModel`)来存储数据,并且在`TreeView`中使用`Repeater`来递归地展示每一层的节点。每个节点都是一个`Item`,并且包含一个可点击的箭头图标来控制子节点的...

Global site tag (gtag.js) - Google Analytics