先看效果图:

定义树的数据结构

[java] view plain copy
  1. /**
  2. * 2010-11-8
  3. * John
  4. */
  5. package tree;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /**
  9. * 树的结构
  10. * @author John
  11. *
  12. */
  13. public class Node {
  14. private String name;    //该结点名字
  15. private int layer = 0;  //该结点层级
  16. private List<Node> childs = null; //保存该结点的孩子
  17. public Node(String name){
  18. this.name = name;
  19. }
  20. /**
  21. * 增加一个孩子
  22. * @param n 要作为孩子增加的结点
  23. */
  24. public void add(Node n){
  25. if(childs == null)
  26. childs = new ArrayList<Node>();
  27. n.setLayer(layer+1);
  28. setChildLayout(n);
  29. childs.add(n);
  30. }
  31. /**
  32. * 递归设置孩子的层级
  33. * @param n
  34. */
  35. private void setChildLayout(Node n){
  36. if(n.hasChild()){
  37. List<Node> c = n.getChilds();
  38. for(Node node : c){
  39. node.setLayer(node.getLayer()+1);
  40. setChildLayout(node);
  41. }
  42. }
  43. }
  44. /**
  45. * 获取结点名
  46. * @return 结点名
  47. */
  48. public String getName() {
  49. return name;
  50. }
  51. /**
  52. * 设置结点名
  53. * @param name 结点名
  54. */
  55. public void setName(String name) {
  56. this.name = name;
  57. }
  58. /**
  59. * 获取该结点的层级
  60. * @return 该结点的层级
  61. */
  62. public int getLayer() {
  63. return layer;
  64. }
  65. /**
  66. * 设置该结点的层级
  67. * @param layer 该结点的层级
  68. */
  69. public void setLayer(int layer) {
  70. this.layer = layer;
  71. }
  72. /**
  73. * 获取该结点的孩子
  74. * @return 所有孩子结点
  75. */
  76. public List<Node> getChilds() {
  77. return childs;
  78. }
  79. /**
  80. * 检查是否存在孩子
  81. * @return 是则返回true,否则返回false
  82. */
  83. public boolean hasChild(){
  84. return childs == null ? false : true;
  85. }
  86. /**
  87. * 递归打印所有的结点(包括子结点)
  88. * @param n 要打印的根结点
  89. */
  90. public void printAllNode(Node n){
  91. System.out.println(n);
  92. if(n.hasChild()){
  93. List<Node> c = n.getChilds();
  94. for(Node node : c){
  95. printAllNode(node);
  96. }
  97. }
  98. }
  99. public String getAllNodeName(Node n){
  100. String s = n.toString()+"/n";
  101. if(n.hasChild()){
  102. List<Node> c = n.getChilds();
  103. for(Node node : c){
  104. s+=getAllNodeName(node)+"/n";
  105. }
  106. }
  107. return s;
  108. }
  109. public String toString(){
  110. return layer+"层/t: "+name;
  111. }
  112. }

Node的测试类:

[java] view plain copy
  1. /**
  2. * 2010-11-9
  3. * John
  4. */
  5. package tree.demo;
  6. import tree.Node;
  7. /**
  8. * @author John
  9. *
  10. */
  11. public class TestPrintNode {
  12. public static void main(String[] args){
  13. Node n = new Node("root");
  14. n.add(new Node("a1"));
  15. n.add(new Node("a2"));
  16. Node n2 = new Node("a3");
  17. n2.add(new Node("b1"));
  18. n2.add(new Node("b2"));
  19. n2.add(new Node("b3"));
  20. Node n3 = new Node("b4");
  21. n2.add(n3);
  22. n3.add(new Node("c1"));
  23. n3.add(new Node("c2"));
  24. n.add(n2);
  25. n.printAllNode(n);  //输出树
  26. }
  27. }

画树的Panel

