制作一个非常简单的Java GUI应用程序(纸牌游戏War),其中GUI元素显示,但稍后引用时它们为null。具体来说,我单击Next Round按钮,当从nextRound()
方法引用yourCardLabel时,抛出Null Pointer Exception。这是为什么?
Main.java
public class Main {
public static void main(String[] args) {
War war = new War();
war.initialize();
}
}
War.java
public class War implements NewRoundListener {
public War() {}
private JFrame frame;
private JLabel label;
private JLabel winnerLabel;
private JLabel yourCardLabel;
private JLabel opponentCardLabel;
/**
* Initialize the contents of the frame.
*/
public void initialize() {
System.out.println("Initializing . . .");
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
label = new JLabel("War");
label.setFont(new Font("Times New Roman", Font.ITALIC, 20));
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setBounds(192, 38, 46, 14);
frame.getContentPane().add(label);
JLabel lblYourCard = new JLabel("Your card");
lblYourCard.setBounds(100, 84, 77, 14);
frame.getContentPane().add(lblYourCard);
JLabel lblOpponentsCard = new JLabel("Opponent's card");
lblOpponentsCard.setBounds(279, 84, 108, 14);
frame.getContentPane().add(lblOpponentsCard);
winnerLabel = new JLabel("No winner");
winnerLabel.setBounds(187, 64, 89, 14);
frame.getContentPane().add(winnerLabel);
yourCardLabel = new JLabel("0");
yourCardLabel.setFont(new Font("Tahoma", Font.PLAIN, 30));
yourCardLabel.setHorizontalAlignment(SwingConstants.CENTER);
yourCardLabel.setBounds(100, 133, 46, 42);
frame.getContentPane().add(yourCardLabel);
opponentCardLabel = new JLabel("0");
opponentCardLabel.setFont(new Font("Tahoma", Font.PLAIN, 30));
opponentCardLabel.setHorizontalAlignment(SwingConstants.CENTER);
opponentCardLabel.setBounds(299, 133, 46, 55);
frame.getContentPane().add(opponentCardLabel);
JButton btnNewButton = new JButton("New Round");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
NewRoundListener listener = new War();
listener.newRound();
}
});
btnNewButton.setBounds(177, 203, 112, 23);
frame.getContentPane().add(btnNewButton);
frame.setVisible(true);
}
@Override
public void newRound() {
int yourCard = getRandomCard();
int opponentCard = getRandomCard();
String yourCardText = textForCardInt(yourCard);
String opponentCardText = textForCardInt(opponentCard);
System.out.println(yourCardText);
if (yourCardLabel != null && opponentCardLabel != null) {
yourCardLabel.setText(yourCardText);
opponentCardLabel.setText(opponentCardText);
} else { // This executes, indicating both are null
System.out.println(yourCardLabel);
System.out.println(opponentCardLabel);
}
}
public int getRandomCard() {
Random r = new Random();
return r.nextInt(13) + 1;
}
public String textForCardInt(int cardNum) {
if (cardNum == 1) {
return "Ace";
} else if (cardNum > 1 && cardNum < 11) {
return "" + cardNum;
} else if (cardNum == 12) {
return "Jack";
} else if (cardNum == 13) {
return "Queen";
} else if (cardNum == 14) {
return "King";
} else {
return "Cannot Identify Card";
}
}
}
NewRoundListener.java
public interface NewRoundListener {
public void newRound();
}
答案 0 :(得分:3)
在actionPerformed
的新圆形按钮内...
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
NewRoundListener listener = new War();
listener.newRound();
}
});
您创建了一个新的War
实例,但从未设置任何实例变量(因为您不会调用initialize
),因此它有一堆null
个字段。可以理解的是,在尝试使用它时会出现空指针异常。
我认为您可能打算使用现有的War
实例,而不是创建一个新实例。幸运的是,您已进入当前War
实例,因此您可以从您所在的位置访问它。考虑
NewRoundListener listener = War.this;
这将为您提供当前实例,而不是使用null
字段创建新实例。