Árvore Binária Gráfica

Galera, sou estudante de Computação e me deparei com um trabalho que está me tirando o sono. Meu professor de Estrutura de Dados está nos ensinando Árvores Binárias e pediu que nós criássemos um programa que exiba a construção passo a passo da árvore de forma gráfica. Eu escolhi como linguagem o Java por sua portabilidade e por já ter estudado também. Só que nunca havia estudado a biblioteca gráfica AWT. Então, estou meio perdido. Depois de muita pesquisa, consegui criar a janela, que é super simples quando se tem uma IDE. Sei que muita gente prefere o Eclipse, e tem seus motivos, mas estou usando o NetBeans por me familiarizar mais com ele. Nada contra o Eclipse! Já criei a classe No, que representa cada nó da árvore, e a classe principal. Também comecei a criar a classe Arvore. O problema está em como vou fazer para que os nós sejam exibidos na árvore. Todo esse trabalho foi feito com muita pesquisa. E já pesquisei bastante para resolver esse problema, mas não consegui encontrar nada. Preciso de ajuda! Como meu código está muito grande, criei uma versão menor para apresentar a vocês que foca mais no que eu pretendo. Abaixo seguem os códigos.

Classe Principal:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package teste;

import javax.swing.JFrame;

/**
*

  • @author Sergio
    */
    public class Teste {

    /**

    • @param args the command line arguments
      */
      public static void main(String[] args) {

      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setVisible(true);
      f.setTitle(“Teste”);
      f.setSize(800, 600);
      f.setLocationRelativeTo(null);

      No n = new No(12);
      f.add(new Arvore());

    }
    }[/code]

Classe No:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package teste;

import java.awt.BasicStroke;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

/**
*

  • @author Sergio
    */
    public class No extends JPanel{

    public No(){
    val = 0;
    alt = 0;
    pai = null;
    filDir = null;
    filEsq = null;
    }

    public No(int v){
    val = v;
    alt = 0;
    pai = null;
    filDir = null;
    filEsq = null;
    }

    public void setVal(int val){
    this.val = val;
    }

    public int getVal(){
    return val;
    }

    public void setAlt(int alt){
    this.alt = alt;
    }

    public int getAlt(){
    return alt;
    }

    public void setPai(No pai){
    this.pai = pai;
    }

    public No getPai(){
    return pai;
    }

    public void setFilDir(No filDir){
    this.filDir = filDir;
    }

    public No getFilDir(){
    return filDir;
    }

    public void setFilEsq(No filEsq){
    this.filEsq = filEsq;
    }

    public No getFilEsq(){
    return filEsq;
    }

    public void setPosX(int posX){
    this.posX = posX;
    }

    public int getPosX(){
    return posX;
    }

    public void setPosY(int posY){
    this.posY = posY;
    }

    public int getPosY(){
    return posY;
    }

    public void paint(Graphics g){
    Graphics2D g2d = (Graphics2D) g;

     Font a = new Font("Arial",Font.BOLD,16);
     
     if (filDir != null){
         g2d.drawLine(posX + (tam / 2), posY + (tam / 2), filDir.posX + (tam / 2), filDir.posY + (tam / 2));
     }
     
     if (filEsq != null){
         g2d.drawLine(posX + (tam / 2), posY + (tam / 2), filEsq.posX + (tam / 2), filEsq.posY + (tam / 2));
     }
     
     g2d.setStroke(new BasicStroke(3));
     g2d.drawOval(posX, posY, tam, tam);
     //tenta centralizar o texto no centro do circulo.
     g2d.setFont(a);
     g2d.drawString(String.valueOf(val),
             posX + ((tam / 2) - 4 * (String.valueOf(val).length())), 
             posY + ((tam / 2) + 4));
    

    }

    //atributos privados.
    private int val;
    private int alt;
    private No pai;
    private No filDir;
    private No filEsq;
    //variaveis do no grafico.
    private int tam = 50;
    private int posX;
    private int posY;
    }[/code]

Classe Arvore:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package teste;

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

