swing树形图

来源:互联网 发布:java spring压缩 编辑:程序博客网 时间:2024/06/11 01:41



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 0
原创粉丝点击