[java] view plain copy
  1. /**
  2. * 2010-11-9
  3. * John
  4. */
  5. package tree;
  6. import java.awt.Color;
  7. import java.awt.Font;
  8. import java.awt.FontMetrics;
  9. import java.awt.Graphics;
  10. import java.util.List;
  11. import javax.swing.JPanel;
  12. /**
  13. * TODO 同一层结点过多有BUG,应该对每一层的所有结点都进行个数统计,之后才绘制。
  14. * @author John
  15. *
  16. */
  17. public class TreePanel extends JPanel {
  18. private Node tree;              //保存整棵树
  19. private int gridWidth = 80;     //每个结点的宽度
  20. private int gridHeight = 20;    //每个结点的高度
  21. private int vGap = 50;          //每2个结点的垂直距离
  22. private int hGap = 30;          //每2个结点的水平距离
  23. private int startY = 10;        //根结点的Y,默认距离顶部10像素
  24. private int startX = 0;         //根结点的X,默认水平居中对齐
  25. private int childAlign;                     //孩子对齐方式
  26. public static int CHILD_ALIGN_ABSOLUTE = 0; //相对Panel居中
  27. public static int CHILD_ALIGN_RELATIVE = 1; //相对父结点居中
  28. private Font font = new Font("微软雅黑",Font.BOLD,14);  //描述结点的字体
  29. private Color gridColor = Color.BLACK;      //结点背景颜色
  30. private Color linkLineColor = Color.BLACK;  //结点连线颜色
  31. private Color stringColor = Color.WHITE;    //结点描述文字的颜色
  32. /**
  33. * 默认构造
  34. */
  35. public TreePanel(){
  36. this(null,CHILD_ALIGN_ABSOLUTE);
  37. }
  38. /**
  39. * 根据传入的Node绘制树,以绝对居中的方式绘制
  40. * @param n 要绘制的树
  41. */
  42. public TreePanel(Node n){
  43. this(n,CHILD_ALIGN_ABSOLUTE);
  44. }
  45. /**
  46. * 设置要绘制时候的对齐策略
  47. * @param childAlign 对齐策略
  48. * @see tree.TreePanel#CHILD_ALIGN_RELATIVE
  49. * @see tree.TreePanel#CHILD_ALIGN_ABSOLUTE
  50. */
  51. public TreePanel(int childAlign){
  52. this(null,childAlign);
  53. }
  54. /**
  55. * 根据孩子对齐策略childAlign绘制的树的根结点n
  56. * @param n 要绘制的树的根结点
  57. * @param childAlign 对齐策略
  58. */
  59. public TreePanel(Node n, int childAlign){
  60. super();
  61. setTree(n);
  62. this.childAlign = childAlign;
  63. }
  64. /**
  65. * 设置用于绘制的树
  66. * @param n 用于绘制的树的
  67. */
  68. public void setTree(Node n) {
  69. tree = n;
  70. }
  71. //重写而已,调用自己的绘制方法
  72. public void paintComponent(Graphics g){
  73. startX = (getWidth()-gridWidth)/2;
  74. super.paintComponent(g);
  75. g.setFont(font);
  76. drawAllNode(tree, startX, g);
  77. }
  78. /**
  79. * 递归绘制整棵树
  80. * @param n 被绘制的Node
  81. * @param xPos 根节点的绘制X位置
  82. * @param g 绘图上下文环境
  83. */
  84. public void drawAllNode(Node n, int x, Graphics g){
  85. int y = n.getLayer()*(vGap+gridHeight)+startY;
  86. int fontY = y + gridHeight - 5;     //5为测试得出的值,你可以通过FM计算更精确的,但会影响速度
  87. g.setColor(gridColor);
  88. g.fillRect(x, y, gridWidth, gridHeight);    //画结点的格子
  89. g.setColor(stringColor);
  90. g.drawString(n.toString(), x, fontY);       //画结点的名字
  91. if(n.hasChild()){
  92. List<Node> c = n.getChilds();
  93. int size = n.getChilds().size();
  94. int tempPosx = childAlign == CHILD_ALIGN_RELATIVE
  95. ? x+gridWidth/2 - (size*(gridWidth+hGap)-hGap)/2
  96. : (getWidth() - size*(gridWidth+hGap)+hGap)/2;
  97. int i = 0;
  98. for(Node node : c){
  99. int newX = tempPosx+(gridWidth+hGap)*i; //孩子结点起始X
  100. g.setColor(linkLineColor);
  101. g.drawLine(x+gridWidth/2, y+gridHeight, newX+gridWidth/2, y+gridHeight+vGap);   //画连接结点的线
  102. drawAllNode(node, newX, g);
  103. i++;
  104. }
  105. }
  106. }
  107. public Color getGridColor() {
  108. return gridColor;
  109. }
  110. /**
  111. * 设置结点背景颜色
  112. * @param gridColor 结点背景颜色
  113. */
  114. public void setGridColor(Color gridColor) {
  115. this.gridColor = gridColor;
  116. }
  117. public Color getLinkLineColor() {
  118. return linkLineColor;
  119. }
  120. /**
  121. * 设置结点连接线的颜色
  122. * @param gridLinkLine 结点连接线的颜色
  123. */
  124. public void setLinkLineColor(Color gridLinkLine) {
  125. this.linkLineColor = gridLinkLine;
  126. }
  127. public Color getStringColor() {
  128. return stringColor;
  129. }
  130. /**
  131. * 设置结点描述的颜色
  132. * @param stringColor 结点描述的颜色
  133. */
  134. public void setStringColor(Color stringColor) {
  135. this.stringColor = stringColor;
  136. }
  137. public int getStartY() {
  138. return startY;
  139. }
  140. /**
  141. * 设置根结点的Y位置
  142. * @param startY 根结点的Y位置
  143. */
  144. public void setStartY(int startY) {
  145. this.startY = startY;
  146. }
  147. public int getStartX() {
  148. return startX;
  149. }
  150. /**
  151. * 设置根结点的X位置
  152. * @param startX 根结点的X位置
  153. */
  154. public void setStartX(int startX) {
  155. this.startX = startX;
  156. }
  157. }

