swing树形图



package zhipu.fenxi.tree;

import zhipu.view.treechart.Node;

import javax.swing.*;
import java.awt.*;

/** 
 * @author John 
 * 
 */  
public class TestDrawTree extends JFrame{
    public TestDrawTree(){
        super("Test Draw Tree");
        initComponents();
        this.setTitle("添加商品");
        this.setSize(840, 660);
        this.setVisible(true);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    }
    public void initComponents(){

        int a=1;
        Node n = new Node("root");
        Node a1 = new Node("a1");
        Node a2 = new Node("a2");
        n.add(a1);
        n.add(a2);
          
        Node a3 = new Node("a3");
        Node b1 = new Node("b1");
        Node d1 = new Node("d1");
        Node d2 = new Node("d2");
        b1.add(d1);
        b1.add(d2);
        a3.add(b1);
          
        a3.add(new Node("b2"));
        a3.add(new Node("b3"));
        Node n3 = new Node("b4");
        a3.add(n3);
        n3.add(new Node("c1"));
        n3.add(new Node("c2"));
  
        n.add(a3);
        //n.printAllNode(n);    //输出树  
          
        /**
         * 创建一个用于绘制树的面板并将树传入,使用相对对齐方式
         */
        TreePanel panel1 = new TreePanel(TreePanel.CHILD_ALIGN_RELATIVE);
        panel1.setTree(n);

        JScrollPane  jScrollPane=new JScrollPane(panel1);
        add(jScrollPane,BorderLayout.CENTER);
        /**
         * 创建一个用于绘制树的面板并将树传入,使用绝对对齐方式
         */  
//        TreePanel panel2 = new TreePanel(TreePanel.CHILD_ALIGN_ABSOLUTE);
//        panel2.setTree(n);
//        panel2.setBackground(Color.BLACK);
//        panel2.setGridColor(Color.WHITE);
//        panel2.setLinkLineColor(Color.WHITE);
//        panel2.setStringColor(Color.BLACK);

    }
    public static void main(String[] args){
        TestDrawTree frame = new TestDrawTree();

        frame.setSize(800, 600);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}  


package zhipu.fenxi.tree;

import zhipu.view.treechart.Node;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

/** 
 * TODO 同一层结点过多有BUG,应该对每一层的所有结点都进行个数统计,之后才绘制。 
 * @author John 
 * 
 */  
public class TreePanel extends JPanel {  
  
    private Node tree;              //保存整棵树
    private int gridWidth = 20;     //每个结点的宽度
    private int gridHeight = 80;    //每个结点的高度
    private int vGap = 50;          //每2个结点的垂直距离  
    private int hGap = 30;          //每2个结点的水平距离
      
    private int startX = 10;        //根结点的Y,默认距离顶部10像素
    private int startY = 0;         //根结点的X,默认水平居中对齐
      
    private int childAlign;                     //孩子对齐方式  
    public static int CHILD_ALIGN_ABSOLUTE = 0; //相对Panel居中  
    public static int CHILD_ALIGN_RELATIVE = 1; //相对父结点居中  
      
    private Font font = new Font("微软雅黑",Font.BOLD,14);  //描述结点的字体  
      
    private Color gridColor = Color.YELLOW;      //结点背景颜色
    private Color linkLineColor = Color.BLACK;  //结点连线颜色  
    private Color stringColor = Color.BLACK;    //结点描述文字的颜色
      
    /** 
     * 默认构造 
     */  
    public TreePanel(){  
        this(null,CHILD_ALIGN_ABSOLUTE);  
    }  
      
    /** 
     * 根据传入的Node绘制树,以绝对居中的方式绘制 
     * @param n 要绘制的树 
     */  
    public TreePanel(Node n){  
        this(n,CHILD_ALIGN_ABSOLUTE);  
    }  
      
    /** 
     * 设置要绘制时候的对齐策略 
     * @param childAlign 对齐策略
     */  
    public TreePanel(int childAlign){  
        this(null,childAlign);  
    }  
      
    /** 
     * 根据孩子对齐策略childAlign绘制的树的根结点n 
     * @param n 要绘制的树的根结点 
     * @param childAlign 对齐策略 
     */  
    public TreePanel(Node n, int childAlign){  
        super();  
        setTree(n);
        this.setPreferredSize(new Dimension(800,1000));
        this.childAlign = childAlign;  
    }  
      
