Nathan Ruth
Nathan Ruth

Reputation: 163

JFrame updates only upon resizing window

I'm trying to make my own version of Snake for learning purposes. Everything seems to work fine except that if I want my frame to be repainted, I have to resize my window manually. Here is my code:

package snake;

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PlayGame extends JPanel implements Runnable{

    public boolean animate = false;           
    public final int FRAME_DELAY = 750;

    PickupBall b = new PickupBall();
    Snake bob = new Snake();


    public synchronized void start() {
        animate = true;
    }

    public synchronized void stop() {
        animate = false;
    }
    private synchronized boolean animationEnabled() {
        return animate;
    }

    @Override
    public void run(){            
        while(true){    
            if (animationEnabled()){                    
                repaint();                    
            }
            try {
                Thread.sleep(FRAME_DELAY);
            }   
            catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }        

    @Override
    public void paintComponent(Graphics g){            
        super.paintComponent(g);  

        b.draw(g);
        bob.draw(g);            
    }        

    public static void main(String[] args) {    
        JFrame jfr = new JFrame("Snake");  
        jfr.setSize(640,640);
        jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            
        jfr.setResizable(true);

        PlayGame p = new PlayGame();  

        jfr.setContentPane(p);  

        p.setBackground(Color.WHITE);            

        p.start();            

        new Thread(p).start();            
        jfr.setVisible(true);    

    }


}

Why isn't repaint() triggered without altering the frame size? I get the correlation but it makes no sense to me why it needs such a trigger when it's in a while(true) loop anyway.

What am I missing here?

Edit 1: Removed thread object Replaced t.start() with p.start()

Edit 2: Added new Thread(p).start(); and now it works! Thanks.

Edit 3: Removed revalidate();

Upvotes: 1

Views: 350

Answers (2)

Nathan Ruth
Nathan Ruth

Reputation: 163

Added new Thread(p).start();

Still have no idea how or why this is different to Thread t = new Thread(p); t.start();

But it worked.

Upvotes: 0

Timothy Truckle
Timothy Truckle

Reputation: 15622

You are executing repaint() in the worker thread and not in the event dispatch tread (EDT) which is the only one actually drawing onto the screen.

You have to en queue the call to repaint() in the EDT using SwingUtilities static methods invokeLater() or invokeAndWait().

Upvotes: 1

Related Questions