исключение указателя java

1

У меня есть класс, который создает корабль (класс Ship расширяет GameObject) и пытается добавить его в gameBoard.
Чтобы сделать это, он сообщает gameFrame добавить объект следующим образом:

public void startNewGame() {
    Ship myShip = new Ship(GAME_BOARD_WIDTH / 2, GAME_BOARD_HEIGHT-1, SHIP_WIDTH,
            SHIP_HEIGHT);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            gameFrame = new InvadersGameFrame();
        }
    });
    gameFrame.addGameObject(myShip); //Problem line
    gameFrame.repaint();
}

Затем GameFrame вызывает:

GameBoard gameBoard = new GameBoard();
...
...
public void addGameObject(GameObject ob) {
    gameBoard.addGameObject(ob);
}

Что в свою очередь вызывает:

public class GameBoard extends JPanel implements GameData{
    private JPanel gameBoard;
    private List<GameObject> objects = new ArrayList<>();

    public GameBoard() {
        gameBoard = new JPanel();
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        setBackground(Color.black);
        g.setColor(Color.RED);
        for(GameObject ob : objects){
            g.drawOval(ob.x, ob.y, ob.width, ob.height);
        }
    }

    //Places object into list for drawing upon next repaint.
    public void addGameObject(GameObject ob) {
        objects.add(ob);
    }
}

Теперь моя проблема в том, что я получаю исключение Null Pointer Exception, когда у меня есть gameFrame.addGameObject(myShip);
Трудность в том, что когда я запускаю через отладчик, я вообще не получаю NPE (но список моих объектов по-прежнему кажется пустым).
Кроме того, я могу следить за каждым из них и все еще видеть myShip, так что я просто ссылаюсь на свой GameObject (Ship) неправильно?
Должны ли мои параметры addGameObject как-то быть более абстрактными?

  • 1
    У вас есть трассировка стека для публикации?
  • 0
    Ваша трассировка стека является наиболее ценной информацией, которую вы имеете при отладке подобных вещей. Почему вы забыли опубликовать это?
Показать ещё 2 комментария
Теги:
swing
nullpointerexception

4 ответа

4
Лучший ответ

Проблема в том, что вы назначаете gameFrame внутри Runnable, который не запускается до gameFrame. Поэтому gameFrame может быть нулевым в точке, которую вы вызываете gameFrame.addGameObject(myShip)

  • 1
    +1: уточнить: « может быть нулевым»; это непредсказуемо, следовательно несоответствие в полученных ошибках.
  • 1
    Совершенно верно - «может быть ноль». Но это определенно ноль тех времен, в которых вы получаете исключение NullPointerException. :) Отредактировал мой ответ - спасибо.
Показать ещё 1 комментарий
2

Проблема, вероятно, в том, что вы используете invokeLater, который назначается всякий раз, когда Swing чувствует себя так и, вероятно, происходит после gameFrame.addGameObject(myShip);

Это не происходит в отладчике, потому что это несколько условие гонки, в отладчике Swing вызывает runmethod перед gameFrame.addGameObject(myShip), потому что вы не можете щелкнуть достаточно быстро, чтобы выполнить этот оператор;)

1

Лучшим решением этой проблемы является перемещение этих операторов внутри метода run, например:

public void startNewGame() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Ship myShip = new Ship(GAME_BOARD_WIDTH / 2, GAME_BOARD_HEIGHT-1, 
                SHIP_WIDTH, SHIP_HEIGHT);
            gameFrame = new InvadersGameFrame();
            gameFrame.addGameObject(myShip); //Problem line
            gameFrame.repaint();
        }
    });
}

Таким образом, 4 оператора будут выполняться в ожидаемом порядке, и при необходимости атрибут не будет null.

0

проверьте область, в которой вы инициализировали эту переменную. т.е. фигурные скобки {} вокруг нового InvadersGameFrame(). Убедитесь, что вы используете объект после его создания.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню