Java的新功能,我正在尝试使用GUI进行第一个项目。我有一个GameConsole类,其中包含gamePlay()和userTurn()。我有一个ButtonListener类,该类使用一个调用userTurn()的actionListener构造按钮。但是,每次按下按钮,我都会得到一个NullPointerException。为什么会发生这种情况,我该怎么解决?

相关代码:

public static final void main (String[] args){
    GameConsole game = new GameConsole();
    game.gamePlay();
}

public class GameConsole {
    public Player user;
    public Player dealer;
    public Deck playingDeck;
    ValidateInput validate = new ValidateInput();

public void gamePlay(){
    //get info from user
    user.addToHand(playingDeck.getTopCard());
    dealer.addToHand(playingDeck.getTopCard());
    user.addToHand(playingDeck.getTopCard());
    dealer.addToHand(playingDeck.getTopCard());

    userTurn();
}

public void userTurn(){
    boolean turn = true;
    do{   //the code breaks at this point. On the first round of gameplay I get the exception pasted
          //below. The second round (after the button is pressed) I get an
          //Exception in thread "AWT-EventQueue-0      bringing me back here
        JOptionPane.showMessageDialog(null, "The cards you were dealt are: \n" + user.printHand());

        if(user.sumOfHand() == 21){  //no need to continue if user has 21
            System.out.println("You win this round.");
            break;
        } else if (user.sumOfHand() > 21){
            System.out.println("You have busted. You lose this round.");
            break;
        }


        String HSInput = null;
        for(int x = 0; x < 1;){
        HSInput = JOptionPane.showInputDialog("\nThe dealer is showing a " + dealer.getTopCard()
                + "\nYou are currently at " + user.sumOfHand()
                + "\n\nWhat would you like to do?\nHit (H) or Stay (S)?");
        if(validate.containDesiredString(HSInput, "HhSs")) //only accept h and s either caps
            x++;
        }


        if(HSInput.equalsIgnoreCase("H")){  //if the user wants to stay
            user.addToHand(playingDeck.getTopCard()); //deal new card then repeat loop
        }
        else {
            turn = false;
            }
    } while (turn == true);
}


还有ButtonListener类...

public class ButtonListener implements ActionListener {

    JButton newRoundButton;

    public ButtonListener(JPanel endGamePanel){

        newRoundButton = new JButton("Start another round");
        newRoundButton.setPreferredSize(new Dimension(150, 50));
        endGamePanel.add(newRoundButton);
        newRoundButton.addActionListener(this);

    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == newRoundButton){
            System.out.println("Hi there for a new round");
                     //I know that this method is entered into because this line will print
            GameConsole game = new GameConsole();
            game.userTurn();
        }
    }


我极度迷失了自己,过去两天一直在兜圈子。现在,程序甚至都不会输入userTurn()。我不知道我做了什么,因为几个小时前那不是问题。无论哪种方式,我的最终问题是我无法让ButtonListener调用userTurn()类。为什么现在要为userTurn()获取NullPointerException?如何使ActionListener在不提供NullPointerException的情况下调用userTurn()?

-绝望的失落...感谢您的帮助!

编辑:堆栈跟踪
线程“主” JAV中的异常

a.lang.NullPointerException
    at blackjackControls.GameConsole.userTurn(GameConsole.java:180)
    at blackjackControls.GameConsole.gamePlay(GameConsole.java:119)
    at blackjackControls.Main.main(Main.java:7)


由于它不再进入userTurn()中,因此无法为此发布跟踪。它确实指出这是AWT中的一个线程

ButtonListener类已与现有ResultPane类组合在一起。完整的代码是:

public class ResultPanel extends JFrame {

    JFrame frame = new JFrame("Blackjack Game");
    JPanel endGamePanel = new JPanel();
    ImageIcon image;
    JLabel lbl;
    JButton newRoundButton;
    JButton endButton;

    public ResultPanel(){

        frame.setSize(800, 600);
        frame.getContentPane().add(endGamePanel);   //add the panel to the frame
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton newRoundButton= new JButton("Start another round");
        newRoundButton.setPreferredSize(new Dimension(150, 50));
//      newRoundButton.addActionListener();
        newRoundButton.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {

                System.out.println("Hi there for a new round");
                GameConsole game = new GameConsole();
                game.userTurn();
            }
        });


        frame.setVisible(true);
    }

    public void winGame(){
        image = new ImageIcon(getClass().getResource("win.jpg"));
        lbl = new JLabel (image);
        endGamePanel.add(lbl);

        frame.setVisible(true);
    }

最佳答案

据我所知,您在主游戏中创建了一个新的GameConsole对象,因此我认为这是整个游戏进行的对象。如果是这种情况,为什么您的按钮创建一个新的GameConsole对象?我假设您正在获取NullPointerException,因为您的按钮在尚未具有User对象的新userTurn()对象上调用了GameConsole方法,因此例如user.sumOfHand()会引发异常。

您的按钮应该在您在主对象中创建的userTurn对象上调用GameConsole方法,而不是在新对象上。

代码建议:

JButton newRoundButton= new JButton("Start another round");
newRoundButton.setPreferedSize(new Dimension(150, 50));
newRoundButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Hi there for a new round");
        game.userTurn();
    }
});
endGamePanel.add(newRoundButton);


这是假设任何构建面板的类都知道您的GameConsole对象。如果此类是GameConsole对象本身,则删除game.如果在您的GameConsole对象中创建了该类的对象,只需将GameConsole对象传递给该类中带有参数GameConsole game的那个类构造函数,并在需要时使其成为该类中的一个字段。要从该对象传递GameConsole对象,请传递this

10-04 19:10