JPanel замораживает все мое приложение при попытке рисовать на нем - PullRequest
3 голосов
/ 04 декабря 2011

Я пишу код Oregon Trail для школьного проекта и внедряю мини-игру для охоты.Мы используем модельный вид презентера с макетом карты.Когда HuntingPanel переключается на него, запускаются вызовы, и появляется 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 ]

5 голосов
/ 04 декабря 2011

Вы должны реализовать javax.swing.Timer вместо Thread.sleep(int), потому что эта строка кода останавливает весь графический интерфейс во время EDT до тех пор, пока Thread.sleep(int) не закончится. Вот демонстрации что происходит, если GUI задерживается во время EDT на Thread.sleep(int)

2 голосов
/ 04 декабря 2011

Ваша программа "зависает", потому что вы не запустили новый поток для цикла while. Поскольку обновления и перерисовки панели обрабатываются в главном потоке, вы предотвращаете их возникновение. Чтобы решить эту проблему, вы должны начать новую тему. Вы можете сделать это, заставив ваш класс реализовать работоспособный и использовать новый 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.
    }
}
...