我正在为 BST 实现制作可视化(前几天我发布了另一个关于它的问题)。我创建了一个显示查看区域和按钮的 GUI。我已将代码添加到 BST 实现以递归遍历树,该函数接收坐标以及最初由主 GUI 类传入的 Graphics 对象。我的想法是让这个函数在每次更新(添加、删除等)后重新绘制树,首先在所有内容上绘制一个矩形以“刷新”查看区域。这也意味着我可以更改 BST 实现(即通过添加平衡操作)并且它不会影响可视化。
我遇到的问题是 draw 函数仅在第一次调用时起作用,之后它不显示任何内容。我想我不完全理解 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);
}
}
它被公共(public)函数调用时传递给根节点。我是否必须:
Graphics g = vPanel.getGraphics();
...在 drawTree 函数中?这没有意义!!
感谢您的帮助。
最佳答案
这不是正确的做法。如果您想要一个显示树的组件,您应该制作自己的 JComponent
并覆盖 paintComponent
方法。
每当模型(树/当前节点等)发生变化时,您调用 redraw()
将触发 paintComponent
。
我实际上认为除了 paintComponent
方法的参数之外,您不能从任何其他地方获取 Graphics
对象。
试试下面的程序
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
关于Java 图形在连续的函数调用中不显示,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2749191/