Search code examples
javaswingnullpointerexceptionjbutton

Java: NullPointerException thrown when JButton is clicked in the Flash Card Game


Details: It's a Flash Card game, each Card has question and answer.
QuizCard is the class of Cards having functions like getQuestion(), getAnswer(), setQuestion(), setAnswer() and two String Instances as question and answer. A parameterised constructor takes two strings, first as question and second as answer.

I saved questions and answers in a text file, where question and answer is separated by a "/". All new questions start from a new line.
E.g. -> What is the Capital of India?/New Delhi
Where is the Taj Mahal?/Agra

Rest of the code can be easily understood.

Problem: When the "nextButton" is clicked it throws a NullPointerException and doesn't change the text on the "nextButton".

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

public class QuizCardPlayer 
{

private JFrame frame;
private JTextArea display;
private boolean isAnswer = true;
private JButton nextButton;
private ArrayList<QuizCard> cardList;
private int currentCardIndex;

public static void main(String[] args)
{
    QuizCardPlayer player = new QuizCardPlayer();
    player.go();
}

public void go()
{
    frame = new JFrame("Quiz Card Player");
    display = new JTextArea(6,20);
    JPanel mainPanel = new JPanel();
    Font bigFont = new Font("serif", Font.BOLD, 24);
    display.setFont(bigFont);
    JScrollPane scroller = new JScrollPane(display);
    scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    display.setText("Lets Start!");
    JButton nextButton = new JButton("Show Question");

    mainPanel.add(scroller);
    mainPanel.add(nextButton);
    nextButton.addActionListener(new NextButtonListener());

    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("File");
    JMenuItem loadMenuItem = new JMenuItem("Load card set");
    loadMenuItem.addActionListener(new LoadMenuListener());
    fileMenu.add(loadMenuItem);
    menuBar.add(fileMenu);
    frame.setJMenuBar(menuBar);
    frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
    frame.setVisible(true);
    frame.setSize(300,300);
}

public class NextButtonListener implements ActionListener
{
    public void actionPerformed(ActionEvent event)
    {
        System.out.print("Called!!");
       if(isAnswer)
       {
            nextButton.setText("Show Answer");
            if( currentCardIndex < cardList.size() )
            {
                display.setText(cardList.get(currentCardIndex).getQuestion());
                isAnswer = false;
            }
            else
            {
                display.setText("That was last Card.");
                nextButton.setEnabled(false);
            }
        }
        else
        {
            nextButton.setText("Next Card");
            display.setText(cardList.get(currentCardIndex).getAnswer());
            isAnswer = true;
            currentCardIndex++;
        }
    }
}

public class LoadMenuListener implements ActionListener
{
    public void actionPerformed(ActionEvent ev)
    {
        JFileChooser openFile = new JFileChooser();
        openFile.showOpenDialog(frame);
        loadFile(openFile.getSelectedFile());
    }
}

public void loadFile(File loadFile)
{
    try
    {
        BufferedReader reader = new BufferedReader(new FileReader(loadFile));
        String line="";
        cardList = new ArrayList<QuizCard>();
        while( (line = reader.readLine()) != null )
        {
            String[] result = line.split("/");
            QuizCard card = new QuizCard(result[0] , result[1]);
            cardList.add(card);
            currentCardIndex=0;
        }
        reader.close();
    }
    catch(IOException ex)
    {
        ex.printStackTrace();
    }
}
}

I am novice in Java having a experience of just one month, any suggestion is most welcome.


Solution

  • You are creating nextButton as an instance variable of class QuizCardPlayer, but inside go() method, you initializing the local variable nextButton and adding Listener to this local copy, and adding this local copy of nextButton to the mainPanel (which is visible on the VIEW ).

    Though the instance variable remains null, as you never did assigned it to anythingy, and you trying to access this null variable inside NextButtonListener class, as follows:

    nextButton.setText("Show Answer");
    

    EDIT 1:

    Simply replace this line inside go () method:

    JButton nextButton = new JButton("Show Question");
    

    to

    nextButton = new JButton("Show Question");
    

    This will work :-)