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

2023-11-16

        以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));	//这条语句可有可无,在树完全生成后,再确定每个节点的selfX
		this.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);
	}
	
	//递归函数,设置树中每个节点的selfX
	void setX(DrawNode root){
		//设置子结点的beginX和endX
		int 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、控制台运行步骤:

                

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java绘制(可视化)树结构图 的相关文章

  • 是什么决定了从 lambda 创建哪个函数式接口?

    请考虑这个例子 import java util function Consumer public class Example public static void main String args Example example new
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • 如何使用 Java 处理 Selenium WebDriver 中的新窗口?

    这是我的代码 driver findElement By id ImageButton5 click Thread sleep 3000 String winHandleBefore driver getWindowHandle drive
  • Java AES 128 加密方式与 openssl 不同

    我们遇到了一种奇怪的情况 即我们在 Java 中使用的加密方法会向 openssl 生成不同的输出 尽管它们在配置上看起来相同 使用相同的键和 IV 文本 敏捷的棕色狐狸跳过了懒狗 加密为 Base64 字符串 openssl A8cMRI
  • java中如何连接字符串

    这是我的字符串连接代码 StringSecret java public class StringSecret public static void main String args String s new String abc s co
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • JavaFX 中具有自定义内容的 ListView

    How i can make custom ListView with JavaFx for my app I need HBox with image and 2 Labels for each line listView 您可以通过查看
  • 在 S3 中迭代对象时出现“ConnectionPoolTimeoutException”

    我已经使用 aws java API 一段时间了 没有遇到太多问题 目前我使用的是库 1 5 2 版本 当我使用以下代码迭代文件夹内的对象时 AmazonS3 s3 new AmazonS3Client new PropertiesCred
  • 普罗米修斯指标 - 未找到

    我有 Spring Boot 应用程序 并且正在使用 vertx 我想监控服务和 jvm 为此我选择了 Prometheus 这是我的监控配置类 Configuration public class MonitoringConfig Bea
  • 在游戏视图下添加 admob

    我一直试图将 admob 放在我的游戏视图下 这是我的代码 public class HoodStarGame extends AndroidApplication Override public void onCreate Bundle
  • 如何在 Java 中测试一个类是否正确实现了 Serialized(不仅仅是 Serialized 的实例)

    我正在实现一个可序列化的类 因此它是一个与 RMI 一起使用的值对象 但我需要测试一下 有没有办法轻松做到这一点 澄清 我正在实现该类 因此在类定义中添加 Serialized 很简单 我需要手动序列化 反序列化它以查看它是否有效 我找到了
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我
  • 欧洲中部时间 14 日 3 月 30 日星期五 00:00:00 至 日/月/年

    我尝试解析格式日期Fri Mar 30 00 00 00 CET 14至 日 月 年 这是我的代码 SimpleDateFormat formatter new SimpleDateFormat dd MM yyyy System out
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • 为什么这个作业不起作用?

    我有课Results which extends ArrayList
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • 调整添加的绘制组件的大小和奇怪的摆动行为

    这个问题困扰了我好几天 我正在制作一个特殊的绘画程序 我制作了一个 JPanel 并添加了使用 Paint 方法绘制的自定义 jComponent 问题是 每当我调整窗口大小时 所有添加的组件都会 消失 或者只是不绘制 因此我最终会得到一个
  • 在 RESTful Web 服务中实现注销

    我正在开发一个需要注销服务的移动应用程序 登录服务是通过数据库验证来完成的 现在我陷入了注销状态 退一步 您没有提供有关如何在应用程序中执行身份验证的详细信息 并且很难猜测您在做什么 但是 需要注意的是 在 REST 应用程序中 不能有会话

随机推荐

  • 如何终止一个无限循环线程和 程序退出时销毁线程

    http zhidao baidu com question 299079849 html android 启动了一个子线程 这个子线程是一个死循环 不成的打印 Hello 现在要实现点击一个Button 让这个子线程终止 用什么方法啊 s
  • 单相逆变器第四课、F28027最小系统绘画

    今天我们说的是F28027最小系统的绘画 其实我暂时还没有规划后面要用到什么引脚 所以我很任性的把所有GPIO引脚都接出去了 呵呵 先给大家上一个整体的图 看着图片是不是比较小 呵呵 没办法 截图最大的了 我晚点会把原理图和PCB上传到下载
  • VMware15中安装Linux详细教程

    VMware15中安装Linux详细教程 一 搭建VMware环境 1 打开链接 https www vmware com cn html 选择适合自己电脑系统的版本进行下载 2 下载完成后点击文件进行安装 安装界面如图 注 1 安装目录尽
  • 信息安全产品认证

    文章目录 一 引言 二 网络关键设备和网络安全专用产品安全认证证书 2 1 背景 2 2 产品目录 2 3 认证依据标准 2 4 认证机构 2 5 商密产品检测认证目录 与 网络关键设备和网络安全专用产品目录 的关系 三 中国国家信息安全产
  • 20个常见的Java错误以及规避方法

    原文 50 Common Java Errors and How to Avoid Them Part 1 作者 Angela Stringfellow 翻译 雁惊寒 译者注 本文介绍了20个常见的Java编译器错误 每种错误都包含了代码片
  • MKP勒索病毒:了解最新变种mkp,以及如何保护您的数据

    导言 在数字化时代 mkp 勒索病毒成为了网络安全领域的一大威胁 它采用高级加密技术 将您的数据文件锁定 要求支付赎金以解锁 本文将详细介绍 mkp 勒索病毒的工作原理 如何恢复被它加密的数据文件 以及如何采取预防措施来降低受攻击的风险 如
  • lambdaQuery用法

    lambdaQuery用法 LambdaQueryWrapper
  • pandas DataFrame行或列的删除方法

    pandas DataFrame的增删查改总结系列文章 pandas DaFrame的创建方法 pandas DataFrame的查询方法 pandas DataFrame行或列的删除方法 pandas DataFrame的修改方法 此文我
  • uniapp之微信小程序开发教程及如何合理使用WebSocket(实时监听)+workman聊天系统+linux系统配置阿里云端口

    添加链接描述 添加链接描述 thinphp6 1 workerman文档 添加链接描述 https www kancloud cn manual thinkphp6 0 1147857 workerman手册 https www worke
  • 软件的最低测试方法

    前言 1 1 引言 对于大部分软件系统 如何测试及有效的测试 是一个很头痛的问题 在软件工程上 测试是软件工程中极其重要的一部分 但在具体的实际情况上 无论是时间 人手及资源的调配等原因 使国内大部分软件公司没有进行过理论上的完整的测试 本
  • JAVA变量与数据类型

    人生不如意之事十有八九 在最好的年纪要努力充实自己 莫等空悲切白了少年头 而是要及时当勉励 岁月不待人 一 java变量 变量概述 1 内存中存储的一个存储区域 2 该存储区域内的数据在同一类型范围内不断变化 3 变量是程序中最基本的存储单
  • 老虎证券美股策略——将动量策略日频调仓改成月频

    最近策略频繁回撤 跑不赢标普500指数 所以对策略简单修改 以待后效 新加入的代码 def get if trade day infile open countday dat r incontent infile read infile c
  • Linux系统中负载较高问题排查思路与解决方法

    Load 就是对计算机干活多少的度量 Load Average 就是一段时间 1分钟 5分钟 15分钟 内平均Load linux服务器出现高负载的情况下 一般都有一些具体的症状 比如cpu 内存等被耗尽 磁盘IO或者网络等出现问题 下面通
  • CentOS7下安装LNMP以及phpMyAdmin

    两种安装 第一种 下载 可以到官网找 版本 https www phpmyadmin net downloads cd 到你要下载的位置 wget https files phpmyadmin net phpMyAdmin 4 4 12 p
  • Maven中pom文件内scope标签中import、parent 、dependencies、dependencyManagement详解

    首先介绍parent 如果父项目中有这些依赖
  • linux-sed命令

    目录 1 linux shell sed获取某一段字符串 2 linux shell shell脚本中 sed n取出某一行赋给一个变量 3 linux shell sed查询某一行 1 linux shell sed获取某一段字符串 如果
  • 网络层(四)

    网络层 我们说过 网络层主要讲的就是ip编址和路由选择算法 更准确的说 应该是网际IP协议 网际IP协议主要说明了各个主机和服务器的ip编址规则 了解IP编址前 我们需要知道IP数据报 IP数据报在网络层中传输 我们看一下IP数据报的结构
  • STM32F103ZET6【标准库函数开发】------PB3,PB4当做普通IO口,重定义

    一 如题 我在设计原理图的时候将PB3和PB4当做了普通IO口 结果按照一般配置的方法操作后 PB3 PB4并没有输出自己想要的信号 配置如下 void MOTOR GPIO Init void 初始化 GPIO InitTypeDef G
  • 人社练兵比武怎样挣积分 python 源码在线答题源码

    可以自动答题积分 不明白如何用的可以联系我 下面2个函数是学练习的 需要用的库为selenium time re pickle 题库需要收集 def dan 单选或多选 j browser find element by xpath id
  • java绘制(可视化)树结构图

    以JPanel组件为画板 继承JPanel类并重写paint Graphics g 函数 在函数中使用画笔g绘制树结构图 实例代码 3个java源文件 Main java DrawNode java DrawTree java 1 Main