Reputation: 3219
Making a very simple java GUI app (card game War) where the GUI elements are showing up, but they are null when referenced later on. Specifically, I click the Next Round Button and a Null Pointer Exception is thrown when the yourCardLabel is referenced from the nextRound()
method. Why is this?
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();
}
Upvotes: 1
Views: 164
Reputation: 70357
Inside your actionPerformed
for the new round button...
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
NewRoundListener listener = new War();
listener.newRound();
}
});
You create a new War
instance but never set any of its instance variables (since you don't call initialize
), so it has a bunch of null
fields. Understandably, you get a null pointer exception when trying to work with it.
I think you may have intended to work with the existing War
instance rather than create a new one. Fortunately, you're inside the current War
instance, so you can access it from where you are. Consider
NewRoundListener listener = War.this;
That will give you the current instance, rather than making a new one with null
fields.
Upvotes: 3