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;
}
}
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.