2014-04-21 115 views
1

我有一些類創建一個Ship(類Ship擴展GameObject)並嘗試將它添加到gameBoard。
要做到這一點,它告訴gameFrame添加的對象如下:java空指針異常傳遞對象

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); 
    } 
} 

現在我的問題是我收到一個空指針異常,當我gameFrame.addGameObject(myShip);
棘手的是當我ru n通過調試器我根本沒有收到NPE(但我的對象列表仍然顯示爲空)。
另外,我可以按照每個這些仍然看到myShip,所以我只是引用我的GameObject(船)錯了嗎?
我的addGameObject參數應該更抽象嗎?

+1

你有一個stacktrace發佈? –

+0

您的堆棧跟蹤是調試此類事件時最有價值的信息。你爲什麼忘記發佈它? –

+0

因爲我太新鮮了,甚至不知道如何獲得堆棧跟蹤。我會谷歌並返回。 – user1695505

回答

4

問題是您在Runnable的內部分配了gameFrame,直到後來才運行。因此gameFrame可能在您要撥打的位置爲空gameFrame.addGameObject(myShip)

+1

+1:澄清:「* may be * null」;這是不可預測的,因此收到的錯誤不一致。 –

+1

非常真實 - 「可能爲空」。但是在你遇到NullPointerException的時候肯定是空的。 :)編輯我的答案 - 謝謝。 –

+0

將在3分鐘內接受答案。謝謝,非常有見識!我正在尋找錯誤的對象,甚至花了很長時間纔開始尋找框架。 – user1695505

0

檢查您初始化該變量的範圍。即圍繞新InvadersGameFrame()的大括號{}。 確保您使用的對象創建後

2

可能是你使用的invokeLater,即每當鞦韆感覺它也可能安排的問題後 gameFrame.addGameObject(myShip)發生;

,這並不在調試器中發生,因爲它是有點競爭條件,在調試器的Swing調用runmethod之前gameFrame.addGameObject(myShip),因爲你不能點擊速度不夠快,preemt該語句;)

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在需要的時候。