JLabel数组setIcon()导致空指针异常

时间:2014-08-20 17:07:42

标签: java swing nullpointerexception jlabel

我正在写一个纸牌游戏,我需要用用户选择的牌替换现有牌。 首先,我在面板中显示了14张卡片,这是一个在我的GUI类中声明和初始化的JLabel数组:

public JLabel[] cardsLabel;  //as class variable
cardsLabel = new JLabel[14];  //inside constructor

并且卡片显示在面板中,下面的代码完全正常工作。

for (int index=0; index<cardsLabel.length; index++)
        {
            cardsLabel[index] = new JLabel();
            cardsLabel[index].setIcon(backOfCard);
            cardsContainer1.add(cardsLabel[index]);
            game.add(cardsContainer1, BorderLayout.EAST);       //add cards to east of game container
        }

我有另一个游戏类,我将用户选择索引传递给我的GUI类中的方法

public void cardFlip(int c1, int c2) {

        ImageIcon cardOne = new ImageIcon(resizeImage(new ImageIcon(table.getCard(c1).getImg()),100,120));
        ImageIcon cardTwo = new ImageIcon(resizeImage(new ImageIcon(table.getCard(c2).getImg()),100,120));

        cardsLabel[c1].setIcon(cardOne);  //this is where I'm getting Null Pointer Exception error
        cardsLabel[c2].setIcon(cardTwo);
}

我使用JLabel数组得到Null Point Error。 这是前几行错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at game.GameTableFrame.cardFlip(GameTableFrame.java:162)
at game.FishingGame.gamePlay(FishingGame.java:80)
at game.GameTableFrame.<init>(GameTableFrame.java:152)
at game.GameModule$1.actionPerformed(GameModule.java:95)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)

所以我一直在阅读其他帖子,这可能是由于数组未正确初始化但我已经这样做了所以我无法弄清楚导致此错误的原因。 如果有任何善良的灵魂可以启发我,我将不胜感激。

提前致谢。

更新

游戏课

public FishingGame(Player p) {

        player = p;
        dealer = new Dealer();
        table = new Table();
        gameTable = new GameTableFrame();     //this is my GUI class where cardFlip is 


        players = new ArrayList<PlayerInterface>();
        players.add(player);
        players.add(dealer);
    }

public void gamePlay() {


        int turn = 0;
        PlayerInterface currentPlayer;

        while (table.hasMoreCard()) { // play the game while the table has cards

            currentPlayer = players.get(turn);
            System.out.println(currentPlayer.getLoginName() + "'s turn");


            // prompt for card numbers
            int[] cardsIndex = currentPlayer.getCardsIndex();

            // show cards on table
            table.showCards(cardsIndex[0], cardsIndex[1]);

            gameTable.cardFlip(cardsIndex[0],cardsIndex[1]);  //this is how I call cardFlip

            // more lines of code below for game
            }

更新更新:

这是cardsLabel初始化的地方。

    public GameTableFrame(Dealer dealer, Player player)
        {

            fg = new FishingGame(player);
            playersData = new PlayersData();
            dealer = new Dealer();
            card = new Card();

            cardsLabel = new JLabel[14];
for (int index=0; index<cardsLabel.length; index++)
        {
            cardsLabel[index] = new JLabel();
            cardsLabel[index].setIcon(backOfCard);
            cardsContainer1.add(cardsLabel[index]);
            game.add(cardsContainer1, BorderLayout.EAST);       //add cards to east of game container
        }

    }

更新

使用参数化构造函数,我的程序将在登录时挂起。 这是我的计划流程:

  1. 登录(类:GameModule)
  2. 如果成功,将显示带有14张牌的GameFrame(类:GameModuleFrame)
  3. 提示用户输入索引号(Class:FishingGame)并发送到GameModuleFrame下的CardFlip
  4. 替换用户选择的卡(类:GameModuleFrame)**这是我遇到错误的地方但是当我更改为参数化构造函数时,我的程序将挂在第1项。
  5. 更新

    更改为

    public FishingGame(Player p) {
    
            player = p;
            dealer = new Dealer();
            table = new Table();
            gameTable = new GameTableFrame(dealer,player, this);
    }
    

     public GameTableFrame(Dealer dealer, Player player, FishingGame fg)
        {
    
            fg = new FishingGame(player);
            playersData = new PlayersData();
    
    // more codes here
    }
    

    我怎样才能改变GameModule课程?

    public GameModule() {
            playersData = new PlayersData();    
            dealer = new Dealer();
            login = new JPanel();
            loginFrame = new JFrame();
        }
    

    //目前这就是我从GameModule类中调用GameTableFrame的方法

    gameTableFrame = new GameTableFrame(dealer, player);
    

3 个答案:

答案 0 :(得分:2)

你必须改变:

gameTable = new GameTableFrame();   

有关:

gameTable = new GameTableFrame(dealer, player);

否则,您不会初始化卡片。

更新

因为您正在交叉引用对象而冻结。因此,当您创建GameTableFrame时,它会创建一个FishingGame,它会创建另一个GameTableFrame等。您无法执行此操作。如果你需要引用FishingGame,你应该将对象传递给GameTableFrame,如:

new GameTableFrame(dealer, player, this)

并改变:

public GameTableFrame(Dealer dealer, Player player)

有关:

public GameTableFrame(Dealer dealer, Player player, FishingGame fg)

答案 1 :(得分:1)

你正在调用错误的构造函数。

public GameTableFrame()

初始化在参数化构造函数中完成。

public GameTableFrame(Dealer dealer, Player player)

使用参数化的。

答案 2 :(得分:0)

如果索引错误,将抛出ArrayIndexOutOfBounds。我想cardsLabel数组在代码中的其他地方被更新为null,这就是为什么在访问它时抛出NullPointerException的原因。

你能发布你的GUI类完整代码吗?