测试TreePanel

[java] view plain copy
  1. /**
  2. * 2010-11-9
  3. * John
  4. */
  5. package tree.demo;
  6. import java.awt.BorderLayout;
  7. import java.awt.Color;
  8. import java.awt.GridLayout;
  9. import java.awt.Panel;
  10. import javax.swing.JFrame;
  11. import javax.swing.JPanel;
  12. import javax.swing.JScrollPane;
  13. import javax.swing.JTextArea;
  14. import tree.Node;
  15. import tree.TreePanel;
  16. /**
  17. * @author John
  18. *
  19. */
  20. public class TestDrawTree extends JFrame{
  21. public TestDrawTree(){
  22. super("Test Draw Tree");
  23. initComponents();
  24. }
  25. public static void main(String[] args){
  26. TestDrawTree frame = new TestDrawTree();
  27. frame.setSize(800, 600);
  28. frame.setVisible(true);
  29. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  30. }
  31. public void initComponents(){
  32. /*
  33. * 初始化树的数据
  34. */
  35. Node n = new Node("root");
  36. Node a1 = new Node("a1");
  37. Node a2 = new Node("a2");
  38. n.add(a1);
  39. n.add(a2);
  40. Node a3 = new Node("a3");
  41. Node b1 = new Node("b1");
  42. Node d1 = new Node("d1");
  43. Node d2 = new Node("d2");
  44. b1.add(d1);
  45. b1.add(d2);
  46. a3.add(b1);
  47. a3.add(new Node("b2"));
  48. a3.add(new Node("b3"));
  49. Node n3 = new Node("b4");
  50. a3.add(n3);
  51. n3.add(new Node("c1"));
  52. n3.add(new Node("c2"));
  53. n.add(a3);
  54. //n.printAllNode(n);    //输出树
  55. /*
  56. * 创建一个用于绘制树的面板并将树传入,使用相对对齐方式
  57. */
  58. TreePanel panel1 = new TreePanel(TreePanel.CHILD_ALIGN_RELATIVE);
  59. panel1.setTree(n);
  60. /*
  61. * 创建一个用于绘制树的面板并将树传入,使用绝对对齐方式
  62. */
  63. TreePanel panel2 = new TreePanel(TreePanel.CHILD_ALIGN_ABSOLUTE);
  64. panel2.setTree(n);
  65. panel2.setBackground(Color.BLACK);
  66. panel2.setGridColor(Color.WHITE);
  67. panel2.setLinkLineColor(Color.WHITE);
  68. panel2.setStringColor(Color.BLACK);
  69. JPanel contentPane = new JPanel();
  70. contentPane.setLayout(new GridLayout(2,1));
  71. contentPane.add(panel1);
  72. contentPane.add(panel2);
  73. add(contentPane,BorderLayout.CENTER);
  74. }
  75. }

