【发布时间】:2014-07-01 12:10:31
【问题描述】:
我正在尝试通过从文本字段中插入其元素来创建 AVL 树,然后通过按下按钮“绘制”来绘制树。我的问题是,当我将随机元素存储在主树中并运行程序时,paint 方法工作正常并且树在框架上绘制,但是当我使用文本字段插入元素并在 actionPerformed 方法中调用 repaint 方法时对于绘制按钮,它不绘制任何东西。 有人可以帮我知道绘制按钮的 actionPerformed 方法有什么问题以及为什么 repaint 方法没有响应。
这是我的第一个包含所有组件的面板
public class PanelComponents extends JPanel {
private JButton insertB;
private JButton drawB;
private JTextField insertTF;
private AvlTree<Integer> avl = new AvlTree<Integer>();// use AVL tree class
private TreeCanvas treeCanvas;
public PanelComponents() {
setPreferredSize(new Dimension(780, 500));
insertB = new JButton("insert");
drawB = new JButton("draw");
insertTF = new JTextField(7);
createTreeCanvas();
insertB.addActionListener(new ActionListener() {
// here is the event handler
public void actionPerformed(ActionEvent e) {
int number = Integer.parseInt(insertTF.getText());
avl.insert(number);
}
});
drawB.addActionListener(new ActionListener() {
// here is the event handler
public void actionPerformed(ActionEvent e) {
if (avl.isEmpty()) return;
treeCanvas.setRoot(avl.getRoot());
treeCanvas.repaint();
}
});
add(insertTF);
add(insertB);
add(drawB);
}
private TreeCanvas createTreeCanvas() {
if (treeCanvas == null) {
treeCanvas = new TreeCanvas();
treeCanvas.setBounds(5,5,680,230);
add(treeCanvas);
}
return treeCanvas;
}
}
这是演示类
public class TreeDemo {
public TreeDemo(){
/**
* when I use this way of inserting the tree painted
*/
// AvlTree<Integer> t = new AvlTree<Integer>();
// t.insert (new Integer(2));
// t.insert (new Integer(1));
// t.insert (new Integer(4));
// t.insert (new Integer(5));
// t.insert (new Integer(9));
// t.insert (new Integer(3));
// t.insert (new Integer(6));
// t.insert (new Integer(7));
// TreeCanvas b =new TreeCanvas();
// b.setRoot(t.getRoot());
JFrame frame = new JFrame("AVL Tree");
PanelComponents panel = new PanelComponents();
// frame.add(b);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(1000, 700);
}
public static void main (String[] args){
new TreeDemo();
}}
这个类用于在面板上绘制树,它工作正常。你不需要经历它
public class TreeCanvas extends JPanel {
private static final int NODE_WIDTH = 30;
private static final int ROW_GAP = 10;
private AvlNode<Integer> root;
public TreeCanvas() {
root = null;
}
interface RenderNode {
public void draw(Graphics g, AvlNode<Integer> parent, Point parentLoc,
AvlNode<Integer> child, Point childLoc);
}
public void paint(Graphics g) {
super.paint(g);
int startX = getWidth() / 2;
int startY = ROW_GAP + (NODE_WIDTH / 2);
render(g, null, null, root, new Point(startX, startY), getWidth() / 2,
new RenderNode() {public void draw(Graphics g, AvlNode<Integer>
parent, Point parentLoc, AvlNode<Integer> child, Point childLoc) {
if (parent != null) {
g.setColor(Color.black);
g.drawLine(parentLoc.x, parentLoc.y, childLoc.x,childLoc.y);
}
}
});
render(g, null, null, root, new Point(startX, startY), getWidth() / 2,
new RenderNode() {
public void draw(Graphics g, AvlNode<Integer>parent,
point parentLoc, AvlNode<Integer> child, Point childLoc) {
child.draw(g, childLoc);
}
});
}
private void render(Graphics g, AvlNode<Integer> parent, Point parentLoc,
AvlNode<Integer> child, Point childLoc, int spacing, RenderNode
callback) {
if (child == null)
return;
callback.draw(g, parent, parentLoc, child, childLoc);
int nextY = childLoc.y + (ROW_GAP + NODE_WIDTH);
render(g, child, childLoc, child.getLeft(), new Point(childLoc.x
- (spacing / 2), nextY), spacing / 2, callback);
render(g, child, childLoc, child.getRight(), new Point(childLoc.x
+ (spacing / 2), nextY), spacing / 2, callback);
}
public void setRoot(AvlNode<Integer> root){
this.root = root;
}
}
【问题讨论】:
-
不要使用
paint()进行自定义绘画,使用paintComponent()。 -
谢谢,我使用了paintComponent(),但还是同样的问题。
-
您的渲染代码令人困惑且难以理解。乍一看,你真的想要
if (parent != null) {检查一旦 TreeCanvas 已经被添加,因此已经有了一个父母?我的建议是添加简单的 system.out.println 语句,或者使用调试器来验证方法是否按您期望的顺序被调用。如果是这样,那么您的代码中存在逻辑错误。