我正在为BST实施进行可视化(我前几天发布了另一个关于它的问题)。我创建了一个显示查看区域和按钮的GUI。我已经向BST实现添加了代码以递归遍历树,该函数接收坐标以及最初由主GUI类传入的Graphics对象。我的想法是,我只是让这个函数在每次更新(添加,删除等等)之后重新绘制树,首先在所有内容上绘制一个矩形以“刷新”查看区域。这也意味着我可以改变BST实现(即通过添加平衡操作),它不会影响可视化。
我遇到的问题是绘图功能仅在第一次调用时才起作用,之后它不会显示任何内容。我想我并不完全理解Graphics对象是如何工作的,因为它不会像我从不同函数传递/调用时那样预期。我知道getGraphics函数与它有关。
相关代码:
private void draw(){
Graphics g = vPanel.getGraphics();
tree.drawTree(g,ORIGIN,ORIGIN);
}
vPanel是我正在使用的
private void drawTree(Graphics g, BinaryNode<AnyType> n, int x, int y){
if( n != null ){
drawTree(g, n.left, x-10,y+10 );
if(n.selected){
g.setColor(Color.blue);
}
else{
g.setColor(Color.gray);
}
g.fillOval(x,y,20,20);
g.setColor(Color.black);
g.drawString(n.element.toString(),x,y);
drawTree(g,n.right, x+10,y+10);
}
}
当公共函数调用它时,它会传递给根节点。我必须要:
Graphics g = vPanel.getGraphics();
...在drawTree函数中?这没有意义!!
感谢您的帮助。
答案 0 :(得分:4)
这不是正确的做法。如果您想要一个显示树的组件,您应该创建自己的JComponent
并覆盖paintComponent
- 方法。
每当模型(树/当前节点等)发生变化时,您都会调用redraw()
,这将触发paintComponent
。
我实际上不认为你可以从Graphics
方法的参数以外的任何地方获取paintComponent
对象。
试用以下程序
import java.awt.Graphics;
public class FrameTest {
public static void main(String[] args) {
final JFrame f = new JFrame("Frame Test");
f.setContentPane(new MyTreeComponent());
f.setSize(400, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
new Thread() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
f.repaint();
}
}
}.start();
}
}
class MyTreeComponent extends JComponent {
public void paintComponent(Graphics g) {
// Draw your tree. (Using random here to visualize the updates.)
g.drawLine(30, 30, 50, 30 + new Random().nextInt(20));
g.drawLine(30, 30, 50, 30 - new Random().nextInt(20));
}
}
最佳起点可能是http://java.sun.com/docs/books/tutorial/uiswing/painting/index.html
答案 1 :(得分:2)
@ aioobe的方法是合理的,这个例子很有说服力。除了引用的教程Performing Custom Painting之外,我还要补充一点,绘图应该在Event Dispatch Thread (EDT)上进行。在下面的变体中,请注意如何使用EventQueue.invokeLater
构建GUI。同样,actionPerformed()
的{{1}}方法会在EDT上调用javax.swing.Timer
来显示最近添加的节点。可以找到更详细的示例here。
repaint()