Search code examples
javaswingrepaint

repaint in a loop


I am writing a game using Java Swing. I want to paint each time a loop executes with a small delay in between to create a cascade effect on screen. I believe that the efficiency routines in the system are collapsing the calls to repaint() into a single call. At any rate, the changes all occur at once after the total delay. Is there some way to force the system to repaint immediately and then delay on each iteration of the loop?

My Code:

for(int i=0;i<10;i++){
    JButton[i].setBackground(Color.WHITE);
    JButton[i].repaint();
    Thread.sleep(2000);
    JButton[i].setBackground(Color.GRAY);
    JButton[i].repaint();
}

Solution

  • You can use JComponent.paintImmediately to force an immediate repaint.

    EDIT: After reading your question again it occurs to me that you might be executing your logic on the event dispatch thread. This would mean that the repaint requests will not be executed until after your method returns. If you put your code into another thread then that will probably fix the problem and it will be a lot nicer than using paintImmediately.

    void uiFunction() {
        new Thread() {
            public void run() {
                for(int i = 0; i < 10; i++) {
                    final JButton b = buttons[i];
                    SwingUtilities.invokeLater(new Runnable() {
                        b.setBackground(Color.WHITE);
                        b.repaint();
                    }
                    Thread.sleep(2000);
                    SwingUtilities.invokeLater(new Runnable() {
                        b.setBackground(Color.GRAY);
                        b.repaint();
                    }
                }
            }
        }.run();
    }
    

    It's a bit mucky but hopefully it gives you an idea of where to begin.