Двоичное дерево не рисуется в JInternalFrame - PullRequest
0 голосов
/ 25 апреля 2020

Прочитав больше о Java GUI, я решил адаптировать BST к форме GUI. Идея довольно проста c: вставьте узел и посмотрите, как дерево раскрашивается каждый раз, когда вы нажимаете кнопку вставки.

Однако в моей программе дерево не рисуется, и я не получаю любые сообщения об ошибках.

Мой класс BinarySearchTree

    public class BinarySearchTree {
        class Node {
            int key;
            Node left;
            Node right;

            public Node(int item) {
                key = item;
                left = right = null;
            }
        }
        int height;
        Node root;

        BinarySearchTree(){
            root = null;
        }

        Node insert(int key) {
            root = recursion(root, key);
            return root;
        }

        Node recursion(Node root, int key) {
            if(root == null) {
                root = new Node(key);
                return root;
            }

            if(key < root.key) {
                root.left = recursion(root.left, key);
            } else if (key > root.key) {
                root.right = recursion(root.right, key);
            }
            return root;
        }

        private void height(Node key, int depth) {
            if (key != null) {
                height(key.left, depth + 1);
                height = depth;
                height(key.right, depth + 1);
            }
        }


        public int getHeight() {
            height(root, 1);
            return height;
        }

        public JPanel getGraph() {
            return new BSTGraph(this);
        }

        public void makeEmpty() {
            root = null;
        }

        public boolean isEmpty() {
            if(root==null)
                return true;
            else
                return false;


 }
}

Мой класс BSTGraph

public class BSTGraph extends JPanel{

    private BinarySearchTree bst;
    private HashMap nodeMap = null;
    private HashMap subtreeSizes = null;
    private boolean dirty = true;
    private int parentToChild = 20, childToChild = 30;
    private Dimension empty = new Dimension(0,0);
    private FontMetrics fm = null;

    public BSTGraph(BinarySearchTree bst) 
    {
          this.bst = bst;
          this.setBackground(Color.WHITE);
          nodeMap = new HashMap();
          subtreeSizes = new HashMap();
          dirty = true;
          repaint();      
    }

    private void getPositions() 
    {
         nodeMap.clear();
         subtreeSizes.clear();
         BinarySearchTree.Node root = this.bst.root;
         if (bst.root != null) 
         {
             getChildTreeSize(bst.root);
             getPosition(root, Integer.MAX_VALUE, Integer.MAX_VALUE, 0);
         }
    }

    private void getPosition(BinarySearchTree.Node n, int left, int right, int top) 
    {
      if (n == null) 
          return;

      Dimension ld = (Dimension) subtreeSizes.get(n.left);
      if (ld == null) 
          ld = empty;

      Dimension rd = (Dimension) subtreeSizes.get(n.right);
      if (rd == null) 
          rd = empty;

      int center = 0;

      if (right != Integer.MAX_VALUE)
          center = right - rd.width - childToChild/2;
      else if (left != Integer.MAX_VALUE)
          center = left + ld.width + childToChild/2;
      int width = fm.stringWidth(n.key+"");

      nodeMap.put(n,new Rectangle(center - width/2 - 3, top, width + 6, fm.getHeight()));

      getPosition(n.left, Integer.MAX_VALUE, center - childToChild/2, top + fm.getHeight() + parentToChild);
      getPosition(n.right, center + childToChild/2, Integer.MAX_VALUE, top + fm.getHeight() + parentToChild);
    }

    private Dimension getChildTreeSize(BinarySearchTree.Node n) 
    {
          if (n == null) 
              return new Dimension(0,0);

          Dimension ld = getChildTreeSize(n.left);
          Dimension rd = getChildTreeSize(n.right);

          int h = fm.getHeight() + parentToChild + Math.max(ld.height, rd.height);
          int w = ld.width + childToChild + rd.width;

          Dimension d = new Dimension(w, h);
          subtreeSizes.put(n, d);

          return d;
    }

    private void graphTree(Graphics2D g, BinarySearchTree.Node n, int x, int y, int yOffSet) 
    {
     if (n == null) 
         return;

     Rectangle r = (Rectangle) nodeMap.get(n);
     g.draw(r);
     g.drawString(n.key+"", r.x + 3, r.y + yOffSet);

     if (x != Integer.MAX_VALUE)

     g.drawLine(x, y, (int)(r.x + r.width/2), r.y);

     graphTree(g, n.left, (int)(r.x + r.width/2), r.y + r.height, yOffSet);
     graphTree(g, n.right, (int)(r.x + r.width/2), r.y + r.height, yOffSet);

   }

    @Override
   public void paint(Graphics g) 
   {
         super.paint(g);
         fm = g.getFontMetrics();

         if (dirty) 
         {
           getPositions();
           dirty = false;
         }

         Graphics2D g2d = (Graphics2D) g;
         g2d.translate(getWidth() / 2, parentToChild);
         graphTree(g2d, this.bst.root, Integer.MAX_VALUE, Integer.MAX_VALUE, 
                  fm.getLeading() + fm.getAscent());
         fm = null;
   }
}

Наконец, в моем классе GUI есть метод дополнения, который заботится о добавлении «рисование» в элемент JInternalFrame с именем graficoFrame

public void complement(){

        Rectangle size = this.graficoFrame.getBounds();
        this.graficoFrame = null;
        this.graficoFrame = new JInternalFrame("Representación gráfica", true);
        this.graficoFrame.setBounds(size);
        this.graficoFrame.setEnabled(false);
          this.repaintTree();
    }
    private void repaintTree() {

        Rectangle size = this.graficoFrame.getBounds();
        this.graficoFrame = null;
        this.graficoFrame = new JInternalFrame("Representación gráfica", true);
        this.graficoFrame.setBounds(size);
        this.graficoFrame.setEnabled(false);
        this.graficoFrame.add(bst.getGraph(), BorderLayout.CENTER);
        this.graficoFrame.setVisible(true);
    }

Я подтвердил, что узлы правильно добавляются и сохраняются, однако чертеж никогда не отображается, JInternalFrame по-прежнему пуст. Есть видимая причина, почему? на основе этого кода

РЕДАКТИРОВАТЬ: я заметил, что он даже не создает рисунок, он не дает ему название

...