英文:
How do I call a method from another class to use in my ActionListener class
问题
import javax.swing.*;
import java.awt.event.*;
public class CarView extends JFrame {
// ... (other member variables)
// ... (constructor and other methods)
//AccelerateButtonListener is an action listener private inner class for the Accelerate Button.
private class AccelerateButtonListener implements ActionListener {
//The actionPerformed 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(String.valueOf(vehicle.getSpeed())); // Update speedTextField with the new speed value
}
}
//BrakeButtonListener is an action listener private inner class for the Brake Button.
private class BrakeButtonListener implements ActionListener {
//The actionPerformed 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(String.valueOf(vehicle.getSpeed())); // Update speedTextField with the new speed value
}
}
// ... (rest of the code)
}
Note: I've added lines to update the speedTextField
with the new speed value after calling the accelerate()
and brake()
methods to ensure the displayed speed is updated correctly.
英文:
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.
}
}
Error
> 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!
答案1
得分: 1
当我运行你的代码时,我收到一个NullPointerException
。仔细查看代码后,我可以看到两个可能导致此问题的问题...
public class CarView extends JFrame
{
//...
private JTextField modelTextField; // 引用模型年份文本字段
private JTextField makeTextField; // 引用制造商文本字段
//...
private final int carYear = Integer.parseInt(modelTextField.getText());
private final String type = makeTextField.getText();
在类的初始化阶段,你不能从modelTextField
或makeTextField
获取值,因为这些变量为null
,即使它们不是null
,它们也是空的,因为组件还没有显示在屏幕上。
相反,你需要在其他时间点获取值 - 请记住GUI是事件驱动的,而不是过程化或线性的。
还有很多其他问题,包括布局问题,没有验证,当速度发生变化时没有向用户报告。
我可以继续讲很长时间,但我要给你一点启发:
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; // 引用面板
private JLabel modelYearLabel; // 引用车型年份标签
private JLabel makeLabel; // 引用制造商标签
private JLabel speedLabel; // 引用速度标签
private JTextField modelTextField; // 引用车型年份文本字段
private JTextField makeTextField; // 引用制造商文本字段
private JTextField speedTextField; // 引用速度文本字段
private JButton accelerateButton; // 引用加速按钮
private JButton brakeButton; // 引用刹车按钮
private JButton makeCarButton;
private Car vehicle;
// 构造函数
public CarView() {
// 设置窗口标题。
setTitle("Car referencer!");
// 设置窗口大小。
//setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
// 指定当单击关闭按钮时发生的情况
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 构建面板并将其添加到窗体中。
buildPanel();
// 将面板添加到窗体的内容面板。
add(panel);
// 显示窗口
pack();
setVisible(true);
}
// buildPanel()
// 负责:向面板添加标签、文本字段和按钮
private void buildPanel() {
// 创建显示说明的标签
modelYearLabel = new JLabel("Enter the year of your model");
makeLabel = new JLabel("Enter the make of your car");
speedLabel = new JLabel("Enter the current speed of your car");
// 创建文本字段
modelTextField = new JTextField(5);
makeTextField = new JTextField(5);
speedTextField = new JTextField(5);
// 创建按钮
accelerateButton = new JButton("Accelerate");
brakeButton = new JButton("Brake");
// 为按钮添加动作侦听器
accelerateButton.addActionListener(new AccelerateButtonListener());
brakeButton.addActionListener(new BrakeButtonListener());
// 不要在创建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();
// 一些奇怪的验证
if (make == null || make.isBlank() || model == null || model.isBlank()) {
// 添加错误消息
return;
}
int year = Integer.parseInt(model);
vehicle = new Car(year, make);
makeCarButton.setEnabled(false);
accelerateButton.setEnabled(true);
brakeButton.setEnabled(true);
speedTextField.setEnabled(true);
}
});
// 创建一个带有GridLayout的JPanel对象,并使面板字段引用它。
panel = new JPanel(new GridLayout(-1, 2));
// 将标签、文本字段和按钮添加到面板
panel.add(modelYearLabel);
panel.add(modelTextField);
panel.add(makeLabel);
panel.add(makeTextField);
panel.add(new JPanel());
panel.add(makeCarButton);
panel.add(speedLabel);
panel.add(speedTextField);
panel.add(accelerateButton);
panel.add(brakeButton);
}
// AccelerateButtonListener是用于“加速”按钮的动作侦听器的私有内部类。
private class AccelerateButtonListener implements ActionListener {
// 当用户单击“加速”按钮时,actionPerformed方法执行。
public void actionPerformed(ActionEvent e) {
vehicle.accelerate();//使用我们之前创建的Car类的实例变量,可以调用Car类中的accelerate方法。
speedTextField.setText(NumberFormat.getInstance().format(vehicle.speed));
}
}
// BrakeButtonListener是用于“刹车”按钮的动作侦听器的私有内部类。
private class BrakeButtonListener implements ActionListener {
// 当用户单击“刹车”按钮时,actionPerformed方法执行。
public void actionPerformed(ActionEvent e) {
vehicle.brake();//使用我们之前创建的Car类的实例变量,可以调用Car类中的brake方法。
speedTextField.setText(NumberFormat.getInstance().format(vehicle.speed));
}
}
// main方法创建CarView的实例,这会导致窗口显示出来。
public static void main(String[] args) {
CarView cv = new CarView();
}
public class Car {
private int yearModel; // yearModel是一个int,保存汽车的型号年份
private String make; // make引用一个String对象,保存汽车的制造商。
private double speed; // speed字段是一个double,保存汽车的当前速度。
// 构造函数接受汽车的型号年份和制造商作为参数。应将这些值分配给对象的yearModel和make字段。
// 速度也应分配为0。
public Car(int model, String type) {
this.yearModel = model;
this.make = type;
speed = 0.0; // 将速度设置为0。
}
// getModel方法
// 负责:获取汽车的型号
public int getModel() {
<details>
<summary>英文:</summary>
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:
* [Laying Out Components Within a Container](https://docs.oracle.com/javase/tutorial/uiswing/layout/index.html)
* [How to Write an Action Listener](https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html)
* [How to Use Buttons, Check Boxes, and Radio Buttons](https://docs.oracle.com/javase/tutorial/uiswing/components/button.html)
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
</details>
# 答案2
**得分**: 0
包含两个类在同一个包中,这样你就可以在第二个类中创建第一个类的对象。
希望你明白!
<details>
<summary>英文:</summary>
include both class in same package so that you can create object of the first class in your second class.
hope you understand !
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论