Прочитав больше о 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 по-прежнему пуст. Есть видимая причина, почему? на основе этого кода
РЕДАКТИРОВАТЬ: я заметил, что он даже не создает рисунок, он не дает ему название