/**
*

  • @author Sergio
    */
    public class Arvore extends JPanel{

    public Arvore(){
    raiz = null;
    }

    public Arvore(No raiz){
    this.raiz = raiz;
    }

    public void setRaiz(No raiz){
    this.raiz = raiz;
    }

    public No getRaiz(){
    return raiz;
    }

    public void paint(Graphics g){
    Graphics2D g2d = (Graphics2D) g;

    }

    private No raiz;
    }[/code]

Pelo que entendi, tenho que exibir um JPanel(No) em outro JPanel(Arvore). Só não sei como faz. A minha classe No está funcionando. Se rodarem o código abaixo, é criado um nó no JFrame.

Classe Principal com No instanciado:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package teste;

import javax.swing.JFrame;

/**
*

  • @author Sergio
    */
    public class Teste {

    /**

    • @param args the command line arguments
      */
      public static void main(String[] args) {

      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setVisible(true);
      f.setTitle(“Teste”);
      f.setSize(800, 600);
      f.setLocationRelativeTo(null);

      No n = new No(12);
      f.add(n);

    }
    }[/code]

Desde já, agradecido!

Não sei se é uma boa ideia ficar misturando Swing com AWT (mais que o necessário, porque em alguns casos é inevitável). Se entendi seu problema, você quer desenhar os nós de uma árvore em um JPanel (que é Swing), certo? Mas a sua dificuldade é calcular os pontos dos nós (a posição deles em relação ao pai) ou o desenho propriamente dito?

Se seu problema é o desenho, leia este tópico: http://www.guj.com.br/java/118828-exemplo-de-java2d—simulador-de-automatos. Tem umas noções de desenho legais que você pode aplicar ao seu problema. Tem também o fonte da aplicação, pra você baixar e estudar.

Se seu problema é o posicionamento, e seus nós não guardam a posição em que estão (ou seja, todas as vezes que a tela é atualizada - um novo nó é adicionado, por exemplo, você então está recalculando a posição de cada um deles a todo momento, certo? Neste link tem um exemplo que deve te ajudar: http://www.uta.fi/~jl/pguibook/other.html (veja a parte Binary tree for Java).

Uma observação: eu não vejo necessidade de os nós serem JPanel. Você pode criar, dentro deles, um Ellipse2D (Se estiver usando Java2D), e, no JPanel Pai, chamar um método draw para este Ellipse2D. É claro, depende da sua necessidade.

Abraço.

[quote=TerraSkilll]Não sei se é uma boa ideia ficar misturando Swing com AWT (mais que o necessário, porque em alguns casos é inevitável). Se entendi seu problema, você quer desenhar os nós de uma árvore em um JPanel (que é Swing), certo? Mas a sua dificuldade é calcular os pontos dos nós (a posição deles em relação ao pai) ou o desenho propriamente dito?

Se seu problema é o desenho, leia este tópico: http://www.guj.com.br/java/118828-exemplo-de-java2d—simulador-de-automatos. Tem umas noções de desenho legais que você pode aplicar ao seu problema. Tem também o fonte da aplicação, pra você baixar e estudar.

Se seu problema é o posicionamento, e seus nós não guardam a posição em que estão (ou seja, todas as vezes que a tela é atualizada - um novo nó é adicionado, por exemplo, você então está recalculando a posição de cada um deles a todo momento, certo? Neste link tem um exemplo que deve te ajudar: http://www.uta.fi/~jl/pguibook/other.html (veja a parte Binary tree for Java).

Uma observação: eu não vejo necessidade de os nós serem JPanel. Você pode criar, dentro deles, um Ellipse2D (Se estiver usando Java2D), e, no JPanel Pai, chamar um método draw para este Ellipse2D. É claro, depende da sua necessidade.

Abraço.[/quote]

Muito obrigado pela resposta. Mas, na verdade minha dúvida é como eu apresento o Nó dentro da Árvore. Como eu disse, sou novato em programação gráfica Java, então ainda estou meio confuso sobre o que é AWT e o que é Swing. Darei uma olhada no material que você indicou e também peguei alguns materiais sobre Swing.