    /** 
     * 设置用于绘制的树 
     * @param n 用于绘制的树的 
     */  
    public void setTree(Node n) {  
        tree = n;  
    }  
      float flag=1;
    JButton j1;
    //重写而已,调用自己的绘制方法  
    public void paintComponent(Graphics g){
        startY = (getHeight()-gridHeight)/2;
        super.paintComponent(g);
        if(j1==null) {
            j1 = new JButton("放大"); //按钮和按钮监听
            j1.setBounds(30, 300, 80, 30);
            j1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub
                    flag *= 1.1;
                    gridWidth *= flag;     //每个结点的宽度
                    gridHeight *= flag;   //每个结点的高度
                    vGap *= flag;      //每2个结点的垂直距离
                    hGap *= flag;        //每2个结点的水平距离
                    repaint(); //重绘
                }
            });
            add(j1);
            JButton j2 = new JButton("缩小");
            j2.setBounds(150, 300, 80, 30);
            j2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub
                    flag *= 0.9;
                    gridWidth *= flag;     //每个结点的宽度
                    gridHeight *= flag;   //每个结点的高度
                    vGap *= flag;      //每2个结点的垂直距离
                    hGap *= flag;        //每2个结点的水平距离
                    repaint();
                }
            });
            add(j2);
        }
        g.setFont(font);

        drawAllNode(tree, startY, g);
    }

    //居中显示文本
    public void drawString(Graphics g, String str, int xPos, int yPos) {

        int strWidth = g.getFontMetrics().stringWidth(str);
        g.drawString(str, xPos + strWidth / 2, yPos);
    }

    /** 
     * 递归绘制整棵树 
     * @param n 被绘制的Node 
     * @param y 根节点的绘制X位置
     * @param g 绘图上下文环境 
     */  
    public void drawAllNode(Node n, int y, Graphics g){
        int x = n.getLayer()*(hGap+gridWidth)+ startX;
        int fontX = x + gridWidth/2 - 5;     //5为测试得出的值,你可以通过FM计算更精确的,但会影响速度
          int aa=2;
        g.setColor(gridColor);  
        g.fillRect( x,y, gridWidth, gridHeight);    //画结点的格子
          
        g.setColor(stringColor);

        g.drawString(n.toString(),fontX, y+gridHeight/2 );       //画结点的名字
          
        if(n.hasChild()){
             aa=2;
            List<Node> c = n.getChilds();  
            int size = n.getChilds().size();
            int tempPosy = childAlign == CHILD_ALIGN_RELATIVE
                         ? y+gridHeight/2 - (size*(gridHeight+vGap)-vGap)/2
                         : (getHeight() - size*(gridHeight+vGap)+vGap)/2;
            int i = 0;  
            for(Node node : c){
                aa=2;
                int newY = tempPosy+(gridHeight+vGap)*i; //孩子结点起始X
                g.setColor(linkLineColor);
                g.drawLine(x+gridWidth, y+gridHeight/2, x+gridWidth+hGap/2,y+gridHeight/2);   //画连接结点的线
                g.drawLine(x+gridWidth+hGap/2,y+gridHeight/2,  x+gridWidth+hGap/2,newY+gridHeight/2 );   //画连接结点的线
                g.drawLine(x+gridWidth+hGap/2,newY+gridHeight/2, x+gridWidth+hGap, newY+gridHeight/2 );   //画连接结点的线
//                g.drawLine(x+gridWidth/2, y+gridHeight, newX+gridWidth/2, y+gridHeight+vGap);   //画连接结点的线
                drawAllNode(node, newY, g);
                i++;
            }
        }  
    }
    public Color getGridColor() {  
        return gridColor;  
    }  
  
    /** 
     * 设置结点背景颜色 
     * @param gridColor 结点背景颜色 
     */  
    public void setGridColor(Color gridColor) {  
        this.gridColor = gridColor;  
    }  
  
    public Color getLinkLineColor() {  
        return linkLineColor;  
    }  
  
    /** 
     * 设置结点连接线的颜色 
     * @param gridLinkLine 结点连接线的颜色 
     */  
    public void setLinkLineColor(Color gridLinkLine) {  
        this.linkLineColor = gridLinkLine;  
    }  
  
    public Color getStringColor() {  
        return stringColor;  
    }  
  
    /** 
     * 设置结点描述的颜色 
     * @param stringColor 结点描述的颜色 
     */  
    public void setStringColor(Color stringColor) {  
        this.stringColor = stringColor;  
    }  
      
    public int getStartX() {
        return startX;
    }  
  
    /** 
     * 设置根结点的Y位置 
     * @param startX 根结点的Y位置
     */  
    public void setStartX(int startX) {
        this.startX = startX;
    }  
  
    public int getStartY() {
        return startY;
    }  
  
    /** 
     * 设置根结点的X位置 
     * @param startY 根结点的X位置
     */  
    public void setStartY(int startY) {
        this.startY = startY;
    }  
  
      
}  


