Ryan Cocuzzo
Ryan Cocuzzo

Reputation: 3219

UI Elements showing up as null

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

Answers (1)

Silvio Mayolo
Silvio Mayolo

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

Related Questions