用java 生成一个树形菜单
- 格式:docx
- 大小:37.06 KB
- 文档页数:7
一种web树组件生成方法Web树组件的生成方法可以通过使用HTML、CSS和JavaScript来实现。
下面是一个简单的Web树组件生成方法的步骤:步骤1:HTML结构首先,在HTML中创建一个具有适当的class或id的根元素。
例如,可以使用'id="tree"'来标识树的根元素。
步骤2:CSS样式然后,使用CSS来为树组件定义样式。
可以为树的节点、连接线、折叠图标等定义样式。
样式可以根据个人喜好或项目需求进行定制。
步骤3:JavaScript逻辑接下来,使用JavaScript来实现树组件的逻辑部分。
可以使用原生JavaScript或者流行的JavaScript库,如jQuery或React等来简化开发过程。
在JavaScript代码中,首先获取根元素并为其添加事件监听器。
例如,可以使用document.getElementById('tree')来获取根元素并为其添加一个点击事件监听器。
在事件处理程序中,可以根据点击的节点展开或折叠子节点。
根据具体需求,可以通过添加或删除CSS类来控制节点的展开或折叠状态。
此外,还可以通过JavaScript动态生成节点和连接线,并将它们插入到树组件中。
步骤4:数据绑定树组件通常需要与后端数据进行绑定,以便动态生成节点。
为了实现数据绑定,可以发送异步请求获取树组件的数据。
然后,根据返回的数据动态生成节点。
对于大型树组件,可以使用分页或延迟加载等策略来提高性能。
例如,可以只加载可见的节点,而不是一次性加载整个树。
步骤5:增加交互功能树组件通常需要提供一些交互功能,如节点的展开/折叠、节点的选中等。
为了实现这些功能,可以为节点添加事件监听器,如点击事件、双击事件等。
在事件处理程序中,可以根据需要实现所需的交互功能。
例如,可以通过添加或删除CSS类来实现节点的展开/折叠功能,并在选中节点时使用CSS样式来突出显示选中状态。
java组织树递归详解全文共四篇示例,供读者参考第一篇示例:Java组织树的递归是一种常见且重要的数据结构操作方法,通过递归算法可以方便地遍历和操作组织结构树。
在实际的项目开发中,经常会遇到需要处理组织结构树的情况,比如公司部门架构、树状菜单等。
本文将详细介绍Java组织树递归的原理、实现方式和应用场景。
一、理解组织树在开始讲述组织树的递归之前,首先需要理解什么是组织树。
组织树是一种树形结构,通常用来表示具有层级关系的数据。
比如一个公司的部门架构,可以用一个树形结构来表示,公司为根节点,各个部门为子节点,部门下还可能有子部门或者员工。
树形结构的特点是每个节点都可以有多个子节点,但只有一个父节点,形成了一种层级结构。
二、递归原理递归是一种编程技术,常用于解决问题时,将问题分解成相同类型的子问题,并对子问题进行求解,最终汇总结果。
在处理组织树时,递归的主要原理是通过递归方法,一层一层地对树的每个节点进行遍历,直到叶子节点为止。
递归方法通常需要递归调用自身,以实现对整个树形结构的遍历和操作。
三、组织树递归实现方式在Java中,可以通过递归方法来实现对组织树的遍历和操作。
下面我们以一个简单的示例来说明如何实现组织树的递归:假设有一个部门实体类Department,包含部门ID、部门名称、父部门ID等属性;```javapublic class Department {private Long id;private String name;private Long parentId;// 省略getter和setter方法}```接下来我们定义一个方法,通过递归方式遍历组织树:```javapublic void traverseDepartmentTree(Department department, List<Department> departmentList) {System.out.println(department.getName());List<Department> children = getChildren(department, departmentList);if(children != null && !children.isEmpty()) {for(Department child : children) {traverseDepartmentTree(child, departmentList);}}}private List<Department> getChildren(Department parent, List<Department> departmentList) {List<Department> children = new ArrayList<>();for(Department department : departmentList) {if(parent.getId().equals(department.getParentId())) {children.add(department);}}return children;}```在上面的示例中,traverseDepartmentTree方法接收一个部门对象和部门列表,首先输出当前部门的名称,然后调用getChildren方法获取当前部门的子部门列表,递归遍历子部门,直到叶子节点。
C#→⽤TreeView实现树菜单具体⽅法是:创建⼀个数据库,设计树图信息表S_Menu,包含NodeId、ParentId、NodeName、Address、Icon字段,其它字段根据实际业务⽽定,节点名称NodeName将在树型控件的节点上显⽰,NodeId字段保存节点的唯⼀标识号,ParentId表⽰当前节点的⽗节点号,标识号组成了⼀个“链表”,记录了树上节点的结构。
设计⼀个Web窗体其上放置TreeView控件,修改其属性Id为tvMenu。
数据结构如下:CREATE TABLE [dbo].[S_Menu] ([NodeId] [char] (6) COLLATE Chinese_PRC_CI_AS NULL ,[ParentId] [char] (6) COLLATE Chinese_PRC_CI_AS NULL ,[NodeName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,[Address] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,[Icon] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL) ON [PRIMARY]GO数据库如下:NodeId ParentId NodeName Address Icon100000 0 公共查询部 icon_document.gif100001 100000 ⼈民币⽇报查询 public/a1.aspx icon_settings.gif100002 100000 外币⽇报查询 public/a2.aspx icon_settings.gif100003 0 分⾏科技部 icon_document.gif100004 100003 ⼈民币⽇报查询 tech/a1.aspx icon_settings.gif100005 100003 外币⽇报查询 tech/a2.aspx icon_settings.gif100006 0 福⽥⽀⾏ icon_document.gif100007 100006 ⽉存款进度表 a1.aspx icon_settings.gif100008 100006 ⽉存款⾛势图 a2.aspx icon_settings.gif100009 0 罗湖⽀⾏ icon_document.gif100010 100009 ⽉存款进度表 a1.aspx icon_settings.gif100011 100009 ⽉存款⾛势图 a2.aspx icon_settings.gifmenu_left.aspx⽂件如下:<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %><%@ Page language="c#" Codebehind="menu_Left.aspx.cs" AutoEventWireup="false" Inherits="hzquery.menu.menu_Left" %><HTML><HEAD><title>menu_Left</title><meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"><meta name="CODE_LANGUAGE" Content="C#"><meta name="vs_defaultClientScript" content="JavaScript"><meta name="vs_targetSchema" content=""></HEAD><body MS_POSITIONING="GridLayout"><form id="menu_Left" method="post" runat="server"><iewc:TreeView id="tvMenu" runat="server"></iewc:TreeView></form></body></HTML>CodeBehind代码如下:using System;using System.Collections;using ponentModel;using System.Data;using System.Drawing;using System.Web;using System.Web.SessionState;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.HtmlControls;using Microsoft.Web.UI.WebControls;using System.Data.SqlClient;namespace hzquery.menu{/// <summary>/// menu_Left 的摘要说明。
java递归合并树形结构以下是一个Java递归合并树形结构的示例代码:```javapublic class TreeNode {private int value;private List<TreeNode> children;public TreeNode(int value) {this.value = value;this.children = new ArrayList<>();}public void addChild(TreeNode child) {this.children.add(child);}public List<TreeNode> getChildren() {return children;}public int getValue() {return value;}}public class TreeMerger {public static TreeNode mergeTrees(TreeNode tree1, TreeNode tree2) {// 如果其中一个树为空,则返回另一个树if (tree1 == null) {return tree2;}if (tree2 == null) {return tree1;}// 创建一个新的节点,值为两个树节点的值相加TreeNode mergedTree = new TreeNode(tree1.getValue() + tree2.getValue());// 对两个树的子节点进行递归合并int size1 = tree1.getChildren().size();int size2 = tree2.getChildren().size();int maxSize = Math.max(size1, size2);for (int i = 0; i < maxSize; i++) {TreeNode child1 = (i < size1) ?tree1.getChildren().get(i) : null;TreeNode child2 = (i < size2) ?tree2.getChildren().get(i) : null;TreeNode mergedChild = mergeTrees(child1, child2);mergedTree.addChild(mergedChild);}return mergedTree;}public static void main(String[] args) {// 创建两个树TreeNode tree1 = new TreeNode(1);TreeNode child11 = new TreeNode(2);TreeNode child12 = new TreeNode(3);tree1.addChild(child11);tree1.addChild(child12);TreeNode tree2 = new TreeNode(4);TreeNode child21 = new TreeNode(5);tree2.addChild(child21);// 合并两个树TreeNode mergedTree = mergeTrees(tree1, tree2);// 输出合并后的树结构printTree(mergedTree);}public static void printTree(TreeNode root) {System.out.println(root.getValue());for (TreeNode child : root.getChildren()) {printTree(child);}}}```这个示例演示了如何通过递归合并两个树形结构。
WinForm-DevExpress控件-TreeList-树形框菜单的使⽤环境声明:使⽤控件:DevExpress16.2开发语⾔:C#开发⼯具:VS2017开发框架:WinForm#通过绑定数据List<Data>⽅式来达到树形框显⽰1.绑定数据格式public class Data{public int ID { get; set; } //数据ID,主键public string Name { get; set; } //数据名称public int GroupId { get; set; } //分组ID,当前位于树形菜单第⼏级的意思public int ParentID { get; set; } //⽗标签ID,⽗标签的数据ID}2.添加绑定列,设置绑定数据名称TreeList >> Run Designer >> Add Column,设置其绑定字段为数据名称:“Name”3.设置主键绑定数据名称TreeList >> KeyFieldName=“Id”4.设置⽗标签绑定数据名称TreeList >> ParentFieldName=“Parent”#树形框不可编辑treeList.OptionsBehavior.Editable = true;#添加节点(绑定对象模式)Data.Add(new DTO.BookList() { id = 主键, GroupId = 0, Name = "新增节点", ParentID = 0 });this.treeList.DataSource = Data;this.treeList.RefreshDataSource();#使添加的选中节点进⼊编辑状态foreach (TreeListNode node in treeList.Nodes) {if ((int)node.GetValue("id")==主键) {treeList.FocusedNode = node; //设置选中焦点到节点treeList.OptionsBehavior.Editable = true;//开启控件编辑状态treeList.ShowEditor();//进⼊编辑模式break;}}#离开编辑触发事件treeList_HiddenEditorprivate void treeList_HiddenEditor(object sender, EventArgs e){Console.WriteLine("离开编辑当前节点,可以在这⾥做⼀些后续动作");}PS:未完待续。
Hutool 是一个Java 工具包,提供了许多实用的功能,包括文件操作、日期处理、数据转换等。
`TreeNode` 是Hutool 工具包中用于表示树形结构的一个类。
在Hutool 中,`TreeNode` 类主要用于构建和操作树形结构。
你可以使用`TreeNode` 来表示一个具有父子关系的节点,每个节点可以包含多个子节点。
下面是一个简单的示例,演示了如何使用Hutool 的`TreeNode` 类来构建和操作树形结构:import cn.hutool.core.tree.TreeNode;public class TreeNodeExample {public static void main(String[] args) {// 创建根节点TreeNode<String> root = new TreeNode<>("根节点");// 创建子节点TreeNode<String> child1 = new TreeNode<>("子节点1");TreeNode<String> child2 = new TreeNode<>("子节点2");// 将子节点添加到根节点root.add(child1);root.add(child2);// 创建孙节点TreeNode<String> grandChild = new TreeNode<>("孙节点");// 将孙节点添加到子节点child1.add(grandChild);// 遍历树形结构root.forEach(node -> System.out.println(node.getName()));// 获取根节点的子节点TreeNode<String>[] children = root.getChildren();for (TreeNode<String> child : children) {System.out.println(child.getName());}// 获取节点的父节点TreeNode<String> parent = child1.getParent();System.out.println(parent.getName());// 获取节点的子节点TreeNode<String>[] subChildren = child1.getChildren();for (TreeNode<String> subChild : subChildren) {System.out.println(subChild.getName());}}}在上面的示例中,我们首先创建了一个根节点`root`,然后创建了两个子节点`child1` 和`child2`,并将它们添加到根节点中。
hutool treeutil例子【最新版】目录1.Hutool 工具简介2.TreeUtil 类介绍3.TreeUtil 的使用示例正文【1.Hutool 工具简介】Hutool 是一个 Java 工具类库,它包含了众多实用的工具类,可以帮助开发者快速完成各种常见的开发任务。
Hutool 提供了全面的解决方案,涵盖了字符串处理、文件操作、加密解密、网络编程等多个领域。
它具有易于使用、功能齐全、性能优越等特点,是 Java 开发者的得力助手。
【2.TreeUtil 类介绍】TreeUtil 是 Hutool 中的一个工具类,主要用于处理树形结构数据。
它提供了一系列实用的方法,如节点查找、节点删除、节点遍历等,可以方便地对树形数据进行操作。
TreeUtil 类继承自 java.util.TreeMap,因此它具有 TreeMap 的所有功能,同时还扩展了许多实用的方法。
【3.TreeUtil 的使用示例】下面是一个使用 Hutool TreeUtil 类的例子,演示如何创建一个简单的树形结构,并对其进行操作。
```javaimport cn.hutool.core.collection.TreeUtil;import ng.Console;import java.util.ArrayList;import java.util.List;public class TreeUtilExample {public static void main(String[] args) {// 创建一个简单的树形结构TreeUtil<String, List<String>> tree = new TreeUtil<>(String.class, List.class);tree.put("root", new ArrayList<>());tree.put("root", "child1", new ArrayList<>());tree.put("root", "child2", new ArrayList<>());// 遍历树形结构TreeUtil.traverse(tree, node ->Console.log(node.getKey()));// 查找节点Console.log(tree.get("root", "child1"));// 删除节点tree.remove("root", "child1");// 遍历更新后的树形结构TreeUtil.traverse(tree, node ->Console.log(node.getKey()));}}```这个例子中,我们首先创建了一个简单的树形结构,然后使用TreeUtil 类的方法进行了遍历、查找和删除操作。
java JMenu菜单在一个窗口中,经常需要给窗口添加菜单条。
在Java中这一部分是由JMenuBar、JMenu和JMenuItem三个类实现的,分别对应菜单条、菜单和菜单项。
1.菜单栏(JMenuBar)创建菜单栏是制作菜单的第一步,并JMenuBar的构造方法相当简单,如通过“JMenuBar TestJMenuBar=new JMenuBar();”语句即可创建。
而在设置菜单栏时,可以通过表9-22所示的常用方法。
需要说明的是,JMenuBar类根据JMenu添加的顺序从左到右显示,并建立整数索引。
2.菜单(JMenu)在添加完菜单栏后,并不会显示任何菜单内容,所以还需要在菜单栏中添加菜单内容。
菜单内容的JMenu类的构造方法有4种:●JMenu( ) 构造一个空菜单。
●JMenu(Action a) 构造一个菜单,菜单属性由相应的动作来提供。
●JMenu(String s) 用给定的标志构造一个菜单。
●JMenu(String s,Boolean b) 构造一个新JMenu,用提供的字符串作为其文本并指定其是否为分离式(tear-off)菜单。
在构造完后,使用JMenuBar类的add方法添加到菜单栏中。
而JMenu的常用方法如表9-23所示。
3.菜单项(JMenuItem)在菜单中可以添加不同的内容,可以是菜单项(JMenuItem),可以是一个子菜单,也可以是分隔符。
子菜单的添加是直接将一个子菜单添加到母菜单中,而分隔符的添加只需要将分隔符作为菜单项添加到菜单中。
菜单的该实现是一个包含JMenuItem的弹出窗口,用户选择JMenuBar上的项时会显示该JMenuItem。
除JMenuItem之外,JMenu还可以包含JSeparator。
其菜单项的构建方法如下:●JMenuItem() 创建不带有设置文本或图标的JMenuItem。
●JMenuItem(Action a) 创建从指定的Action获取其属性的菜单项。
hutool包treeutil用法
Hutool 是一个常用的 Java 工具包,其中的 TreeUtil 类可以用于构造树形结构。
以下是 TreeUtil 的一些常见用法:
1. 构造节点列表:首先,需要将三级树形目录转换为节点列表,每个节点包含节点 ID、父节点 ID 和节点名称等信息。
2. 构建树形结构:使用`TreeUtil.build(nodeList, 0)`方法可以快速构建树形结构,参数`nodeList`为节点列表,0 为根节点的父节点 ID。
3. 遍历树形结构:可以使用`TreeUtil.bfs(tree)`方法遍历整个树形结构,该方法会按照层级顺序遍历,并返回遍历结果列表。
4. 获取指定节点下的所有子节点:可以使用`TreeUtil.subtree(node)`方法获取指定节点的子树结构。
在使用 TreeUtil 时,可以根据具体需求配置节点名称、孩子节点 key 信息、排序字段等信息。
你可以参考 Hutool 官方文档或相关教程,了解 TreeUtil 的更多用法。
hutool treeutil例子Hutool TreeUtil例子1. 简介Hutool是一个Java工具包,提供了各种各样的工具类,其中之一是TreeUtil。
TreeUtil是一个树结构工具类,用于处理树形数据结构的相关操作。
本文将介绍一些使用TreeUtil的例子,并详细讲解每个例子的实现方法。
2. 生成树结构使用TreeUtil可以将一个列表转换为树结构。
首先,我们需要定义一个节点类,包含节点的唯一标识符和父节点的标识符。
接下来,假设我们有一个列表,其中每个元素都有唯一的id和parentId。
我们可以使用TreeUtil的build方法将该列表转换为树结构。
class Node {private String id;private String parentId;// getter和setter省略 ...}List<Node> nodeList = new ArrayList<>();// 假设nodeList中包含了一些节点数据List<Node> tree = (nodeList, "root");在上述例子中,我们将nodeList转换成了以”root”作为根节点的树结构。
build方法还支持传入一个函数式接口作为参数,用于自定义根节点的查找方式。
3. 遍历树结构TreeUtil还提供了遍历树结构的方法,例如先序遍历、后序遍历和层序遍历。
我们可以使用这些方法对树结构进行操作。
// 先序遍历(tree, (node) -> (()));// 后序遍历(tree, (node) -> (()));// 层序遍历(tree, (node) -> (()));这些遍历方法接受一个函数式接口参数,用于处理遍历到的每个节点。
在上述例子中,我们简单地将节点的id打印出来。
4. 获取树节点通过节点的唯一标识符,我们可以很容易地获取树结构中的某个节点。
echartstree【树形列表,右键出现菜单】【转】:1,列表上右键事件 treeNodeonRightClick,代码中有2,⾃定义右键菜单内容 getNodeTreeRightClickMenu,代码中有3,return下⾯写⼊右键菜单内容 {this.getNodeTreeRightClickMenu()}4,效果图5,详细代码import React, { PureComponent } from'react';import { findDOMNode } from'react-dom';import moment from'moment';import { Link } from'react-router-dom';import { connect } from'dva';import { Row, Col, Table, Radio, Input, Form, Button, Icon, DatePicker, Select, Modal, Popconfirm, Badge, Dropdown, Tree, Menu, Popover, } from'antd'; import styles from'./departmentList.less';const FormItem = Form.Item;const RadioButton = Radio.Button;const RadioGroup = Radio.Group;const SelectOption = Select.Option;const { Search, TextArea } = Input;const { TreeNode } = Tree;const treeData = [{}];@Form.create()class DepartmentList extends PureComponent {state = {expandedKeys: ['1', '2', '4'],autoExpandParent: true,checkedKeys: [],selectedKeys: [],value2: 'Apple',treeData: [],department_id: '',rightClickNodeTreeItem: {pageX: '',pageY: '',id: '',categoryName: '',},display: 'block',};componentDidMount() {const departmentsListTree = this.props.departmentList;this.setState({treeData: departmentsListTree,});}// 展开onExpand = (expandedKeys, expanded, record) => {// console.log('onExpand', expandedKeys);this.setState({expandedKeys,autoExpandParent: false,});};// 选择节点onSelect = (selectedKeys, info) => {console.log('selected', selectedKeys, info);const departmentId = info.selectedNodes[0].props.dataRef.id;// console.log('departmentId', departmentId);const { dispatch } = this.props;dispatch({ type: 'department/userRole', payload: { department_id: departmentId } });// console.log('id',info.selectedNodes[0].props.dataRef.id);};// 读取⼦节点renderTreeNodes = data =>data.map(item => {if (item.children) {return (<TreeNode title={} key={item.id} dataRef={item} data-key={item.id} data-title={item.categoryName} > {this.renderTreeNodes(item.children)}</TreeNode>);}return <TreeNode {...item} dataRef={item} />;});// tree列表上右键事件treeNodeonRightClick = e => {this.setState({display: 'block',rightClickNodeTreeItem: {pageX: e.event.pageX,pageY: e.event.pageY,id: e.node.props['data-key'],categoryName: e.node.props['data-title'],},});// console.log("id::",e.node.props["title"])};// 点击取消隐藏hideRight = e => {this.setState({display: 'none',});console.log(this.state);};// ⾃定义右键菜单内容getNodeTreeRightClickMenu = () => {// alert(33)const { pageX, pageY, id } = { ...this.state.rightClickNodeTreeItem };// console.log("右键菜单id:",id);const tmpStyle = {position: 'absolute',left: `${pageX + 40}px`,top: `${pageY - 12}px`,display: this.state.display,};const menu = (<div style={tmpStyle} className={styles.selfrightmenu} onMouseLeave={this.hideRight}><Link to={{ pathname: '/SetUp/department/edit', query: { id: id } }}><a>编辑</a></Link><Popconfirm title="确定删除此记录?" onConfirm={() => this.deleteDepartment(id)}><a href="javascript:;"><a>删除</a></a></Popconfirm><Link to={{ pathname: '/SetUp/userSet/edit', query: { department_id: id } }}><a href="javascript:;">添加⽤户</a></Link><Link to={{ pathname: '/SetUp/department/edit', query: { parent_id: id } }}><a style={{ borderBottom: '1px solid gainsboro', paddingBottom: '10px', display: ' block', }}>添加部门</a></Link><Button onClick={this.hideRight} style={{ marginLeft: '15px', marginTop: '10px' }}>取消</Button></div>);return this.state.rightClickNodeTreeItem == null ? '' : menu;};render() {const formItemLayout = {labelCol: {xs: { span: 20 },sm: { span: 6 },},wrapperCol: {xs: { span: 20 },sm: { span: 12 },},};const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form; const modalVisible = this.props.modalVisible;const { dispatch } = this.props;const departmentsListTree = this.props.departmentList;const { checkedKeys, selectedValue, treeData, checkNodes, expandedKeys } = this.state; return (<div className={styles.listback}><div style={{ width: '35%', float: 'left' }}><h3>部门树</h3><TreeshowLineexpandedKeys={this.state.expandedKeys}onSelect={this.onSelect}onExpand={this.onExpand}onRightClick={this.treeNodeonRightClick}>{this.renderTreeNodes(departmentsListTree)}</Tree>{this.getNodeTreeRightClickMenu()}</div></div>);}}function mapStateToProps(state) {return { ...state.department };}export default connect(mapStateToProps)(DepartmentList);。
将List数据转成树的两种⽅式(递归、循环)在做⽤户菜单权限的时候(因为多张表关联外键,hibernate返回回去会出现⽆限循环),所以把他转换成和数据库⽆关的VO类即可⼀、VO类如下***** 封装菜单的树形结构* @author 六松岛福⼩林***/public class MenuTree implements java.io.Serializable {/*** 树形节点id*/private String id;/*** 菜单级别 0为第⼀级菜单,1为第⼆级菜单……*/private String level;/*** ⽗级树形id*/private String parentId;/*** 树形节点名称*/private String name;/*** 对应的菜单图⽚路径*/private String imagePath;/*** 菜单对应的url地址*/private String url;/*** ⼦节点list*/private List<MenuTree> children;……对应的Getter和Setter 这个在此省略……}⼆、封装的树形⼯具类如下备注:循环和递归使⽤任何⼀种即可/*** 两层循环实现建树* @param menuTrees 传⼊的树节点列表* @return List<MenuTree> ⼦节点集合*/public static List<MenuTree> build(List<MenuTree> menuTrees) {//返回的树形结构数据List<MenuTree> trees = new ArrayList<>();//循环菜单树形数据for (MenuTree menuTree : menuTrees) {//菜单级别为0,则是⼀级数据,根据实际情况判断可修改相关关联判断if("0".equals(menuTree.getLevel())){trees.add(menuTree);for (MenuTree it : menuTrees) {//找出⼀级菜单下⾯的所有⼆级菜单,并加⼊到list中去if (menuTree.getId().equals(it.getParentId())) {if (menuTree.getChildren() == null) {menuTree.setChildren(new ArrayList<MenuTree>());}menuTree.getChildren().add(it);}}}}return trees;}/*** 使⽤递归⽅法建树* @param menuTrees ⼦节点集合* @return List<MenuTree>*/public static List<MenuTree> buildByRecursive(List<MenuTree> menuTrees) {List<MenuTree> trees = new ArrayList<>();for (MenuTree menuTree : menuTrees) {//菜单级别为0,则是⼀级数据,根据实际情况判断可修改相关关联判断if ("0".equals(menuTree.getLevel())) {trees.add(findChildren(menuTree,menuTrees));}}return trees;}/*** 递归查找⼦节点* @param menuTree 菜单数对象* @param menuTrees ⼦节点* @return MenuTree*/private static MenuTree findChildren(MenuTree menuTree,List<MenuTree> menuTrees) {for (MenuTree it : menuTrees) {if(menuTree.getId().equals(it.getParentId())) {if (menuTree.getChildren() == null) {menuTree.setChildren(new ArrayList<MenuTree>());}menuTree.getChildren().add(findChildren(it,menuTrees));}}return menuTree;}三、调⽤/***根据⽤户id返回菜单的树形数据* @param userId ⽤户的id* @param systemService 操作数据库的service* @return 封装好的菜单树形数据*/public static List<MenuTree> getMenuTreeList(String userId, SystemService systemService) throws Exception{ //查询该⽤户所有的菜单数据List<Map<String, Object>> menuDataList = getMenuDataList(userId, systemService);//封装成菜单对象listList<MenuTree> menuList = getMenuList(menuDataList);//调⽤封装树形数据⽅法return TreeBuilder.build(menuList);}仍在不断学习中,如有不妥还望各位⼤神留⾔指教代码下载地址在下⼀篇根据⽤户查询相关菜单的博客中。
Composite模式将对象组合成树形结构以表示“整体—部分”的层次结构。
Composite模式使单个对象和组合对象的使用具有一致性。
如果把Composite模式看成是树形结构的话,那么它主要角色有:1) 树干角色(Component):该角色是一个抽象类,它定义了一些操作增删树叶(Leaf)的操作。
2)树枝角色(Composite):树枝上有很多树干,树枝也是树干的一种。
3) 树叶角色(Leaf):树干上的树叶,也就是Component中的具体操作对象。
说到Composite模式,让我想到以前项目中遇到的一个问题,做一个影视节目列表的树形结构,要求支持二级分类,由于当时还没接触过设计模式,这个东西让我搞了好久,才弄好。
现在使用Composite模式来解决这个问题,简直太简单了,别说是二级了,N级都没问题。
下面我就用Composite来实现它,代码如下:import java.util.ArrayList;abstract class MovieClass{//Componentpublic String name;public ArrayList<MovieClass> list;public abstract void add(MovieClass component);public abstract void remove(MovieClass component);public abstract void display();}class Program extends MovieClass{//Leafpublic Program(String name){=name;}public void add(MovieClass component){System.out.println("you can't add component to a proagram object");}public void display() {System.out.println("----------"+name);}public void remove(MovieClass component) {System.out.println("you can't remove component to a proagram object");}}class ConcreteMovieClass extends MovieClass{//Compositepublic ConcreteMovieClass(String name){=name;list=new ArrayList<MovieClass>();}public void add(MovieClass component) {list.add(component);}public void remove(MovieClass component) {if(list.contains(component)){list.remove(component);}}public void display(){System.out.println(name);for(MovieClass mc:list){mc.display();}}}public class Client {public static void main(String args[]){Program pro=new Program("大汉天子");Program pro2=new Program("贞观长歌");ConcreteMovieClass cmc=new ConcreteMovieClass("电视连续剧");//一级分类cmc.add(pro);cmc.add(pro2);Program pro3=new Program("满城尽带黄金甲");Program pro4=new Program("色戒");ConcreteMovieClass cmc2=new ConcreteMovieClass("最新影视");//一级分类cmc2.add(pro3);cmc2.add(pro4);Program pro5=new Program("越狱");Program pro6=new Program("英雄");ConcreteMovieClass secondCmc=new ConcreteMovieClass("热播美剧");//二级分类secondCmc.add(pro5);secondCmc.add(pro6);cmc2.add(secondCmc);//在一级分类(最新影视)下添加二级分类热播美剧ConcreteMovieClass root=new ConcreteMovieClass("root");root.add(cmc);root.add(cmc2);root.display();//显示节目列表}}这个例子只是一个简单的模拟并不通用,在我们的实际应用中,节目的来源(也就是Leaf)基本上都是从数据中读出来放到一个javabean中,我们不可能让这个bean来再来继承我们的(Component),至少绝大部分情况是这样,而且还要有很多操作要实现,如判断一个component是否是单个对象还是一个对象的组合,这个对象是否有子节点(Component),父节点(Component)以及异常处理等等。
java list 树形数据排序方法Java中的List是一种常见的数据结构,它可以存储多个元素,并且可以动态地调整大小。
在实际的开发中,我们经常会遇到需要对树形数据进行排序的需求。
本文将介绍一些常用的方法和技巧,帮助我们对Java List中的树形数据进行排序。
一、树形数据结构简介树形数据结构是一种层次化的数据结构,它由节点和边组成。
每个节点可以有多个子节点,但只能有一个父节点,树形数据结构中的节点之间存在一种层次关系。
常见的树形数据结构有二叉树、多叉树和平衡树等。
二、List中树形数据的排序方法1. 自定义比较器在Java中,我们可以使用自定义比较器来对List中的树形数据进行排序。
比较器是一个实现了Comparator接口的类,它定义了比较两个对象的规则。
我们可以根据树形数据的特点,编写自定义比较器来实现排序。
例如,假设我们有一个树形数据的类TreeNode,它有一个属性value表示节点的值,还有一个属性children表示子节点列表。
我们可以编写一个自定义比较器TreeComparator来比较两个TreeNode对象的大小。
```javapublic class TreeComparator implements Comparator<TreeNode> {@Overridepublic int compare(TreeNode node1, TreeNode node2) {// 比较两个节点的值return node1.getValue().compareTo(node2.getValue());}}```然后,我们可以使用Collections.sort方法来对List中的树形数据进行排序。
```javaList<TreeNode> treeList = new ArrayList<>();// 添加树形数据到List中// ...// 使用自定义比较器进行排序Collections.sort(treeList, new TreeComparator());```2. 递归排序如果树形数据的结构比较复杂,或者我们需要按照多个属性进行排序,可以使用递归排序的方法。
Unity UGUI自定义树形菜单(TreeView)如果你需要的也是这种效果,那你就来对地方了!目前,我们这个树形菜单展现出来的功能如下:1、可以动态配置数据源;2、点击每个元素的上下文菜单按钮(也就是图中的三角形按钮),可以收缩或展开它的子元素;3、可以单独判断某一元素的复选框是否被勾选,或者直接获取当前树形菜单中所有被勾选的元素;4、树形菜单统一控制其下所有子元素按钮的事件分发;5、可自动调节的滚动视野边缘,根据当前可见的子元素数量进行横向以及纵向的伸缩;一、首先,我们先制作子元素的模板(Template),也就是图中菜单的单个元素,用它来根据数据源动态克隆出多个子元素,这里的话,很显然我们的模板是由两个Button加一个Toggle和一个Text组成的,如下:二、我们的每个子元素都会携带一个TreeViewItem脚本,用于描述自身在整个树形菜单中与其他元素的父子关系,而整个树形菜单的控制由TreeViewControl来实现,首先,TreeViewControl会根据提供的数据源来生成所有的子元素,当然,改变数据源之后进行重新生成的时候也是这个方法,干的事情很简单,就是用模板不停的创建元素,并给他们建立父子关系:[csharp] view plain copy/// <summary>/// 生成树形菜单/// </summary>public void GenerateTreeView(){//删除可能已经存在的树形菜单元素if (_treeViewItems != null){for (int i = 0; i < _treeViewItems.Count; i++){Destroy(_treeViewItems[i]);}_treeViewItems.Clear();}//重新创建树形菜单元素_treeViewItems = new List<GameObject>();for (int i = 0; i < Data.Count; i++){GameObject item = Instantiate(Template);if (Data[i].ParentID == -1){item.GetComponent<TreeViewItem>().SetHierarchy(0);item.GetComponent<TreeViewItem>().SetParent(null);}else{TreeViewItem tvi = _treeViewItems[Data[i].ParentID].GetComponent<TreeViewItem>();item.GetComponent<TreeViewItem>().SetHierarchy(tvi.GetHierarchy() + 1);item.GetComponent<TreeViewItem>().SetParent(tvi);tvi.AddChildren(item.GetComponent<TreeViewItem>());} = "TreeViewItem";item.transform.FindChild("TreeViewText").GetComponent<Text>().text = Data[i].Name;item.transform.SetParent(TreeItems);item.transform.localPosition = Vector3.zero;item.transform.localScale = Vector3.one;item.transform.localRotation = Quaternion.Euler(Vector3.zero);item.SetActive(true);_treeViewItems.Add(item);}}三、树形菜单生成完毕之后此时所有元素虽然都记录了自身与其他元素的父子关系,但他们的位置都是在Vector3.zero的,毕竟我们的菜单元素在创建的时候都是一股脑儿的丢到原点位置的,创建君可不管这么多元素挤在一堆会不会憋死,好吧,之后规整列队的事情就交给刷新君来完成了,刷新君玩的一手好递归,它会遍历所有元素并剔除不可见的元素(也就是点击三角按钮隐藏了),并将它们一个一个的重新排列整齐,子排在父之后,孙排在子之后,以此类推......它会遍历每个元素的子元素列表,发现子元素可见便进入子元素列表,发现孙元素可见便进入孙元素列表:[csharp] view plain copy/// <summary>/// 刷新树形菜单/// </summary>public void RefreshTreeView(){_yIndex = 0;_hierarchy = 0;//复制一份菜单_treeViewItemsClone = new List<GameObject>(_treeViewItems);//用复制的菜单进行刷新计算for (int i = 0; i < _treeViewItemsClone.Count; i++){//已经计算过或者不需要计算位置的元素if (_treeViewItemsClone[i] == null || !_treeViewItemsClone[i].activeSelf){continue;}TreeViewItem tvi = _treeViewItemsClone[i].GetComponent<TreeViewItem>();_treeViewItemsClone[i].GetComponent<RectTransform>().localPosition = new Vector3(tvi.GetHierarchy() * HorizontalItemSpace, _yIndex,0);_yIndex += (-(ItemHeight + VerticalItemSpace));if (tvi.GetHierarchy() > _hierarchy){_hierarchy = tvi.GetHierarchy();}//如果子元素是展开的,继续向下刷新if (tvi.IsExpanding){RefreshTreeViewChild(tvi);}_treeViewItemsClone[i] = null;}//重新计算滚动视野的区域float x = _hierarchy * HorizontalItemSpace + ItemWidth;float y = Mathf.Abs(_yIndex);transform.GetComponent<ScrollRect>().content.sizeDelta = new Vector2(x, y);//清空复制的菜单_treeViewItemsClone.Clear();}/// <summary>/// 刷新元素的所有子元素/// </summary>void RefreshTreeViewChild(TreeViewItem tvi){for (int i = 0; i < tvi.GetChildrenNumber(); i++){tvi.GetChildrenByIndex(i).gameObject.GetComponent<RectTransform>().localPosition = new Vector3(tvi.GetChildrenByIndex(i).GetHierarchy() * HorizontalItemSpace, _yIndex, 0);_yIndex += (-(ItemHeight + VerticalItemSpace));if (tvi.GetChildrenByIndex(i).GetHierarchy() > _hierarchy){_hierarchy = tvi.GetChildrenByIndex(i).GetHierarchy();}//如果子元素是展开的,继续向下刷新if (tvi.GetChildrenByIndex(i).IsExpanding){RefreshTreeViewChild(tvi.GetChildrenByIndex(i));}int index = _treeViewItemsClone.IndexOf(tvi.GetChildrenByIndex(i).gameObject);if (index >= 0){_treeViewItemsClone[index] = null;}}}我这里将所有的元素复制了一份用于计算位置,主要就是为了防止在进行一轮刷新时某个元素被访问两次或以上,因为刷新的时候会遍历所有可见元素,如果第一次访问了元素A(元素A的位置被刷新),根据元素A的子元素列表访问到了元素B(元素B的位置被刷新),一直到达子元素的底部后,当不存在更深层次的子元素时,那么返回到元素A之后的元素继续访问,这时在所有元素列表中元素B可能在元素A之后,也就是说元素B已经通过父元素访问过了,不需要做再次访问,他的位置已经是最新的了,而之后根据列表索引很可能再次访问到元素B,如果是这样的话元素B的位置又要被刷新一次,甚至多次,性能影响不说,第二次计算的位置已经不是正确的位置了。
Java常⽤命令汇总这篇⽂章就主要向⼤家展⽰了Java编程中常⽤的命令,下⾯看下具体内容。
1、javac将⽂件编译成.class⽂件⽤法: javac <options> <source files>其中, 可能的选项包括:-g ⽣成所有调试信息-g:none 不⽣成任何调试信息-g:{lines,vars,source} 只⽣成某些调试信息-nowarn 不⽣成任何警告-verbose 输出有关编译器正在执⾏的操作的消息-deprecation 输出使⽤已过时的 API 的源位置-classpath <路径> 指定查找⽤户类⽂件和注释处理程序的位置-cp <路径> 指定查找⽤户类⽂件和注释处理程序的位置-sourcepath <路径> 指定查找输⼊源⽂件的位置-bootclasspath <路径> 覆盖引导类⽂件的位置-extdirs <⽬录> 覆盖所安装扩展的位置-endorseddirs <⽬录> 覆盖签名的标准路径的位置-proc:{none,only} 控制是否执⾏注释处理和/或编译。
-processor <class1>[,<class2>,<class3>...] 要运⾏的注释处理程序的名称; 绕过默认的搜索进程-processorpath <路径> 指定查找注释处理程序的位置-d <⽬录> 指定放置⽣成的类⽂件的位置-s <⽬录> 指定放置⽣成的源⽂件的位置-implicit:{none,class} 指定是否为隐式引⽤⽂件⽣成类⽂件-encoding <编码> 指定源⽂件使⽤的字符编码-source <发⾏版> 提供与指定发⾏版的源兼容性-target <发⾏版> ⽣成特定 VM 版本的类⽂件-version 版本信息-help 输出标准选项的提要-A关键字[=值] 传递给注释处理程序的选项-X 输出⾮标准选项的提要-J<标记> 直接将 <标记> 传递给运⾏时系统-Werror 出现警告时终⽌编译@<⽂件名> 从⽂件读取选项和⽂件名2、java执⾏ .class⽂件,若类中没有main函数,则不能执⾏。
BootStrapJstree树形菜单的增删改查的实现源码1.⾸先需下载jstree的插件点击打开链接2.在页⾯引⼊插件js⽂件css⽂件<link rel="stylesheet" href="plugins/jstree/themes/classic/style.css" rel="external nofollow" ><script type="text/javascript" src="plugins/jstree/_lib/jquery.js"></script><script type="text/javascript"src="plugins/jstree/_lib/jquery.cookie.js"></script><script type="text/javascript"src="plugins/jstree/_lib/jquery.hotkeys.js"></script><script type="text/javascript" src="plugins/jstree/jquery.jstree.js"></script>3.初始化控件1)html<div id="demo2" class="demo" style="height:100px;"></div>2)js 使⽤ demo2来初始化树形控件<script type="text/javascript" class="source below">$(function() {$("#demo2").jstree({"json_data" : {"ajax" : {"url" : "http://localhost:8080/MemberManager/DepartmentTreeJson","data" : function(n) {// the result is fed to the AJAX request `data` optionreturn {"operation" : "get_children","id" : n.attr ? n.attr("id").replace("node_",""): 1};}}},"plugins" : ["themes","json_data","ui","crrm","contextmenu","search" ],}).bind("loaded.jstree",function(event, data) {}).bind("select_node.jstree",function(event, data) {if (data.rslt.obj.attr("id") != undefined) {}}).bind("remove.jstree",function(e, data) {data.rslt.obj.each(function() {$.ajax({async : false,type : 'POST',url : "http://localhost:8080/MemberManager/CreateNodeForDepartment",data : {"operation" : "remove_node","id" : this.id.replace("node_", "")},success : function(r) {if (!r.status) {data.inst.refresh();}}});});}).bind("remove.jstree",function(e, data) {data.rslt.obj.each(function() {$.ajax({async : false,type : 'POST',url : "http://localhost:8080/MemberManager/CreateNodeForDepartment", data : {"operation" : "remove_node","id" : this.id.replace("node_","")},success : function(r) {if (!r.status) {data.inst.refresh();}}});});}).bind("create.jstree",function(e, data) {$.post("http://localhost:8080/MemberManager/CreateNodeForDepartment",{"operation" : "create_node","id" : data.rslt.parent.attr("id").replace("node_",""),"position" : data.rslt.position,"title" : ,"type" : data.rslt.obj.attr("rel")},function(r) {if (r.status) {$(data.rslt.obj).attr("id", "node_" + r.id);} else {data.inst.refresh();$.jstree.rollback(data.rlbk);}});}).bind("rename.jstree",function(e, data) {$.post("http://localhost:8080/MemberManager/CreateNodeForDepartment",{"operation" : "rename_node","id" : data.rslt.obj.attr("id").replace("node_",""),"title" : data.rslt.new_name},function(r) {if (!r.status) {data.inst.refresh();$.jstree.rollback(data.rlbk);}});})// 1) the loaded event fires as soon as data is parsed and inserted// 2) but if you are using the cookie plugin or the core `initially_open` option:.one("reopen.jstree",function(event, data) {})// 3) but if you are using the cookie plugin or the UI `initially_select` option:.one("reselect.jstree",function(event, data) {});});</script></pre>4.代码解析<p></p><p><pre name="code" class="java">import java.util.List;public class Department {// 部门idprivate String departmentid;// 部门名称private String name;// ⽗级部门IDprivate String parentid;//同级之间的排序。
java解析出多个根节点树形结构的方法 ### Java解析出多个根节点树形结构的方法 在Java编程中,树形结构是一种常见的数据结构,特别是在表示具有层次关系的元素时,如文件系统的目录、组织架构等。当树形结构包含多个根节点时,解析这样的结构需要特别的处理。以下是几种在Java中解析具有多个根节点的树形结构的方法。 #### 1.使用递归遍历 递归是处理树形结构的一种直观方法。如果树节点类设计得当,可以通过递归方式遍历整个树。 ```java class TreeNode { private int id; private int parentId; private List children; // Getters and Setters } public List parseMultiRootTree(List nodes) { Map nodeMap = new HashMap<>(); List roots = new ArrayList<>(); // 将所有节点放入哈希表 for (TreeNode node : nodes) { nodeMap.put(node.getId(), node); } // 构建树形结构 for (TreeNode node : nodes) { if (node.getParentId() != null) { TreeNode parent = nodeMap.get(node.getParentId()); if (parent != null) { parent.getChildren().add(node); } } else { roots.add(node); } } return roots; } ``` #### 2.使用迭代和栈 如果树特别深或者担心递归导致的栈溢出,可以使用迭代和栈来遍历。 ```java public List parseMultiRootTreeIterative(List nodes) { Map nodeMap = new HashMap<>(); List roots = new ArrayList<>();
用java 生成一个树形菜单 package com.csii; import java.awt.GridLayout; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeSelectionModel; public class TreeDemo1 extends JFrame implements TreeSelectionListener { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JTree jTree = null; private JEditorPane jEditorPane = null; private JScrollPane jScrollPane = null; public JScrollPane getjScrollPane() { if(jScrollPane==null){ jScrollPane = new JScrollPane(); jScrollPane.setViewportView(getJTree()); } return jScrollPane; } DefaultMutableTreeNode top = null; // @jve:decl-index=0: /** * This is the default constructor */ public TreeDemo1() { super(); initialize(); } /** * This method initializes this * * @return void */ private void initialize() { this.setSize(438, 309); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setContentPane(getJContentPane()); this.setTitle("JFrame"); } /** * This method initializes jContentPane * * @return javax.swing.JPanel */ private JPanel getJContentPane() { if (jContentPane == null) { GridLayout gridLayout = new GridLayout(); gridLayout.setRows(1); gridLayout.setColumns(2); jContentPane = new JPanel(); jContentPane.setLayout(gridLayout); jContentPane.add(getjScrollPane(), null); jContentPane.add(getJEditorPane(), null); } return jContentPane; } /** * This method initializes jTree * * @return javax.swing.JTree */ private JTree getJTree() { if (jTree == null) { top = new DefaultMutableTreeNode("黄山"); createNodes(top); jTree = new JTree(top); jTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); jTree.addTreeSelectionListener(this); } return jTree; } private void createNodes(DefaultMutableTreeNode top) { DefaultMutableTreeNode jingdian = null, jiaotong = null, zhusu = null, binguan = null, luying = null, jiesu = null; jingdian = new DefaultMutableTreeNode("景点"); jingdian.add(new DefaultMutableTreeNode("景点1")); jingdian.add(new DefaultMutableTreeNode("景点2")); jiaotong = new DefaultMutableTreeNode("交通"); jiaotong.add(new DefaultMutableTreeNode("路线1")); jiaotong.add(new DefaultMutableTreeNode("路线2")); jiaotong.add(new DefaultMutableTreeNode("路线3")); zhusu = new DefaultMutableTreeNode("住宿"); zhusu.add(new DefaultMutableTreeNode("A住宿")); zhusu.add(new DefaultMutableTreeNode("B住宿")); zhusu.add(new DefaultMutableTreeNode("C住宿")); binguan = new DefaultMutableTreeNode("宾馆"); binguan.add(new DefaultMutableTreeNode("X宾馆")); binguan.add(new DefaultMutableTreeNode("Y宾馆")); binguan.add(new DefaultMutableTreeNode("Z宾馆")); binguan.add(new DefaultMutableTreeNode("XYZ宾馆")); luying = new DefaultMutableTreeNode("露营"); luying.add(new DefaultMutableTreeNode("方式1")); luying.add(new DefaultMutableTreeNode("方式2")); jiesu = new DefaultMutableTreeNode("借宿"); jiesu.add(new DefaultMutableTreeNode("借宿1")); jiesu.add(new DefaultMutableTreeNode("借宿2")); jiesu.add(new DefaultMutableTreeNode("借宿3")); top.add(jingdian); top.add(jiaotong); top.add(zhusu); top.add(binguan); top.add(luying); top.add(jiesu); } /** * This method initializes jEditorPane * * @return javax.swing.JEditorPane */ private JEditorPane getJEditorPane() { if (jEditorPane == null) { jEditorPane = new JEditorPane(); } return jEditorPane; } @Override public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree .getLastSelectedPathComponent(); if (node == null) // Nothing is selected. return; if(node.isRoot()){ jEditorPane.setText("黄山的简介"); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }catch(Exception e){ e.printStackTrace(); } new TreeDemo1().setVisible(true); } }); } }