java绘制(可视化)树结构图

article/2025/10/10 11:46:21

        以JPanel组件为画板,继承JPanel类并重写paint(Graphics g)函数,在函数中使用画笔g绘制树结构图。

实例代码——3个java源文件:Main.java、DrawNode.java、DrawTree.java

1、Main.java

package drawTree;public class Main {public static void main(String[] args){DrawTree dt = new DrawTree();DrawNode dn0 = new DrawNode("纹理",0,1024);DrawNode dn0_1 = new DrawNode(dn0,"密度","清晰");DrawNode dn0_2 = new DrawNode(dn0,"触感","稍糊");DrawNode dn0_3 = new DrawNode(dn0,"no","模糊");DrawNode dn01_1 = new DrawNode(dn0_1,"no","0.4");DrawNode dn01_2 = new DrawNode(dn0_1,"yes","0.6");DrawNode dn01_3 = new DrawNode(dn0_1,"yes","0.8");DrawNode dn02_1 = new DrawNode(dn0_2,"no","硬滑");DrawNode dn02_2 = new DrawNode(dn0_2,"yes","软粘");dt.function(dn0);}
}

2、DrawNode.java

package drawTree;public class DrawNode {String value = null;		//当前节点的属性DrawNode parentNode = null;	//父结点String lineValue = null;	//与父结点连接的属性int sonNodeNum = 0;			//子结点个数DrawNode[] sonNode = new DrawNode[10];	//子结点int depth = 0;				//深度int beginX = 0;				//以该节点为根节点的树前边界int endX = 0;				//以该节点为根节点的树后边界boolean draw = false;		//是否已经被绘制int selfX = 0;				//自身节点横坐标int selfY = 0;				//自身节点纵坐标int parentX = 0;			//父亲节点横坐标int parentY = 0;			//父亲节点纵坐标DrawNode(String value,int beginX, int endX){	//根节点构造函数this.value = value;this.beginX = beginX;this.endX = endX;this.depth = 0;this.selfX = beginX + (beginX+endX)/2;this.selfY = 0;}DrawNode(DrawNode parentNode, String value, String lineValue){	//不是根节点构造函数this.parentNode = parentNode;this.value = value;this.lineValue = lineValue;this.parentX = parentNode.selfX;this.parentY = parentNode.selfY;this.depth = parentNode.depth+1;//自身x坐标是要根据父结点的子结点的个数动态改变//this.selfX = parentNode.selfX+(-200+parentNode.sonNodeNum*200/(depth+1));	//这条语句可有可无,在树完全生成后,再确定每个节点的selfXthis.selfY = parentNode.selfY+200;parentNode.sonNodeNum++;parentNode.sonNode[parentNode.sonNodeNum-1] = this;//setAllSonX(parentNode);}}

3、DrawTree.java

package drawTree;import java.awt.Graphics;
import java.awt.image.BufferedImage;import javax.swing.*;public class DrawTree {int WIDTH = 1024;int HEIGHT = 1024; DrawNode root = null;void function(DrawNode dn){JFrame jf = new JFrame();jf.setTitle("树");jf.setSize(WIDTH, HEIGHT);MyPanel mp = new MyPanel();setX(dn);mp.root = dn;jf.add(mp);jf.setVisible(true);}//递归函数,设置树中每个节点的selfXvoid setX(DrawNode root){//设置子结点的beginX和endXint gap = (root.endX-root.beginX)/(root.sonNodeNum+1);for(int i=0;i<root.sonNodeNum;i++){root.selfX = root.beginX+(root.endX-root.beginX)/2;root.sonNode[i].selfX = root.beginX+(i+1)*gap;root.sonNode[i].beginX = root.sonNode[i].selfX-gap/2;root.sonNode[i].endX = root.sonNode[i].selfX + gap/2;root.sonNode[i].parentX = root.selfX;if(root.sonNode[i]!= null){setX(root.sonNode[i]);}}}
}class MyPanel extends JPanel{DrawNode root = null;private static final long serialVersionUID = 1L;public void paint(Graphics g){//调用paint获得组件JPanel的画笔,以组件为画板DrawNode tmp = root;int x = 0;int num = 0;if(tmp != null){num = 1;}//类似非递归函数遍历树的节点while(x<num){	//int depth = tmp.depth;if(tmp.draw == false){if(tmp.sonNodeNum==0){}else{num = num + tmp.sonNodeNum;}g.drawOval(tmp.selfX, tmp.selfY, 50, 50);g.drawString(tmp.value, tmp.selfX+25, tmp.selfY+25);if(tmp != root){g.drawLine(tmp.selfX+25, tmp.selfY+25, tmp.parentX+25, tmp.parentY+25);g.drawString(tmp.lineValue, (tmp.selfX+tmp.parentX+50)/2, (tmp.selfY+tmp.parentY+50)/2);}tmp.draw = true;x++;}else{int y = -1;for(int i=0;i<tmp.sonNodeNum;i++){if(tmp.sonNode[i].draw == false){y=i;break;}}if(y!=-1){	//还有子结点为绘画。tmp = tmp.sonNode[y];continue;	//进入子结点,重新循环}else{		//之下的全部结点都以绘完if(tmp ==root){break;	//为根节点就退出}else{tmp = tmp.parentNode;continue;}}}if(tmp.sonNodeNum == 0){	//叶子节点,回到父结点tmp = tmp.parentNode;}else{						//不是叶子节点,进入下一层tmp = tmp.sonNode[0];}}}
}

运行结果:

新人,代码不好,多多包含。。。

        之后可能会尽可能地完善一下。。

补充01:

代码运行方式:

        1、放在eclipse项目的同一个包下,且三个java文件中的package要一致,即可直接运行。

        2、控制台运行步骤:

                

 


http://chatgpt.dhexx.cn/article/74egu6ue.shtml

相关文章

Java的理论知识以及结构图

Java基础 1、 简述Java的基本历史 java起源于SUN公司的一个GREEN的项目&#xff0c;其原先目的是&#xff1a;为家用消费电子产品发送一个信息的分布式代码系统&#xff0c;通过发送信息控制电视机、冰箱等 2、 简单写出Java特点&#xff0c;写出5个以上&#xff0c;越多越好…

Swagger使用教程及Swagger增强工具knife4j

标题 课外知识须知什么是swagger什么是RESTful 面向资源URI和URL区别&#xff1a; 博址推荐SpringBoot集成SwaggerSwagger常用注解Swagger增强工具knife4j 重点掌握&#xff1a;编写swagger的配置文件&#xff0c;理解每个配置的作用 课外知识须知 Swagger官网&#xff1a; …

JVM快速入门(类加载,对象创建,运行数据区,GC垃圾回收算法,jvm调优)

JVM快速入门 JVM定义&#xff1a;常见的几种jvmJDK&#xff0c;JRE&#xff0c;JVM区别 类加载过程类加载器作用加载器分类双亲委派机制好处 全盘委托机制 对象的创建流程类加载校验分配内存设置初值设置对象头对象头中的Mark Word 字段&#xff08;32位&#xff09;对象头中的…

一起学JVM(GC可视化工具Visual GC)

导读 众所周知&#xff0c;JVM&#xff08;java虚拟机&#xff09;运行着我们的java程序。java本身提供了自带工具VisualVM来帮助我们查看JVM的运行情况&#xff0c;下面主要介绍GC的可视化插件&#xff0d;Visual GC java版本 1.8.0_281 工具 VisualVM 的 Visual GC 插…

JVM G1详解

java程序性能 当我们调优java程序时&#xff0c;通常的目标有两个&#xff1a; 响应能力 或者 吞吐量 响应能力 响应能力指一个程序或者系统对请求的是否能够及时响应。 比如&#xff1a; 一个桌面UI能多快的响应一个事件&#xff1b; 一个网站能够多快返回一个页面请求&…

最简单的JVM内存结构图

目录 JVM内存结构图 方法区 堆 栈 程序计数器 本地方法栈 直接内存 内存分配性能优化-逃逸分析 总结 JVM内存结构图 大家好&#xff0c;好几天没有更新了&#xff0c;今天的内容有点多&#xff0c;我们详细介绍下JVM内部结构图&#xff0c;还是和之前一样&#xff0c;案…

JVM进阶(十一):JAVA G1收集器

文章目录 一、前言 一、前言 G1(Garbage First)垃圾收集器是当今垃圾回收技术最前沿的成果之一。早在JDK7就已加入JVM的收集器大家庭中&#xff0c;成为HotSpot重点发展的垃圾回收技术。同优秀的CMS垃圾回收器一样&#xff0c;G1也是关注最小时延的垃圾回收器&#xff0c;也同…

JVM监控之图形化工具

一、工具概述 使用命令行工具存在以下的局限性&#xff1a; 无法获取方法级别的分析数据&#xff0c;如方法之间的调用关系、各方法的调用次数和调用时间等要去用户登陆到java应用所在的宿主机上分析数据通过终端输出&#xff0c;结构不够直观 随着java应用的官方使用&#…

Java 知识结构图

简介 《 值得去的地方&#xff0c;没有捷径&#xff1b;难走的路才更值得开始 》 为什么要说这个【知识结构图】呢&#xff0c;其实是针对于刚开始学习&#xff0c;工作或工作一段时间的人&#xff0c;每天忙&#xff0c;杂七杂八&#xff0c;自己身心巨累&#xff0c;又想要偷…

Java程序员必备基础结构图

前言 最近看了深入理解Java虚拟机第三版&#xff0c;整理了一些基础结构图&#xff0c;算是比较全的了&#xff0c;做一下笔记&#xff0c;大家一起学习。 1.Java虚拟机运行时数据区图 JVM内存结构是Java程序员必须掌握的基础。 程序计数器 程序计数器&#xff0c;可以看作…

JVM 结构图

一&#xff1a;Java技术体系模块图 二&#xff1a;JVM内存区域模型 1.方法区 也称"永久代” 、“非堆”&#xff0c; 它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。默认最小值为16MB&#xff0c;最大值为64MB&#xff0c;可以通过-XX:Per…

JVM结构、GC工作机制详解

题外话&#xff1a;最近在应聘阿里2015暑期实习&#xff0c;感触颇多。机会总是留给有准备的人的&#xff0c;所以平常一定要注意知识的巩固和积累。知识的深度也要有一定的理解&#xff0c;不比别人知道的多&#xff0c;公司干嘛选你&#xff1f;关于JVM和GC&#xff0c;我相信…

详解 JVM Garbage First(G1) 垃圾收集器

前言 Garbage First(G1)是垃圾收集领域的最新成果,同时也是HotSpot在JVM上力推的垃圾收集器,并赋予取代CMS的使命。如果使用Java 8/9,那么有很大可能希望对G1收集器进行评估。本文详细首先对JVM其他的垃圾收集器进行总结,并与G1进行了简单的对比;然后通过G1的内存模型、G1…

【JVM】JVM内存结构之——G1收集器

目录 1. 什么是G12. G1收集器发展历程3. G1收集器分区划分3.1 为什么G1收集器需要设计巨型对象3.2 G1收集器参数设置 3.3 G1收集器回收的细节3.4 G1收集器Rset问题&#xff08;记忆集&#xff09;3.5 G1两种回收策略4. G1收集器优缺点 5. G1收集器核心配置参数 1. 什么是G1 G1…

Visual Studio C# WinForm开发入门(5):TabControl 控件使用

TabContrl选项卡控件可创建标签化窗口&#xff0c;在实际 编程中经常用到&#xff0c;该控件的作用是将相关的组件组合到一系列选项卡页面上。 比如下面的例子&#xff0c;在tabPage1页面和tabPage2页面各放了2个checkBox控件&#xff0c;通过点击不同page即可切换&#xff1a;…

WPF自定义TabControl样式

WPF自定义TabControl样式 原文: WPF自定义TabControl样式 WPF自定义TabControl&#xff0c;TabControl美化 XAML代码&#xff1a; <TabControl x:Class"SunCreate.Common.Controls.TabControlEx"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/present…

C# WinForm TabControl美化

窗口Load加下面代码&#xff0c;ItemSize根据自己显示文本长度调整 #region tabMainItem属性设置this.tabModuleMainItem.DrawMode TabDrawMode.OwnerDrawFixed;this.tabModuleMainItem.Alignment TabAlignment.Top;this.tabModuleMainItem.SizeMode TabSizeMode.Fixed;this…

浅谈C#tabcontrol应用

作为Winfrom开发者来说&#xff0c;我们很多时候会用到tabcontrol来实现和网页标签页相关的效果。同时微软自带的控件样式不符合我们的需求&#xff0c;我们该如何去实现更加美观且可以自定义的组合控件呢&#xff1f;带着这个问题进入我们今天的主题&#xff0c;组合控件tabco…

C# WPF TabControl控件用法详解

概述 TabControl我之前有讲过一节&#xff0c;内容详见&#xff1a; C# WPF TabControl用法指南(精品)&#xff0c;上节主要讲解了tabcontrol控件的左右翻页&#xff0c;以及页面筛选&#xff0c;以及数据绑定等内容&#xff0c;这节内容继续接续上节内容进行扩展讲解&#xff…

WPF 自定义控件TabControl

WPF 自定义控件TabControl 新TabControl效果&#xff1a; 新添加一个自定义控件ZTabControl&#xff1a; public class ZTabControl : TabControl{#region Private属性#endregion#region 依赖属性定义public static readonly DependencyProperty TypeProperty;#endregion#r…