当试图绘制它时,JPanel会冻结我的整个应用程序

时间:2011-12-03 22:10:22

标签: java swing drawing jpanel freeze

我正在为一个学校项目编写Oregon Trail,我正在实施狩猎迷你游戏。我们正在使用具有卡片布局的模型视图演示器。当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();
    }
}

2 个答案:

答案 0 :(得分:5)

您必须实施javax.swing.Timer而不是Thread.sleep(int),因为此代码行会在EDT期间冻结所有GUI,直到Thread.sleep(int)结束。这是demonstrations如果GUI在EDT期间被Thread.sleep(int)

延迟会发生什么

答案 1 :(得分:2)

您的程序“冻结”,因为您没有为while循环启动新线程。由于面板更新和重绘是在主线程中处理的,因此您可以防止它们发生。要解决此问题,您必须启动一个新线程。你可以通过让你的类实现runnable并使用新的Thread(this).start()来运行你的循环来做到这一点。

class HuntingGame extends JPanel implements Runnable {
    public void initialize(int x) {
        //...
        new thread(this).start();// This will run your 'run()' method in a new thread.
    }
}