使用Java的JComponent repaint()

时间:2010-01-06 20:00:38

标签: java swing repaint jcomponent

我正在用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,所以任何帮助都会非常感激。希望我已经足够清楚地解释了它,让我知道其他情况!

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        repaint();
    }
}); 

答案 2 :(得分:1)

来自repaint()的JavaDocs:

  

如果组件是,则将指定的区域添加到脏区列表中   展示。该组件将在所有当前重新绘制后重新绘制   已发送待处理事件。

所有重画都表示该区域需要重新粉刷 试试paintImmediatelyupdate