我的栏目树的值是存放在数据库里的,所以首先应该有一个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> " + nodes[index][1] + "</span>";
}else{
label += "a target='main' href='" + nodes[index][3] + "'> " + 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
分享到:
相关推荐
本文将深入探讨“水平树 Treeview自定义高级控件 菜单分级树形”的概念,以及如何在C#环境中实现这一功能。 `TreeView`控件通常以垂直布局显示数据,每一级节点可以通过展开或折叠来展示其子节点。然而,“水平树”...
进化树treeview
在Qt5.5之前是没有树控件的,我们在使用时用的是ListView来构造出一个树,Qt5.5之后的QML开发阶段,有了树控件TreeView,本篇着重记录QML的TreeView的使用(包括增加树节点和删除节点)。
Bootstrap Treeview是一款基于jQuery和Bootstrap库的插件,它提供了美观且功能丰富的树形视图。这个特定的压缩包文件包含了一个实现可搜索下拉树形功能的示例,这在许多Web应用中非常有用,比如用于导航菜单、组织...
在VB(Visual Basic)编程中,树形控件(TreeView)是一种常见的用户界面元素,用于显示层次结构的数据。它以节点的形式展现数据,每个节点可以有子节点,形成树状结构,非常适合用来表示目录结构、文件系统或者组织...
### 使用TreeView实现树形菜单 在本篇内容中,我们将探讨如何使用ASP.NET中的`TreeView`控件来创建一个树形菜单系统。树形菜单在许多应用中都非常常见,尤其是在那些需要展示层级结构数据的应用中,例如网站导航、...
在IT界,尤其是在GUI(图形用户界面)设计中,`TreeView`控件是一个常见的元素,它用于展示数据的层次结构,通常以树形的方式呈现。这个控件允许用户通过节点的展开和折叠来查看和操作多级数据。下面将详细阐述`...
在Unity项目中,TreeView常用于创建可交互的树形菜单,用户可以通过展开和折叠节点来探索和操作数据。本教程将深入探讨Unity TreeView的实现、自定义和优化。 首先,我们要理解Unity TreeView的基本结构。一个...
在给定的“JQ TreeView树视图”主题中,我们将探讨如何使用jQuery来创建一个动态加载数据的TreeView组件。 首先,`TreeView`是一种将层次结构数据以树状结构展示的UI元素,它常用于网站和应用中以展示目录结构、...
《TreeView树控件全攻略》是一份面向广大编程爱好者,特别是VC、VB、VFP、SQL程序员的重要参考资料。它深入浅出地介绍了TreeView控件的各个方面,帮助开发者更好地理解和运用这个常用的图形用户界面元素。 首先,...
当我们需要管理远程FTP服务器上的文件和目录结构时,一种常见的方法是通过构建目录树视图,也就是将FTP服务器的目录结构映射到类似Windows资源管理器那样的树形控件中,例如TreeView。这个"获取Ftp目录树并绑定到...
本篇文章将深入探讨C# TreeView的常用操作,包括添加节点、查询节点、递归调用以及如何实现一个横向展示的树形结构。 1. **添加节点**:在C#中,我们可以通过`TreeNode`类来创建节点,并通过`TreeView`的`Nodes`...
VB6.0 自定义TreeView树形菜单(展开菜单),类似于实现多级菜单、展开菜单的功能,当然也可当作Tree树控菜单来使用。最终的功能预览图请参见测试截图所示。 Set a = TreeView1.Nodes.Add(, etvwFirst, 1, "第一个...
【纯HTML CSS JS目录树形框TreeView】是一种利用前端技术实现的交互式树状结构,主要用于展示层次化的数据。在不依赖任何外部JavaScript库的情况下,它仅通过HTML、CSS和JavaScript来创建。这样的设计使得代码更简洁...
4. 自制TreeView组件代码 虽然教程中没有提供完整的自定义TreeView组件代码,但根据上述操作,你可以创建一个自定义的TreeView组件,可能包含更复杂的逻辑,如事件处理、节点的动态加载等。自定义组件通常会扩展`...
TREEVIEW控件是Windows Forms和ASP.NET中的一个常用控件,用于显示树形结构的数据。下面将详细讲解如何使用TREEVIEW控件实现下拉菜单。 一、数据库设计 在实现TREEVIEW控件之前,我们需要设计一个数据库来存储树...
ASP.NET MVC中的树形结构(Tree)控件与ASP.NET中的TreeView控件相似,用于在Web应用程序中展示层级数据,例如目录结构、组织结构或分类系统。这些控件通过节点和子节点的关系来呈现数据,使得用户可以方便地浏览和...
标题中的"三状态树(Treeview)控件源代码"指的是一个C#编程项目,该项目创建了一个新的树形控件,它扩展了Windows Forms的`TreeView`控件,增加了第三个状态——部分选中。这个自定义控件允许用户选择单个节点,同时...
要实现递归树显示,我们需要定义一个自定义的树模型(`TreeModel`)来存储数据,并且在`TreeView`中使用`Repeater`来递归地展示每一层的节点。每个节点都是一个`Item`,并且包含一个可点击的箭头图标来控制子节点的...