Search code examples
staticnullpointerexceptionjlabelsettext

Java JLabel setText Method Not Working


I've been trying to figure out what the problem is, but i cannot figure it out. I call a method from a class using w.setCandyAmountLabelText(numberofcandies); However it does not work. I am trying to change the text of a jlabel which is in another class. Here is the error and code. error

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at CandyWindow.setCandyAmountLabelText(CandyWindow.java:111)
at Counter$1.actionPerformed(Counter.java:32)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

mainclass

public class CandyMain {

public static void main(String[] args) {
    CandyWindow window = new CandyWindow("Candy Box");
    window.init();

}

CandyWindow Class

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class CandyWindow extends JFrame {

public JPanel mainpanel;
public JLabel candyamountlabel;
public JButton eatcandies;
public JLabel candieseaten;
public boolean candiesmorethan10 = false;
public JButton throwcandies;


Counter counter;

CandyWindow(String title) {

    super(title);

    this.setVisible(true);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

}

CandyWindow() {

}

public void init() {

    counter = new Counter();

    // initialized label

    candyamountlabel = new JLabel("You Have 0 Candies!");
    eatcandies = new JButton("Eat All The Candies!");
    candieseaten = new JLabel("You Have Eaten 0 Candies!");
    throwcandies = new JButton("Throw Candies On Ground!");


    //sets visibilty to false
    candieseaten.setVisible(false);
    throwcandies.setVisible(false);




    // add action listener
    eatcandies.addActionListener(eatcandieslistener);

    // makes panel
    mainpanel = new JPanel();




    // adds label to panel
    mainpanel.add(candyamountlabel);
    mainpanel.add(eatcandies);
    mainpanel.add(candieseaten);
    mainpanel.add(throwcandies);

    // adds panel to jframe
    this.add(mainpanel);
    this.setSize(1600, 850);


    counter.startTimer();


}

ActionListener eatcandieslistener = new ActionListener(){

    @Override
    public void actionPerformed(ActionEvent e) {

        counter.setCandiesEaten(counter.getNumberOfCandies() + counter.getCandiesEaten());
        counter.eatcandies();
        candyamountlabel.setText("You Have 0 Candies!");
        candieseaten.setText("You Have Eaten " + counter.getCandiesEaten() + " Candies!");
        candieseaten.setVisible(true);

    }



};


public void setThrowCandiesVisible(int y){

    if(y == 1){

        candiesmorethan10 = true;

    }
    if(candiesmorethan10){

        throwcandies.setVisible(true);
        throwcandies.repaint();

    }

}

public void setCandyAmountLabelText(long g){

    candyamountlabel.setText("You Have " + g + " Candies!");
    candyamountlabel.repaint();


}

     }

Counter class

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

public class Counter {

long numberofcandies = 0;
long candiespersecond = 0;
long candieseaten = 0;

CandyWindow w = new CandyWindow();

void startTimer() {

    Timer t = new Timer(1000, timercount);
    t.setRepeats(true);
    t.start();

}

ActionListener timercount = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {

        // setscandiespersecond to one
        setCandiesPerSecond(1);

        //increases candies
        numberofcandies = candiespersecond + numberofcandies;

        //changes numberofcandieslabel
        w.setCandyAmountLabelText(numberofcandies); 


        //if candies are more than 10 set throw on ground visible
        int x = 0;
        if(numberofcandies > 9){
            x = 1;
            w.setThrowCandiesVisible(x);

        }


        //System.out.println("Number of Candies" + getNumberOfCandies()); //test print works
        //System.out.println("candies eaten" + getCandiesEaten()); //test print works


    }

};



public long getNumberOfCandies() {

    return numberofcandies;

}

public long getCandiesPerSecond() {

    return candiespersecond;
}

public void setCandiesPerSecond(long g) {

    candiespersecond = g;

}

public void eatcandies(){

    numberofcandies = 0;

}

public long getCandiesEaten(){

    return candieseaten;

}

public void setCandiesEaten(long p){

    candieseaten = p;

}


}

Solution

  • Your CandyWindow creates a new Counter object in init() - But this Counter object makes a new CandyWindow when it is created: CandyWindow w = new CandyWindow();. So the Counter doesn't reference to the CandyWindow which created the Counter - which I think you meant to do. Try passing the CandyWindow along with Counter like:

    counter = new Counter(this);
    

    and creating a constructor for Counter which takes a CandyWindow, and sets w to this reference instead:

    public Counter(CandyWindow w) {
       this.w = w;
    }
    

    The NullPointerException is caused in this case, because the Counter object has a reference to a new CandyWindow, of which the init() function is never called - hence the line: 'w.setCandyAmountLabelText(numberofcandies);' in 'onActionPerformed()' would fail for the CandyAmountLabelText of this new CandyWindow is never initialised.