当尝试在 JPanel 上绘图时,JPanel 冻结了我的整个应用程序
我正在为一个学校项目编写俄勒冈小道的代码,并且正在实现狩猎迷你游戏。我们使用带有卡片布局的模型视图演示器。当 HuntingPanel
切换到它时,它会调用 run,并且 JOptionPane
出现,但随后整个应用程序冻结,我必须强制退出。我在一个单独的项目中对整个狩猎游戏进行了编码,现在将文件带到了 Oregon Trail 游戏中。它在自己的项目中使用自己的 JFrame
运行良好。我不知道该怎么办。
我称其为初始化面板、切换到它并运行游戏。
public void initialize(int ammo) {
player.setBullets(ammo);
bulletLabel.setText("Bullets: "+player.getBullets());
presenter.switchToPanel(OregonTrailPresenter.HUNTING_PANEL);
run();
}
这是我的运行方法。
public void run() {
// starting message
JOptionPane.showMessageDialog(null, "You have reached a nearby field to hunt. You will stay\nhere until " +
"you run out of ammunition or click Return to Trail.");
// while the player has bullets or doesn't click return to trail
while (player.getBullets() > 0 && stillHunting) {
// creates random animals
checkForAnimal();
// moves and updates screen
repaint();
update();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
endHunting();
}
这里还有其他使用的方法。
private void checkForAnimal() {
int x = 0;
int y = rand.nextInt(MAX_Y)-40;
int rand1 = rand.nextInt(100);
String str = null;
if (rand1 < 50) {
str = "left";
x = MAX_X-40;
}
else if (rand1 >= 50) {
str = "right";
x = 0;
}
double gen = rand.nextGaussian(); // gen is a number from -inf to +inf
gen = Math.abs(gen); // gen is now a number from 0 to inf
if (gen >= 1.9 && gen < 2.1) { //1.19%
animalList.add(new Bunny(x,y,str));
}
if(gen >= 2.1 && gen < 2.2) { //0.9%
animalList.add(new Bear(x,y,str));
}
if (gen >= 2.2 && gen < 2.3) {
animalList.add(new Deer(x,y,str));
}
}
public void update() {
for (int i = 0; i < animalList.size(); i++) {
animalList.get(i).move();
}
}
I am coding Oregon Trail for a school project and I am implementing the hunting mini game. We are using model view presenter with a card layout. When the HuntingPanel
gets switched to it calls run, and the JOptionPane
comes up, but then the whole application freezes and I have to force quit. I coded the entire hunting game in a separate project, and just now brought the files over to the Oregon Trail game. It works fine in its own project with its own JFrame
. I'm not sure what to do.
I call this to initialize the panel, switch to it, and run the game.
public void initialize(int ammo) {
player.setBullets(ammo);
bulletLabel.setText("Bullets: "+player.getBullets());
presenter.switchToPanel(OregonTrailPresenter.HUNTING_PANEL);
run();
}
This is my run method.
public void run() {
// starting message
JOptionPane.showMessageDialog(null, "You have reached a nearby field to hunt. You will stay\nhere until " +
"you run out of ammunition or click Return to Trail.");
// while the player has bullets or doesn't click return to trail
while (player.getBullets() > 0 && stillHunting) {
// creates random animals
checkForAnimal();
// moves and updates screen
repaint();
update();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
endHunting();
}
And here are other method used.
private void checkForAnimal() {
int x = 0;
int y = rand.nextInt(MAX_Y)-40;
int rand1 = rand.nextInt(100);
String str = null;
if (rand1 < 50) {
str = "left";
x = MAX_X-40;
}
else if (rand1 >= 50) {
str = "right";
x = 0;
}
double gen = rand.nextGaussian(); // gen is a number from -inf to +inf
gen = Math.abs(gen); // gen is now a number from 0 to inf
if (gen >= 1.9 && gen < 2.1) { //1.19%
animalList.add(new Bunny(x,y,str));
}
if(gen >= 2.1 && gen < 2.2) { //0.9%
animalList.add(new Bear(x,y,str));
}
if (gen >= 2.2 && gen < 2.3) {
animalList.add(new Deer(x,y,str));
}
}
public void update() {
for (int i = 0; i < animalList.size(); i++) {
animalList.get(i).move();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须实现 javax.swing.Timer 而不是 < code>Thread.sleep(int),因为此代码行在 EDT 直到 Thread.sleep(int) 结束。以下是演示,如果 GUI 在 EDT 期间被
Thread.sleep(int)
延迟,会发生什么情况You have to implement javax.swing.Timer instead of
Thread.sleep(int)
, because this code line freezes all GUI during EDT untilThread.sleep(int)
ends. Here is demonstrations what happens if the GUI is delayed during EDT byThread.sleep(int)
您的程序“冻结”,因为您没有为 while 循环启动新线程。由于面板更新和重绘是在主线程中处理的,因此您可以防止它们发生。要解决此问题,您必须启动一个新线程。您可以通过使您的类实现可运行并使用 new Thread(this).start() 来运行循环来做到这一点。
Your program "freezes" because you did not start a new thread for the while loop. Since the panel updates and redraws are handled in the main thread, you are preventing them from happening. To fix this problem you have to start a new thread. You can do this by making your class implement runnable and use new Thread(this).start() to run your loop.