Reputation: 3
I am trying to use the accelerate and brake methods from my Car class to use them in my CarView class whenever a specific button is pressed. I keep getting an error with my current code when it comes to the ActionListeners and I am not sure where to go from here. Here is my code.
import javax.swing.*; //Needed for Swing classes
import java.awt.event.*; // Needed for ActionListener Interface
public class CarView extends JFrame
{
private JPanel panel; //To reference a panel
private JLabel modelYearLable; //To reference a model year Label
private JLabel makeLable; //To reference a make Label
private JLabel speedLable; //To reference a speed Label
private JTextField modelTextField; // To reference a model yeartext field
private JTextField makeTextField; // To reference a make text field
private JTextField speedTextField; // To reference a speed text field
private JButton accelerateButton; // To reference an accelerate button
private JButton brakeButton; // To reference a brake button
private final int WINDOW_WIDTH = 310; // Window width
private final int WINDOW_HEIGHT = 100; // Window heigh
private final int carYear = Integer.parseInt(modelTextField.getText());
private final String type = makeTextField.getText();
Car vehicle = new Car(this.carYear, this.type); //Create an instance variable of the Car class!
//Constructor
public CarView()
{
//Set the window titile.
setTitle("Car referencer!");
//Set the size of the window.
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
// Specify what happens when the close button is clicked
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Build thhe panel and add it to the frame.
buildPanel();
//Add the panel to the frame's content pane.
add(panel);
//Display the window
setVisible(true);
}
//buildPanel()
//Responisibilities: Adds labels, text fields, and buttons to the panel
private void buildPanel()
{
//Create labels to display instructions
modelYearLable = new JLabel("Enter the year of your model");
makeLable = new JLabel("Enter the make of your car");
speedLable = new JLabel("Enter the current speed of your car");
//Create text fields as well
modelTextField = new JTextField(5);
makeTextField = new JTextField(5);
speedTextField = new JTextField(5);
//Create the buttons
accelerateButton = new JButton("Accelerate");
brakeButton = new JButton("Brake");
//Add an action listener to the buttons
accelerateButton.addActionListener(new AccelerateButtonListener());
brakeButton.addActionListener(new BrakeButtonListener());
//Create a JPanel object and let the panel field reference it.
panel = new JPanel();
//Add the labels,text fields, and buttons to the panel
panel.add(modelYearLable);
panel.add(makeLable);
panel.add(speedLable);
panel.add(modelTextField);
panel.add(makeTextField);
panel.add(speedTextField);
panel.add(accelerateButton);
panel.add(brakeButton);
}
//AccelerateButtonListener is an action listener private inner class for the Accelerate Button.
private class AccelerateButtonListener implements ActionListener
{
//The acitonPerformed method executes when the user clicks on the Accelerate Button
public void actionPerformed(ActionEvent e)
{
vehicle.accelerate();//Using the instance variable we made of Car earlier we can call the accelerate method from Car class.
}
}
//BrakeButtonListener is an action listener private inner class for the Brake Button.
private class BrakeButtonListener implements ActionListener
{
//The actton Performed method executes when the user clicks on the Brake Button
public void actionPerformed(ActionEvent e)
{
vehicle.brake();//Using the instance variable we made of Car earlier we can call the brake method from Car class.
}
}
//The main method creates an instance of the CarView, which causes it to display its window
public static void main(String[] args)
{
CarView cv = new CarView();
}
This is the Car Class
public class Car
{
private int yearModel; //The yearModel is an int that holds the car's modcel year
private String make; //The make references a String object that holds the make of the car.
private double speed; //The speed field is a double that hold's thhe car's current speed.
//Construtor that accepts the car's year model and make as arguments. These values should be assigned to the obkect's modelYear and make fields.
//Also assign 0 to the speed
public Car(int model, String type)
{
this.yearModel = model;
this.make = type;
speed = 0.0; //Set the speed to 0.
}
//Get and Set methods for modelYear, make and speed fields.
//getModel
//Responsibilities: gets the model of the car
public int getModel()
{
return yearModel;
}
//getMake
//Responsibilities: gets the make of the car
public String getMake()
{
return make;
}
//getSpeed
//Responsibilities: gets the speed of the car
public double getSpeedl()
{
return speed;
}
//accelerate()
//Responsibilities: Shouyld add 8 to the speed each time it is called
public void accelerate()
{
speed = speed + 8; //Everytime this method is called, add 8 to the speed each time
}
//brake()
//Responsibilities: Should subtract 6 from the speed each time it is called.
public void brake()
{
speed = speed - 6; //Everytime this method is called subtract 6 from speeed.
}
}
I am getting a NullPointerException when I run my current code but I do not know exactly how to counter this. I want to just use my Car class methods accelerate and brake in my action listeners but I do not know-how.
Any help is appreciated thank you!
Upvotes: 0
Views: 75
Reputation: 347184
So, when I run you code, I get a NullPointerException
. Taking a closer look at the code I can see two issues which would cause this...
public class CarView extends JFrame
{
//...
private JTextField modelTextField; // To reference a model yeartext field
private JTextField makeTextField; // To reference a make text field
//...
private final int carYear = Integer.parseInt(modelTextField.getText());
private final String type = makeTextField.getText();
You can't get the values from modelTextField
or makeTextField
during the initialisation phase of the class, as the variables are null
and even if they were, they'd be empty as the component hasn't even been shown on the screen yet
Instead, you need to get the values at some other point in time - remember a GUI is event driven, not procedural or linear.
There's a bunch of other things as well, including, your layouts all over the place; there's no validation; you're not reporting back the speed to the user when it changes.
I could go on for quite some time, but instead, I'm going to give you a little push
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CarView extends JFrame {
private JPanel panel; //To reference a panel
private JLabel modelYearLable; //To reference a model year Label
private JLabel makeLable; //To reference a make Label
private JLabel speedLable; //To reference a speed Label
private JTextField modelTextField; // To reference a model yeartext field
private JTextField makeTextField; // To reference a make text field
private JTextField speedTextField; // To reference a speed text field
private JButton accelerateButton; // To reference an accelerate button
private JButton brakeButton; // To reference a brake button
private JButton makeCarButton;
//private final int carYear;
//private final String type;
private Car vehicle;
//Constructor
public CarView() {
//Set the window titile.
setTitle("Car referencer!");
//Set the size of the window.
//setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
// Specify what happens when the close button is clicked
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Build thhe panel and add it to the frame.
buildPanel();
//Add the panel to the frame's content pane.
add(panel);
//Display the window
pack();
setVisible(true);
}
//buildPanel()
//Responisibilities: Adds labels, text fields, and buttons to the panel
private void buildPanel() {
//Create labels to display instructions
modelYearLable = new JLabel("Enter the year of your model");
makeLable = new JLabel("Enter the make of your car");
speedLable = new JLabel("Enter the current speed of your car");
//Create text fields as well
modelTextField = new JTextField(5);
makeTextField = new JTextField(5);
speedTextField = new JTextField(5);
//Create the buttons
accelerateButton = new JButton("Accelerate");
brakeButton = new JButton("Brake");
//Add an action listener to the buttons
accelerateButton.addActionListener(new AccelerateButtonListener());
brakeButton.addActionListener(new BrakeButtonListener());
// Don't want to use these until AFTER you've created a instance of Car
accelerateButton.setEnabled(false);
brakeButton.setEnabled(false);
speedTextField.setEnabled(false);
makeCarButton = new JButton("Make car");
makeCarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String make = makeTextField.getText();
String model = modelTextField.getText();
// Some funky validation
if (make == null || make.isBlank() || model == null || model.isBlank()) {
// Add an error message
return;
}
int year = Integer.parseInt(model);
vehicle = new Car(year, make);
makeCarButton.setEnabled(false);
accelerateButton.setEnabled(true);
brakeButton.setEnabled(true);
speedTextField.setEnabled(true);
}
});
//Create a JPanel object and let the panel field reference it.
panel = new JPanel(new GridLayout(-1, 2));
//Add the labels,text fields, and buttons to the panel
panel.add(modelYearLable);
panel.add(modelTextField);
panel.add(makeLable);
panel.add(makeTextField);
panel.add(new JPanel());
panel.add(makeCarButton);
panel.add(speedLable);
panel.add(speedTextField);
panel.add(accelerateButton);
panel.add(brakeButton);
}
//AccelerateButtonListener is an action listener private inner class for the Accelerate Button.
private class AccelerateButtonListener implements ActionListener {
//The acitonPerformed method executes when the user clicks on the Accelerate Button
public void actionPerformed(ActionEvent e) {
vehicle.accelerate();//Using the instance variable we made of Car earlier we can call the accelerate method from Car class.
speedTextField.setText(NumberFormat.getInstance().format(vehicle.speed));
}
}
//BrakeButtonListener is an action listener private inner class for the Brake Button.
private class BrakeButtonListener implements ActionListener {
//The actton Performed method executes when the user clicks on the Brake Button
public void actionPerformed(ActionEvent e) {
vehicle.brake();//Using the instance variable we made of Car earlier we can call the brake method from Car class.
speedTextField.setText(NumberFormat.getInstance().format(vehicle.speed));
}
}
//The main method creates an instance of the CarView, which causes it to display its window
public static void main(String[] args) {
CarView cv = new CarView();
}
public class Car {
private int yearModel; //The yearModel is an int that holds the car's modcel year
private String make; //The make references a String object that holds the make of the car.
private double speed; //The speed field is a double that hold's thhe car's current speed.
//Construtor that accepts the car's year model and make as arguments. These values should be assigned to the obkect's modelYear and make fields.
//Also assign 0 to the speed
public Car(int model, String type) {
this.yearModel = model;
this.make = type;
speed = 0.0; //Set the speed to 0.
}
//Get and Set methods for modelYear, make and speed fields.
//getModel
//Responsibilities: gets the model of the car
public int getModel() {
return yearModel;
}
//getMake
//Responsibilities: gets the make of the car
public String getMake() {
return make;
}
//getSpeed
//Responsibilities: gets the speed of the car
public double getSpeedl() {
return speed;
}
//accelerate()
//Responsibilities: Shouyld add 8 to the speed each time it is called
public void accelerate() {
speed = speed + 8; //Everytime this method is called, add 8 to the speed each time
}
//brake()
//Responsibilities: Should subtract 6 from the speed each time it is called.
public void brake() {
speed = speed - 6; //Everytime this method is called subtract 6 from speeed.
}
}
}
I would suggest having a look at:
It's really important that you take some time to better understand how an event driven environment works. Create some buttons which don't do anything, attach some ActionListener
s to them and use System.out.println
to print out what's going on, this will help you get your head around it
Upvotes: 1
Reputation: 115
include both class in same package so that you can create object of the first class in your second class. hope you understand !
Upvotes: 0