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
。