package zhipu.view.treechart;
  
import java.util.ArrayList;  
import java.util.List;  
  
/** 
 * 树的结构 
 * @author John 
 * 
 */  
public class Node {  
    private String name;    //该结点名字  
    private int layer = 0;  //该结点层级  
  
    private List<Node> childs = null; //保存该结点的孩子  
  
    public Node(String name){  
        this.name = name;  
    }  
      
    /** 
     * 增加一个孩子 
     * @param n 要作为孩子增加的结点 
     */  
    public void add(Node n){  
        if(childs == null)  
            childs = new ArrayList<Node>();  
        n.setLayer(layer+1);  
        setChildLayout(n);  
        childs.add(n);  
    }  
      
    /** 
     * 递归设置孩子的层级 
     * @param n 
     */  
    private void setChildLayout(Node n){  
        if(n.hasChild()){  
            List<Node> c = n.getChilds();  
            for(Node node : c){  
                node.setLayer(node.getLayer()+1);  
                setChildLayout(node);  
            }  
        }  
    }  
  
    /** 
     * 获取结点名 
     * @return 结点名 
     */  
    public String getName() {  
        return name;  
    }  
  
    /** 
     * 设置结点名 
     * @param name 结点名 
     */  
    public void setName(String name) {  
        this.name = name;  
    }     
  
    /** 
     * 获取该结点的层级 
     * @return 该结点的层级 
     */  
    public int getLayer() {  
        return layer;  
    }  
  
    /** 
     * 设置该结点的层级 
     * @param layer 该结点的层级 
     */  
    public void setLayer(int layer) {  
        this.layer = layer;  
    }  
      
    /** 
     * 获取该结点的孩子 
     * @return 所有孩子结点 
     */  
    public List<Node> getChilds() {  
        return childs;  
    }  
  
    /** 
     * 检查是否存在孩子 
     * @return 是则返回true,否则返回false 
     */  
    public boolean hasChild(){  
        return childs == null ? false : true;  
    }  
      
    /** 
     * 递归打印所有的结点(包括子结点) 
     * @param n 要打印的根结点 
     */  
    public void printAllNode(Node n){  
        System.out.println(n);  
        if(n.hasChild()){  
            List<Node> c = n.getChilds();  
            for(Node node : c){  
                printAllNode(node);  
            }  
        }  
    }  
      
    public String getAllNodeName(Node n){  
        String s = n.toString()+"/n";  
        if(n.hasChild()){  
            List<Node> c = n.getChilds();  
            for(Node node : c){  
                s+=getAllNodeName(node)+"/n";  
            }  
        }  
        return s;  
    }  
      
    public String toString(){  
        return layer+"层/t: "+name;  
    }  

