3

我正在用 Java 编写一个简单的 Game of Life 程序,但在制作动画时遇到了一些麻烦。我有一个名为LifeDraw的JComponent类,它显示像素网格,具有以下绘制方法:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    for (int y = 0; y < lGrid.getHeight(); y++) {
        for (int x = 0; x < lGrid.getWidth(); x++) {
            if (lGrid.getCell(x,y) == 1) {
                g.setColor(Color.red);
                g.fillRect(x * lGrid.getSqSize(), y * lGrid.getSqSize(), lGrid.getSqSize(), lGrid.getSqSize());
            } else {
                g.setColor(Color.white);
                g.fillRect(x * lGrid.getSqSize(), y * lGrid.getSqSize(), lGrid.getSqSize(), lGrid.getSqSize());
            }
        }
    }
}

然后另一个类LifeGrid有一个方法run(),当调用该方法时,将更新一代像素网格,然后调用LifeDraw.repaint()。但是,如果我尝试run()在循环中调用,则JComponent在循环完成之前不会重新绘制,因此所显示的只是第一代和最后一代。我认为它可能只是更新太快而无法重新绘制,所以我尝试Thread.sleep()在迭代之间使用,但仍然遇到同样的问题。理论上(或者至少我希望它会),它应该在每次迭代之间重新绘制组件并显示像素变化的动画。

我对 Java GUI 不是很精通,所以任何帮助都将不胜感激。希望我已经解释得足够清楚,否则请告诉我!

4

3 回答 3

1

我不知道它是否能解决您的问题,但您可以尝试从Timer调用 run()而不是简单的 for 或 while 循环。

于 2010-01-06T20:04:26.937 回答
1

必须在事件循环中触发重绘,而不是在另一个线程中触发。
尝试用repaint()以下代码替换您的调用:

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        repaint();
    }
}); 
于 2010-01-06T20:06:43.520 回答
1

来自 JavaDocs repaint()

如果组件正在显示,则将指定区域添加到脏区域列表。在所有当前挂起的事件都被调度后,组件将被重新绘制。

重绘所做的只是表明该区域需要重绘。
尝试paintImmediatelyupdate

于 2010-01-06T20:12:44.937 回答