Question

I'm writing a simple Game of Life program in Java and am having a bit of trouble getting it to animate. I've got a JComponent class called LifeDraw, which displays a grid of pixels, with the following paint method:

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());
            }
        }
    }
}

And then another class LifeGrid that has a method run(), which when called will update the grid of pixels for one generation and then call LifeDraw.repaint(). However, if I try to call run() in a loop, the JComponent doesn't repaint until the loop is finished so all that is ever displayed is the first generation and the last one. I figured it was probably just updating too quickly to repaint, so I tried using Thread.sleep() between iterations but still had the same problem. Theoretically (or at least I was hoping it would), it should repaint the component between each iteration and display an animation of the pixels changing.

I'm not that well versed in Java GUI, so any help would be really appreciated. Hopefully I've explained it clearly enough, let me know otherwise!

Was it helpful?

Solution

I don't know if it would solve your problem, but you could try calling run() from a Timer instead of a simple for or while loop.

OTHER TIPS

From the JavaDocs for repaint():

Adds the specified region to the dirty region list if the component is showing. The component will be repainted after all of the currently pending events have been dispatched.

All repaint does is signal that the area needs repainting.
Try paintImmediately or update.

Repaint has to be fired in the event loop, not in another thread.
Try replacing your call to repaint() with following code:

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        repaint();
    }
}); 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top