    public static void main(String[] args){  
        Node n = new Node("root");  
          
        n.add(new Node("a1"));  
        n.add(new Node("a2"));  
          
        Node n2 = new Node("a3");  
        n2.add(new Node("b1"));  
        n2.add(new Node("b2"));  
        n2.add(new Node("b3"));  
        Node n3 = new Node("b4");  
        n2.add(n3);  
        n3.add(new Node("c1"));  
        n3.add(new Node("c2"));  
  
        n.add(n2);  
        n.printAllNode(n);  //输出树  
    }  
  
}  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目录 目录 1 (一) Spring 开发 Swing GUI 简介——依赖注入和富客户机 5 关于本教程 5 前提条件 6 Spring 和依赖注入概述 7 什么是 Spring 框架? 7 什么是依赖注入? 7 环境设置 7 选择编译环境 7 设置 Ant 8 通过 Ant 自动下载依赖软件 10 设置 Maven 10 通过 Maven 自动下载依赖软件 12 设置 Eclipse 13 下载依赖的 JAR 文件并在 Eclipse 的 classpath 中定义这种依赖性 15 创建 to-do 列表:基本的 Swing 和 Spring 应用程序设置 17 创建 MainFrame、Launcher 和 ToDo 类 17 创建 Spring app-context.xml bean 定义文件 19 运行应用程序 20 定义 bean 属性 21 创建 to-do 列表:创建一个可重用组件并在表中显示数据 23 创建一个可重用的面板 23 将 bean 组合在一起 24 添加一个表并重用这个面板 26 定义表模型 28 显示列表中的项 29 创建 to-do 列表:完成 —— 按钮和监听程序 31 创建按钮和监听程序 32 组合按钮和监听程序 35 Spring Rich Client Project 37 Spring Rich Client Project 概述 37 结束语 38 (二) 适用于各类Swing应用的通用数据验证模块 39 项目创建好后,加入类库: 41 然后写一个persistence bean: 41 Java代码 41 我称这个类为HibernateValidationUI,代码如下: 43 Java代码 43 类中用到的Java2DIconFactory代码如下: 47 Java代码 47 Factory类 49 Java代码 49 最后,我们可以编写一个Demo application来看看效果如何,代码如下: 51 Java代码 51 总结: 55 (三) 对JTree从创建到使用详解 56 (四) JTree的使用方法 57 JTreeDemo.java源程序 57 经验汇总 60 1. 初始化 60 2. 三个经常使用的取值函数 60 3. 根据node得到path: 60 4. 根据Path展开到该节点 60 5. 根据path设定该节点选定 61 6. 选中节点的方法 61 7. 滚动到可见位置 61 8. 给JTree添加右键弹出菜单 61 9. 关于JTree的展开 61 10. 如何遍历JTree 62 (五) JTree右键菜单实现编辑、添加、删除节点 63 Test.java源代码 63 (六) 功能齐全的JTree例子 66 TreeEditTest.java源代码 66 (七) JTree控件的使用 70 构造函数: 70 TreeModel接口 70 DefaultTreeModel缺省版本 71 TreeNode接口 71 TreeExpansionListener接口 71 TreeCellRenderer 72 例子: 73 (八) 如何为JTree添加右键菜单? 75 (九) 如何使JTextArea随着窗体的变化自动调整大小 76 TextAreaTest源代码 76 (十) JAVA swing编程JTree实现系统目录 77 FileTree1.java源代码 77 (十一) Java Swing中的JTree模型 85 Swing.tree包中的主要类名称实现 85 1. 构建树模型 86 2. 树结点 86 树结构详细类 86 2.1 TreeNode接口 86 2.2 MutableTreeNode接口 87 2.3 DefaultMutableTreeNode类 88 3. 编辑树 88 3.1获得结点路径 88 3.2编辑结点 88 3.3视显示 89 4. 查找树 89 5. 绘制结点 90 (十二) JTree鼠标左键的双击事件选用那个监听器 91 MouseDemo.java源代码 92 (十三) JTree 92 JTree的构造函数: 93 JTreeDefaultDemo.java源代码 93 (十四) JTree 应用 96 Frame1.java源代码 96 MyDefaultTreeCellRenderer.java源代码 98 (十五) JTree控件 100 树和节点的基本概念 100 有关树JTree的类和接口 100 代码实例:构建一棵树 101 相关语句解释 101 (十六) JTree应用示例——文件路径 103 AnimatedIconTreeExample.java源代码 103 //内部类NodeImageObserver.java源代码 105 //IconNodeRenderer.java源代码 106 //IconNode.java源代码 107 (十七) Swing 学习笔记 108 Swing API 包括18个公共包: 108 例程1.1 HelloWorldSwing.java 109 例程2.2 HelloWorldJFrame.java 110 (十八) 动态加载文件树的java程序 111 FileSystemTree.java源代码 112 //内部类 TreeWillExpandListenerImp.java 114 (十九) 向 Java 应用程序伸出援助之手——用 JavaHelp 2.0 构建下一个 Java 应用程序的帮助系统 115 入门 116 使用 HelpSet 117 HelpSet 数据文件 118 helpset 文件 118 maps 部分 119 view 部分 119 presentation 部分 120 implementation 部分 121 map 文件 121 导航文件 121 TOC 122 Index 122 Glossary 123 Favorites 123 主题文件 123 在 Java 应用程序中调用 JavaHelp 124 自定义外观 125 配置标 125 基于文字的标签还是基于像的标签? 125 要工具栏还是不要工具栏? 125 设置字体 126 使用展示窗口 127 <object> 标签 128 四种 activator 129 添加内容敏感的帮助 130 窗口级帮助 131 字段级帮助 131 屏幕级帮助 133 添加嵌入帮助 135 添加搜索功能 136 停用词 137 自定义停用词列表 137 合并 helpset 138 静态和动态合并 139 添加轻量级组件 141 基于服务器的帮助 144 设置 144 JavaHelp 服务器 bean 144 JavaScript 文件 145 JSP 文件 145 测试服务器端帮助 148 结束语 149

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值