Draw lines in binary tree graphical representation

Asked

Viewed 1,159 times

1

I’m trying to draw a binary tree using swing and awt in java. I can already show the knots of the tree but I’m not able to draw the lines of a parent knot to your children. I have the Node, Treegui, Drawtree and Main classes. This image is how the output is without the lines.

Árvore binária

My intention is to show lines from a parent node to your child nodes. I tried to use the method drawLine class Graphics but it stayed that way:

Arvore

The drawTree method defines the position of the values of the nodes on the screen and stores the position of the nodes in Arraylists. The drawLine method draws the lines. I believe the lines are that way because the values are stored in that particular order. I have tried several ways and I cannot connect the lines correctly. How can I show the lines only from a parent to their children?

public class TreeGUI extends JFrame {

    private JPanel contentPane;
    public Node node;
    public DrawTree drawer;

    /**
     * Create the frame.
     */
    public TreeGUI(Node node) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 500, 500);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        drawer = new DrawTree(node);
        contentPane.add(drawer);
        setContentPane(contentPane);
        this.node = node;
        setVisible(true);
    }

}

class DrawTree extends JPanel{

    public Node node;
    public static ArrayList listX = new ArrayList();
    public static ArrayList listY = new ArrayList();


    public DrawTree(Node node){
        this.node = node;
    }

    @Override
    protected void paintComponent(Graphics g) {
        // TODO Auto-generated method stub
        g.setFont(new Font("Tahoma", Font.BOLD, 20));
        DrawTree(g, 0, getWidth(), 0, getHeight() / node.getheight(node), node);
        listX.clear();
        listY.clear();
    }

    public void DrawTree(Graphics g, int StartWidth, int EndWidth, int StartHeight, int Level, Node node) {
        String data = String.valueOf(node.getValue());
        g.setFont(new Font("Tahoma", Font.BOLD, 20));
        FontMetrics fm = g.getFontMetrics();
        int dataWidth = fm.stringWidth(data);

        g.drawString(data, (StartWidth + EndWidth) / 2 - dataWidth / 2, StartHeight + Level / 2);
        listX.add((StartWidth + EndWidth) / 2 - dataWidth / 2);
        listY.add(StartHeight + Level / 2);
        drawLine(g, node);

        if (node.getLeft() != null) {
            DrawTree(g, StartWidth, (StartWidth + EndWidth) / 2, StartHeight + Level, Level, node.getLeft());
        }
        if (node.getRight() != null)
            DrawTree(g, (StartWidth + EndWidth) / 2, EndWidth, StartHeight + Level, Level, node.getRight());
    }

public void drawLine(Graphics g,  Node node){
       for (int i=1; i < listY.size(); i++)
            g.drawLine((int)listX.get(i-1), (int)listY.get(i-1), (int)listX.get(i), (int)listY.get(i));
    }

}

main method

public static void main(String[] args) {
    Node raiz = null;
    raiz = raiz.insert(raiz, 35);
    raiz.insert(raiz, 25);
    raiz.insert(raiz, 75);
    raiz.insert(raiz, 30);
    raiz.insert(raiz, 20);
    raiz.insert(raiz, 12);
    raiz.insert(raiz, 6);
    raiz.insert(raiz, 23);
    raiz.insert(raiz, 90);
    TreeGUI gui = new TreeGUI(raiz);
}
  • how do you want the final drawing to look like? The children of this Node are just getLeft() and Getright()?

1 answer

1


Try with these modifications that I made, it will probably work, I tested with a Tree class that had already implemented and worked, I hope to have helped.

public void DrawTree(Graphics g, int StartWidth, int EndWidth, int StartHeight, int Level, Node node) {
    String data = String.valueOf(node.getValue());
    g.setFont(new Font("Tahoma", Font.BOLD, 20));
    FontMetrics fm = g.getFontMetrics();
    int dataWidth = fm.stringWidth(data);

    g.drawString(data, (StartWidth + EndWidth) / 2 - dataWidth / 2, StartHeight + Level / 2);
    listX.add((StartWidth + EndWidth) / 2 - dataWidth / 2);
    listY.add(StartHeight + Level / 2);
    drawLine(g, node);

    //Imprime as linhas que ligam os nós a seus filhos
    if(listX.size() > 1){
        g.drawLine((int)listX.get(listX.size()-2), (int)listY.get(listY.size()-2), (int)listX.get(listX.size()-1), (int)listY.get(listY.size()-1));
    }

    if (node.getLeft() != null) {
        DrawTree(g, StartWidth, (StartWidth + EndWidth) / 2, StartHeight + Level, Level, node.getLeft());
    }

    if (node.getRight() != null){

         /*Como a recursão visita os nós da esquerda primeiro, se o nó que está sendo tratado for o filho à direira e
            houver filho(s) à esquerda, quer dizer que os filhos à esquerda já foram visitados e suas linhas já foram 
            desenhadas, ou seja, seus pontos devem ser removidos, para evitar que sejam desenhados outra vez. 
         */
        if (listX.size() > 1 && node.getLeft() != null) {
            for(int i = 0; i < node.getLeft().getHeight(); i++){
                listX.remove(listX.size()-1);
                listY.remove(listY.size()-1);
            }
        }
        DrawTree(g, (StartWidth + EndWidth) / 2, EndWidth, StartHeight + Level, Level, node.getRight());
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.