转载请标明出处:https://blog.csdn.net/men_ma/article/details/106847165.
本文出自 不怕报错 就怕不报错的小猿猿 的博客
easyUI前端框架tree(树)后台实现(树形菜单一)——java
利用tree需要实现的效果图
工具
eclipse/MySQL数据库
用法
树(tree)定义在 ul 元素中。该标记可定义叶节点和子节点。节点将是 ul 列表内的 li元素。
需要用到的jar包
静态方法生成树
案例效果:
代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录后的主界面</title>
<!--导入css -->
<!--全局样式 -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/js/jquery-easyui-1.5.1/themes/default/easyui.css">
<!--定义图标 -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/js/jquery-easyui-1.5.1/themes/icon.css">
<!--导入js -->
<script type="text/javascript" src="${pageContext.request.contextPath }/static/js/jquery-easyui-1.5.1/jquery.min.js"></script>
<!--组件库源码的js文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath }/static/js/jquery-easyui-1.5.1/jquery.easyui.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/static/js/index1.js"></script>
</head>
<body class="easyui-layout">
<div data-options="region:'north',border:false" style="height:60px;background:#B3DFDA;padding:10px">美食网站管理系统</div>
<div data-options="region:'west',split:true,title:'West'" style="width:150px;padding:10px;">
<div class="easyui-panel" style="padding:5px">
<ul class="easyui-tree">
<li>
<span>My Documents</span>
<ul>
<li data-options="state:'closed'">
<span>Photos</span>
<ul>
<li>
<span>Friend</span>
</li>
<li>
<span>Wife</span>
</li>
<li>
<span>Company</span>
</li>
</ul>
</li>
<li>
<span>Program Files</span>
<ul>
<li>Intel</li>
<li>Java</li>
<li>Microsoft Office</li>
<li>Games</li>
</ul>
</li>
<li>index.html</li>
<li>about.html</li>
<li>welcome.html</li>
</ul>
</li>
</ul>
</div>
</div>
<div data-options="region:'east',split:true,collapsed:true,title:'East'" style="width:100px;padding:10px;">east region</div>
<div data-options="region:'south',border:false" style="height:50px;background:#A9FACD;padding:10px;">south region</div>
<div data-options="region:'center',title:'Center'"></div>
</body>
</html>
缺点: 如果树形结构复杂,层级较多,那么c:foreach以及c:if嵌套就会比较多,不方便编码
动态生成树(提供json数据格式来渲染出树)
方法:通过java代码以及Jackson的jar包来生产对应格式的数据
先写一个js文件(index.js):
index.js记得放在js文件夹下:
index.js源码:
$(function() {
$('#tt').tree({
url:'tree_data1.json'
});
})
案例及代码实现
根据easyUI的官方文档对应的结构节点建立的实体类(TreeVo.java)
每个节点都具备以下属性:
id:节点ID,对加载远程数据很重要。
text:显示节点文本。
state:节点状态,‘open’ 或 ‘closed’,默认:‘open’。如果为’closed’的时候,将不自动展开该节点。
checked:表示该节点是否被选中。
attributes: 被添加到节点的自定义属性。
children: 一个节点数组声明了若干节点。
package com.xiaoqing.vo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*
* @author 晴sister
*
* https://i.csdn.net/#/uc/profile
*/
public class TreeVo<T> {
/**
* 节点ID
*/
private String id;
/**
* 显示节点文本
*/
private String text;
/**
* 节点状态,open closed
*/
private Map<String, Object> state;
/**
* 节点是否被选中 true false
*/
private boolean checked = false;
/**
* 节点属性
*/
private Map<String, Object> attributes;
/**
* 节点的子节点
*/
private List<TreeVo<T>> children = new ArrayList<TreeVo<T>>();
/**
* 父ID
*/
private String parentId;
/**
* 是否有父节点
*/
private boolean hasParent = false;
/**
* 是否有子节点
*/
private boolean hasChildren = false;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Map<String, Object> getState() {
return state;
}
public void setState(Map<String, Object> state) {
this.state = state;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public Map<String, Object> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
}
public List<TreeVo<T>> getChildren() {
return children;
}
public void setChildren(List<TreeVo<T>> children) {
this.children = children;
}
public boolean isHasParent() {
return hasParent;
}
public void setHasParent(boolean isParent) {
this.hasParent = isParent;
}
public boolean isHasChildren() {
return hasChildren;
}
public void setChildren(boolean isChildren) {
this.hasChildren = isChildren;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public TreeVo(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
List<TreeVo<T>> children, boolean isParent, boolean isChildren, String parentID) {
super();
this.id = id;
this.text = text;
this.state = state;
this.checked = checked;
this.attributes = attributes;
this.children = children;
this.hasParent = isParent;
this.hasChildren = isChildren;
this.parentId = parentID;
}
public TreeVo() {
super();
}
}
存储节点及生产节点(BuildTree.java)
BuildTree的核心思想:两个循环
1.外层循环默认遍历的就是父节点
2.内层循环默认遍历的就是子节点
核心点:只要父节点的Id=子节点的父Id,那么就是父子关系,子节点的父Id,那么子节点就应该添加到父节点的children中
package com.xiaoqing.util;
import com.xiaoqing.vo.TreeVo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BuildTree {
/**
* 默认-1为顶级节点
* @param nodes
* @param <T>
* @return
*/
public static <T> TreeVo<T> build(List<TreeVo<T>> nodes) {
if (nodes == null) {
return null;
}
List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();
for (TreeVo<T> children : nodes) {
String pid = children.getParentId();
if (pid == null || "-1".equals(pid)) {
topNodes.add(children);
continue;
}
for (TreeVo<T> parent : nodes) {
String id = parent.getId();
if (id != null && id.equals(pid)) {
parent.getChildren().add(children);
children.setHasParent(true);
parent.setChildren(true);
continue;
}
}
}
TreeVo<T> root = new TreeVo<T>();
if (topNodes.size() == 1) {
root = topNodes.get(0);
} else {
root.setId("000");
root.setParentId("-1");
root.setHasParent(false);
root.setChildren(true);
root.setChecked(true);
root.setChildren(topNodes);
root.setText("顶级节点");
Map<String, Object> state = new HashMap<>(16);
state.put("opened", true);
root.setState(state);
}
return root;
}
/**
* 指定idparam为顶级节点
* @param nodes
* @param idParam
* @param <T>
* @return
*/
public static <T> List<TreeVo<T>> buildList(List<TreeVo<T>> nodes, String idParam) {
if (nodes == null) {
return null;
}
List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();
for (TreeVo<T> children : nodes) {
String pid = children.getParentId();
if (pid == null || idParam.equals(pid)) {
topNodes.add(children);
continue;
}
for (TreeVo<T> parent : nodes) {
String id = parent.getId();
if (id != null && id.equals(pid)) {
parent.getChildren().add(children);
children.setHasParent(true);
parent.setChildren(true);
continue;
}
}
}
return topNodes;
}
}
数据库表的数据
最高级别的父节点为**-1**
将从数据库中查询到的结果集转换为json格式
在进行数据查询时,我们需要用到一些工具类
public List<Menu> list(Permission permission,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException{
String sql="select * from t_easyui_menu";
return super.executeQuery(sql, Menu.class, pageBean);
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, SQLException, JsonProcessingException {
MenuDao md=new MenuDao();
List<Menu> list = md.list(null, null);
// Menu的格式是不满足
List<TreeVo<Menu>> nodes=new ArrayList<TreeVo<Menu>>();
// //Menu的格式是不满足easyui的tree组件的展现的数据格式的
// 目的:将List<Menu>转换成List<TreeVo<T>>
// 实现:将List<Menu>得到的单个Menu转换成TreeVo,将TreeVo加入到nodes
TreeVo treeVo=null;
for (Menu p : list) {
System.out.println(p);
treeVo=new TreeVo<>();
treeVo.setId(p.getMenuid());
treeVo.setText(p.getMenuname());
treeVo.setParentId(p.getParentid());
// Map<String, Object> attributes=new HashMap<String, Object>();
// attributes.put("self", p);
// treeVo.setAttributes(attributes);
nodes.add(treeVo);
}
TreeVo<Menu> parent = BuildTree.build(nodes);
ObjectMapper om=new ObjectMapper();
String jsonStr = om.writeValueAsString(parent);
System.out.println(jsonStr);
}
把字符串转换成json格式时,这么一大串,不好看,我们利用json在线工具转换一下
链接: json在线工具.
**转换结果:把转换成功的json格式的结果放入tree_data1.json中
**
效果就出来了
希望有大佬指点迷津!!