JFrame 仅在调整大小时更新 window

JFrame updates only upon resizing window

出于学习目的,我正在尝试制作自己的贪吃蛇版本。一切似乎都很好,除了如果我想重新粉刷我的框架,我必须手动调整 window 的大小。这是我的代码:

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

    }


}

为什么在不改变帧大小的情况下不触发 repaint()?我得到了相关性,但我不明白为什么它在 while(true) 循环中需要这样的触发器。

我在这里错过了什么?

编辑 1: 删除线程对象 将 t.start() 替换为 p.start()

编辑 2: 添加了 new Thread(p).start();,现在可以使用了!谢谢

编辑 3: 已删除 revalidate();

您正在工作线程中执行 repaint(),而不是在 事件调度线程 (EDT) 中执行,后者是唯一实际绘制到屏幕上的线程。

您必须使用 SwingUtilities 静态方法 invokeLater()invokeAndWait().

在 EDT 中将对 repaint() 的调用排队

已添加new Thread(p).start();

仍然不知道这与之前有何不同或为何不同 Thread t = new Thread(p); t.start();

但它奏效了。