如何从另一个类中调用一个方法以在我的ActionListener类中使用

huangapple go评论62阅读模式
英文:

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(); 

在类的初始化阶段,你不能从modelTextFieldmakeTextField获取值,因为这些变量为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&#39;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&#39;d be empty as the component hasn&#39;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&#39;s a bunch of other things as well, including, your layouts all over the place; there&#39;s no validation; you&#39;re not reporting back the speed to the user when it changes.

I could go on for quite some time, but instead, I&#39;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(&quot;Car referencer!&quot;);

            //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&#39;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(&quot;Enter the year of your model&quot;);
            makeLable = new JLabel(&quot;Enter the make of your car&quot;);
            speedLable = new JLabel(&quot;Enter the current speed of your car&quot;);

            //Create text fields as well
            modelTextField = new JTextField(5);
            makeTextField = new JTextField(5);
            speedTextField = new JTextField(5);

            //Create the buttons
            accelerateButton = new JButton(&quot;Accelerate&quot;);
            brakeButton = new JButton(&quot;Brake&quot;);

            //Add an action listener to the buttons
            accelerateButton.addActionListener(new AccelerateButtonListener());
            brakeButton.addActionListener(new BrakeButtonListener());

            // Don&#39;t want to use these until AFTER you&#39;ve created a instance of Car
            accelerateButton.setEnabled(false);
            brakeButton.setEnabled(false);
            speedTextField.setEnabled(false);

            makeCarButton = new JButton(&quot;Make car&quot;);
            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&#39;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&#39;s thhe car&#39;s current speed.

            //Construtor that accepts the car&#39;s year model and make as arguments. These values should be assigned to the obkect&#39;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&#39;s really important that you take some time to better understand how an event driven environment works.  Create some buttons which don&#39;t do anything, attach some `ActionListener`s to them and use `System.out.println` to print out what&#39;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>



huangapple
  • 本文由 发表于 2020年8月8日 12:02:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63311682.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定