用Java2D画出树的结构图相关推荐

  1. 画出微型计算机结构图,中级工792、画出计算机环形网络模式图.doc

    中级工792.画出计算机环形网络模式图 中级工792.画出计算机环形网络模式图. 画出计算机总线网络模式图. 画出计算机星形网络模式图. 画出单工通信方式图. 画出半双工通信方式图. 画出全双工通信方 ...

  2. netron画yolov4网络结构图

    该结构图由netron工具打开制作而成,浏览器中输入链接:https://lutzroeder.github.io/netron/ 即可进入netron在线工具,打开yolov4.cfg即可画出网络结 ...

  3. R语言画基因突变结构图

    R语言画基因突变结构图 做遗传病的同志们经常头痛的一个事应该是怎么画突变示意图,以前都是PPT直接画,但是最近碰到一个问题,综述里涉及到数个基因的数百个突变位点,PPT画的画得累死,于是开始搜索怎么用 ...

  4. 【企业资源计划ERP】,描述该供应商背景;阐述其ERP产品的各项功能,并画出功能结构图;阐述其产品特点及适用行业(至少3个),并针对每个行业至少举出一个具体的案例。

    <企业资源规划(ERP)>课程实验第 1 次实验报告 实验内容及基本要求: 实验项目名称:ERP软件操作 实验类型: 验证 每组人数: 1 实验内容及要求: 结合教材课后上机练习题(P25 ...

  5. Xgboost如何画出树?

    对Xgboost使用了一定程度的读者,肯定会面临如何画出树这个问题,毕竟不画出树就是一个黑箱,黑箱总是难以让人放心.本篇博客完整地给出了如何画出Xgboost中的树的过程. 一.训练一个简单的Xgb模 ...

  6. 使用pydot 画CNN网络结构图

    使用pydot画CNN结构图的难点在于安装pydot 要严格按照安装顺序进行安装,百度搜索就可以找到,成功安装pydot后仅需要两行代码就可以画出网络结构 前提是要搭建好网络结构 import pyd ...

  7. 画出微型计算机结构图,微型计算机试卷(1997年)

    一.填空题(每空0.5分,共20分) 1.Inter 8086.80386.Pentium分别是_________位的微处理器. 2.最大模式下的8086CPU通过输出三位总线周期状态信号______ ...

  8. 产品认知:揭秘你不会画产品信息结构图的本质

    前言: 有没有觉得设计产品信息结构图很难,根本无从下手,不知所措?根本原因在哪? 本质原因在于你脑海中根本就没有面向对象的概念和对数据库表结构的理解. 别慌,博主这带你探寻从产品信息拆解为对象并将之追 ...

  9. cad详图怎么画_CAD原始结构图如何绘制?

    原标题:CAD原始结构图如何绘制? CAD原始结构图绘制 原始结构图是设计师对房屋结构进行实地测量之后,根据测量数据放样出的平面图纸,其中包括房屋整体结构.空间结构.门口.窗户的位置尺寸等.原始结构图 ...

最新文章

  1. linux程序设计——运行SQL语句(第八章)
  2. office文档、图片、音/视频格式转换工具
  3. Python 海龟画图(turtle)常用的颜色单词
  4. 在Excel中如何引用其他的工作表或者工作簿
  5. Oracle之SQL分析函数
  6. Citrix无法访问本地磁盘
  7. 一些常用正则表达式片段的分析
  8. WORD如何定义新项目符号?
  9. 【英语学习】【Daily English】U07 Restaurant L04 It's on me today.
  10. python中name没有定义_Python NameError:全局名称’NAME’未定义! (但它被定义)
  11. STM32F103C8T6 硬件SPI+DMA 控制WS2811
  12. 实现Modbus Rtu 服务端 通过RS485转4G方式 实现远程采集传输串口设备数据
  13. 让你浏览器飞起来的电脑插件合集
  14. 构造图片对网络进行对抗攻击n+m=7
  15. 到底是什么原因?让200多家企业参与区块链改革?
  16. 大数据开发 电脑内存大小
  17. Linux free 查看内存使用情况 常用命令
  18. 高并发 WEB 服务器 nginx 源码通读中文分析注释,带详细函数注释及函数调用注释,附 github 地址,后期持续维护更新...
  19. Android开发 assets目录
  20. 6-4 学生成绩链表处理(20 分)

热门文章

  1. 中学计算机老师 当领导可能性,求分享,当中学计算机老师带信息学奥赛是怎样的感受 - 信息科学技术学院(EECS)版 - 北大未名BBS...
  2. 昵图网学校计算机教室制度,ClassIn在线教室
  3. python文件读取方法read(size)的含义是_Python基于read(size)方法读取超大文件
  4. java nio doug_Java NIO简介
  5. 阻抗匹配工具_工具 | 9R Fret Polishing Wheels 品丝抛光轮
  6. 热议:这样的开源项目,你会支持吗?
  7. 不讲武德,拿到户口后立马辞职...
  8. 如何写好注释,让同事赞不绝口?
  9. 皮一皮:真是个看脸的年代...
  10. 升级 | Fastjson 1.2.68 发布,支持 GEOJSON