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();
但它奏效了。
出于学习目的,我正在尝试制作自己的贪吃蛇版本。一切似乎都很好,除了如果我想重新粉刷我的框架,我必须手动调整 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()
.
repaint()
的调用排队
已添加new Thread(p).start();
仍然不知道这与之前有何不同或为何不同
Thread t = new Thread(p);
t.start();
但它奏效了。