Окна сообщений не перестанут появляться

Я, честно говоря, не уверен, что заголовок полностью соответствует вопросу, но все же вот он. Я делаю простую игру на java, в которой инопланетные космические корабли падают с верхней части экрана, и если вы их не убьете, и они доберутся до нижней части экрана, космическая станция получит урон. Но всякий раз, когда космическая станция уничтожается, окно сообщения, которое должно сообщить игроку, что он умер, не перестанет появляться, оно просто продолжает появляться снова и снова. И в консоли я получаю сообщение об ошибке, которое не перестанет увеличиваться! Это код, который у меня есть для здоровья космической станции:

public class SpaceStation extends Entity {
public static int stationHealth = 100;

public SpaceStation(int x, int y) {
    super(x, y);
}

public void update() {
}

public void draw(Graphics2D g2d) {
    g2d.drawImage(ImageLocator.getSpaceStation(), 0, 595, null);

    // HEALTH BAR
    g2d.fillRect(5, 25, stationHealth, 10);

    if(stationHealth <= 0) {
        try{
            JOptionPane.showMessageDialog(null, "You died on level "
                    + GameFrame.level + ". Better luck next time!");
            GameFrame.mainTimer.stop();
            System.exit(0);
        }
        catch(Exception e){
            JOptionPane.showMessageDialog(null, e.getMessage());
            System.exit(0);
        } 
    }
}

public Rectangle getBounds() {
    return new Rectangle(x, y, 600, 200);
}

}

По-видимому, строка, в которой находится ошибка, - это JOptionPane.showMessageDialog(null, "Вы умерли на уровне" Вот сообщение об ошибке:

at java.lang.Thread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: The current process has         used all of its system allowance of handles for Window Manager objects.

at sun.awt.windows.WToolkit.eventLoop(Native Method)
at sun.awt.windows.WToolkit.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: The current process has used all of its system allowance of handles for Window Manager objects.

Спасибо за ваше время.


person Connor    schedule 21.08.2012    source источник
comment
Вероятно, у вас происходит скрытая рекурсия, вызывающая ошибку переполнения стека. Пожалуйста, опубликуйте сообщение об ошибке, хотя бы первые 20-30 строк. Ошибка также, вероятно, связана с кодом, который вы не показываете. Какая строка вызывает ваше исключение? Пожалуйста, не забудьте опубликовать эту строку и соответствующий код. В противном случае вы как бы заставляете нас догадываться о том, что происходит, и это обычно не слишком хорошо работает.   -  person Hovercraft Full Of Eels    schedule 21.08.2012
comment
@ Эндрю: 5+ голосов. Пожалуйста, сделайте это ответом, чтобы я мог проголосовать за него по-настоящему, и чтобы оригинальный постер мог его принять. Это проблема и решение. Нам нужно было только, чтобы ОП разместил достаточно информации, чтобы нам не приходилось гадать!   -  person Hovercraft Full Of Eels    schedule 21.08.2012
comment
Ой! Спасибо, я больше не получаю эту ошибку, но, похоже, это не имеет большого значения, stationHealth в конечном итоге становится отрицательным, и игра продолжается. Я поместил его в метод update(). Это нормально? О, и извините за то, что не опубликовал достаточно. знак равно   -  person Connor    schedule 21.08.2012
comment
Затем вам нужно проверить stationHealth каким-либо другим способом, либо в вашем игровом цикле (возможно, с помощью таймера Swing), либо сделав stationHealth связанным свойством с помощью PropertyChangeListener.   -  person Hovercraft Full Of Eels    schedule 21.08.2012
comment
Я бы проверил это в actionListener из Timer. ifGameOver() возвращает true, останавливает таймер и вызывает assessWinner(), что может вызвать диалоговое окно «У вашего персонажа 0 здоровья» (намного лучше, чем «Попался, сосунок»).   -  person Andrew Thompson    schedule 21.08.2012


Ответы (1)


Не открывайте диалог из метода рисования! Или, возможно, более специфично для предметной области, не делайте этого в методе, который может быть вызван из метода рисования другого класса, как предлагает draw(Graphics2D).

Я могу только предположить, что в вашем коде есть таймер, который вызывает repaint(), что, в свою очередь, может вызвать вызов paint(Graphics) или paintComponent(Graphics). Но это также делает и сама JRE всякий раз, когда она знает, что компонент может иметь элемент, появляющийся поверх, .. как JOptionPane. Отсюда и «бесконечный цикл».

person Andrew Thompson    schedule 21.08.2012
comment
Спасибо и 1+. ОП, это твоя проблема и ее решение. - person Hovercraft Full Of Eels; 21.08.2012
comment
Спасибо! Я бы +1, если бы мог. Спасибо всем за помощь! - person Connor; 21.08.2012