Использование Java JComponent repaint () - PullRequest
3 голосов
/ 06 января 2010

Я пишу простую программу Game of Life на Java, и у меня возникли проблемы с ее анимацией. У меня есть класс JComponent с именем LifeDraw , который отображает сетку пикселей со следующим методом рисования:

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 ]

1 голос
/ 06 января 2010

Перерисовка должна запускаться в цикле событий, а не в другом потоке.
Попробуйте заменить свой звонок на repaint() следующим кодом:

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        repaint();
    }
}); 
1 голос
/ 06 января 2010

Из JavaDocs для repaint():

Добавляет указанный регион в список грязных регионов, если компонент показ. Компонент будет перекрашен после всего текущего ожидающие события были отправлены.

Все, что нужно перекрасить, это сигнал, что область нуждается в перекраске.
Попробуйте paintImmediately или update.

1 голос
/ 06 января 2010

Я не знаю, решит ли это вашу проблему, но вы можете попробовать вызвать run () из Timer вместо простого цикла for или while.

...