non-static variable timer cannot be referenced from a static context ERROR HELP!
Hi, I'm trying to program my final project in a class. I was doing fine, and I have it displaying the JFrame fine with all the buttons and the moving cars, but as soon as I try to add actionlisterners to the buttons I've created, I start getting the error messages: non-static variable timer cannot be referenced from a static context. I have no clue how to fix this, and I don't know what I've done wrong, as I've been cross referencing with programs already created in our power points and notes. Can anyone offer me some advice? Below is the code I've written...it starts off with tons of lines of creatings and adding buttons, but the car class, main method, and the action listeners i've attempted to add are all farther down. Any help would be greatly appreciated!
Code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FinalProject extends JFrame {
public FinalProject() {
//Create JButtons to affect the movement and sounds with the car
JButton jbtSuspend1 = new JButton("Suspend Car 1");
JButton jbtResume1 = new JButton("Resume Car 1");
JButton jbtReverse1 = new JButton("Reverse Car 1");
JButton jbtRadio1 = new JButton("Radio for Car 1");
JButton jbtHorn1 = new JButton("Get Angry Car 1");
JButton jbtSuspend2 = new JButton("Suspend Car 2");
JButton jbtResume2 = new JButton("Resume Car 2");
JButton jbtReverse2 = new JButton("Reverse Car 2");
JButton jbtRadio2 = new JButton("Radio for Car 2");
JButton jbtHorn2 = new JButton("Get Angry Car 2");
//Create Radio Buttons for Color
JRadioButton jrbRed1 = new JRadioButton("Red");
JRadioButton jrbOrange1 = new JRadioButton("Orange");
JRadioButton jrbYellow1 = new JRadioButton("Yellow");
JRadioButton jrbGreen1 = new JRadioButton("Green");
JRadioButton jrbBlue1 = new JRadioButton("Blue");
JRadioButton jrbPurple1 = new JRadioButton("Purple");
JRadioButton jrbPink1 = new JRadioButton("Pink");
JRadioButton jrbRed2 = new JRadioButton("Red");
JRadioButton jrbOrange2 = new JRadioButton("Orange");
JRadioButton jrbYellow2 = new JRadioButton("Yellow");
JRadioButton jrbGreen2 = new JRadioButton("Green");
JRadioButton jrbBlue2 = new JRadioButton("Blue");
JRadioButton jrbPurple2 = new JRadioButton("Purple");
JRadioButton jrbPink2 = new JRadioButton("Pink");
//Create a slider to affect speed of movement
JSlider jslDelay1 = new JSlider(JSlider.HORIZONTAL);
JSlider jslDelay2 = new JSlider(JSlider.HORIZONTAL);
//Create a panel to house the JButtons
JPanel panelsouth = new JPanel(new GridLayout(1,2));
panelsouth.add(jbtSuspend1);
panelsouth.add(jbtResume1);
panelsouth.add(jbtReverse1);
panelsouth.add(jbtRadio1);
panelsouth.add(jbtHorn1);
panelsouth.add(jbtSuspend2);
panelsouth.add(jbtResume2);
panelsouth.add(jbtReverse2);
panelsouth.add(jbtRadio2);
panelsouth.add(jbtHorn2);
//Create a panel to house the slider
JPanel panelnorth = new JPanel();
panelnorth.add(jslDelay1);
panelnorth.add(jslDelay2);
//Create a panel for the 2 cars
JPanel panelcenter = new JPanel(new GridLayout(2,1));
panelcenter.add(new MovingCar(), BorderLayout.CENTER);
panelcenter.add(new MovingCar(), BorderLayout.CENTER);
JPanel paneleast = new JPanel(new GridLayout(8,1));
paneleast.add(new JLabel("Car 1 Color"));
paneleast.add(jrbRed1);
paneleast.add(jrbOrange1);
paneleast.add(jrbYellow1);
paneleast.add(jrbGreen1);
paneleast.add(jrbBlue1);
paneleast.add(jrbPurple1);
paneleast.add(jrbPink1);
JPanel panelwest = new JPanel(new GridLayout(8,1));
panelwest.add(new JLabel("Car 2 Color"));
panelwest.add(jrbRed2);
panelwest.add(jrbOrange2);
panelwest.add(jrbYellow2);
panelwest.add(jrbGreen2);
panelwest.add(jrbBlue2);
panelwest.add(jrbPurple2);
panelwest.add(jrbPink2);
//Add the panels to the Frame
add(panelsouth, BorderLayout.SOUTH);
add(panelcenter, BorderLayout.CENTER);
add(panelnorth, BorderLayout.NORTH);
add(paneleast, BorderLayout.EAST);
add(panelwest, BorderLayout.WEST);
jbtSuspend1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MovingCar.suspend();
}
});
jbtResume1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MovingCar.resume();
}
});
jslDelay1.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
MovingCar.setDelay(jslDelay1.getMaximum() - e.getValue());
}
});
}
/** Main method */
public static void main(String[] args) {
FinalProject frame = new FinalProject();
frame.setTitle("Moving Cars");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 500);
frame.setVisible(true);
} }
// Inner class: Displaying a moving message
class MovingCar extends JPanel {
private Color c = Color.red;
private int xCoordinate = 0;
private int yCoordinate = 20;
private int delay = 100;
private Timer timer = new Timer(delay, new TimerListener());
private int r = 1;
public MovingCar() {
// Start timer for animation
timer.start();
}
class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(c);
if (xCoordinate > getWidth()) {
xCoordinate = -20;
}
xCoordinate += 5*r;
int xPoints[] = {xCoordinate+0, xCoordinate+0, xCoordinate+20,xCoordinate+20, xCoordinate+50, xCoordinate+50, xCoordinate+70, xCoordinate+70};
int yPoints[] = {55, 35, 35, 20, 20, 35, 35, 55};
g.fillPolygon(xPoints, yPoints, 8);
g.setColor(Color.gray);
g.fillOval(xCoordinate+15,55,10,10);
g.fillOval(xCoordinate+55,55,10,10);
}
public void setCarColor(Color color) {
c=color;
}
public void suspend() {
timer.stop(); // Suspend timer
}
public void resume() {
timer.start(); // Resume timer
}
public void setDelay(int delay) {
this.delay = delay;
timer.setDelay(delay);
}
public void reverse(int r) {
r=r*-1; //Reverse Direction
}
}
Re: non-static variable timer cannot be referenced from a static context ERROR HELP!
Hi spunkyk014, welcome to the forums.
I've added code tags to your post. The idea is that you put [code] at the start of the code and [/code] at the end so that the forum software will render the code in a readable way. (It's also good to use spaces for indents and be meticulous about formatting because people will want to read the code "at a lance").
Also it's a good idea to copy and post the exact compiler message and say which line it is referring to. (Compiling at the command line is a good way to get this information.)
---
Anyway, your problem...
Code :
jbtSuspend1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MovingCar.suspend();
}
});
You are calling suspend() as if it were a static method, but it's not. It's a method that belongs to a specific instance of MovingCar. In other words you have to create an actual instance of MovingCar somewhere, and call its suspend() method with
Code :
MovingCar car = new MovingCar();
// later, somewhere else
car.suspend();
By the way, MovingCar is not an inner class. It's just another class defined within the same java source file. It would be better put in its own file.
Re: non-static variable timer cannot be referenced from a static context ERROR HELP!
Thanks! That's the first time all semester that I have finally understood what that error means. Awesome. However, now I'm running into another problem. I changed both the general movingcars() to car1 and car2, so they've been declared, but now I'm getting an error message as follows:
FinalProject.java:96: error: local variable car1 is accessed from within inner class; needs to be declared final
car1.suspend();
^
FinalProject.java:101: error: local variable car1 is accessed from within inner class; needs to be declared final
car1.resume();
I don't want to declare them final, because I need to be able to change the color of each object. I can't put anything in another file because my professor wants everything turned in in one file, so that's why everything is together.
Re: non-static variable timer cannot be referenced from a static context ERROR HELP!
Declaring a variable as final means that the variable's value can not be changed (ie it can not be set to another object). The object that the variable refers to can be changed.
Re: non-static variable timer cannot be referenced from a static context ERROR HELP!
Norm is right. My previous snippet could be amended to reflect common usage as
Code :
final MovingCar car = new MovingCar();
// later, in the same method
car.suspend();
The inner class it is talking about, btw, is the anonymous inner class that implements ActionListener. The compiler is just demanding a guarantee that you are not going to go changing the value of car so that the action listener instance knows which car's suspend() to call. It's an awkwardness of Java basically. You have no such restrictions in JavaScript, for instance, where *the same* variable is accessed by both the method and the inner call of suspend() and this can result in delightfully obscure behaviour that Java attempts to avoid.
The preceding paragraph is unimportant, what is important is Norm's point that although car1 is final (ie the variable is final: it always points to the same car), the car it points to can change state eg its colour can change.