简体   繁体   English

重绘方法不起作用的Java

[英]repaint method not working java

I have this code, and I want it to repaint so that when the user enters the details it prints out the acceleration and fuel consumption (calculated in another class), I can see it works because i have system.out.println's showing the values but they do not get updated to my JFrame. 我有这段代码,我想让它重新绘制,以便当用户输入详细信息时,它会打印出加速度和油耗(在另一个类中计算),因为我有system.out.println来显示值,所以我可以看到它是有效的但它们不会更新到我的JFrame。

window() is called in another constructor in another class, the JFrame opens fine but does not update 在另一个类的另一个构造函数中调用window(),JFrame可以正常打开,但不会更新

Any ideas? 有任何想法吗?

Thanks 谢谢

public class Vehicle extends JFrame {

    protected static double horsepower;
    protected static double aerodynamics;
    protected static double weight;
    protected static double acceleration;
    protected static double topspeed;
    protected double fuelconsumption;
    protected String userHorsepower;
    protected String userWeight;
    protected String userTopspeed;
    protected String userInput = "No Current Selection";

    JPanel panel = new JPanel();
    JButton Van = new JButton("Add Van");



    public Vehicle(double horsepower, double weight, double aerodynamics, double topspeed){
        super();
    }

    public void window(){

        JButton Van = new JButton("Add Van Car");
        Van.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {

                userHorsepower = JOptionPane.showInputDialog("Enter Horsepower");
                horsepower = Double.parseDouble(userHorsepower);
                userWeight = JOptionPane.showInputDialog("Enter Weight");
                weight = Double.parseDouble(userWeight);
                userTopspeed = JOptionPane.showInputDialog("Enter Topspeed");
                topspeed = Double.parseDouble(userTopspeed);
                aerodynamics = 0.9;
                userInput = "Van";
                TestConsumption.printVan();
                repaint();
                return;

            }});

        JButton SportCar = new JButton("Add Sports Car");
        SportCar.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                        userHorsepower = JOptionPane.showInputDialog("Enter Horsepower");
                        horsepower = Double.parseDouble(userHorsepower);
                        userWeight = JOptionPane.showInputDialog("Enter Weight");
                        weight = Double.parseDouble(userWeight);
                        userTopspeed = JOptionPane.showInputDialog("Enter Topspeed");
                        topspeed = Double.parseDouble(userTopspeed);
                        aerodynamics = 0.5;
                        userInput = "Sports Car";
                        TestConsumption.printCar();
                        panel.repaint();
            }});

        JLabel userChoice = new JLabel(userInput);
        JLabel accel = new JLabel("Acceleration: " + acceleration);
        JLabel fuel = new JLabel("Fuel Consumption: " + fuelconsumption);

        panel.setLayout(new GridLayout(5,5,0,0));
        panel.add(Van);
        panel.add(SportCar);
        panel.add(userChoice);
        panel.add(accel);
        panel.add(fuel);
        add(panel);
        pack();
        setTitle("Title Here");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(true);
        setSize(300,200);
        setLocationRelativeTo(null);
        setVisible(true);
        repaint();
    }

Window is called in this class 窗口在此类中被称为

public class TestConsumption extends Vehicle {

    public TestConsumption(double horsepower, double weight, double aerodynamics, double topspeed) {
        super(horsepower, weight, aerodynamics, topspeed);
    }

    public static void main(String [] args){

        Vehicle vh = new Vehicle(500, 500, 500, 500);
        vh.window();
    }


    public static void printCar(){
        Vehicle Car = new SportCar(horsepower,weight,aerodynamics,topspeed);

        Car.acceleration();
        Car.showFuelConsumption();
    }

    public static void printVan(){

        Vehicle FirstVan = new Van(horsepower,weight,aerodynamics,topspeed);

        FirstVan.acceleration();
        FirstVan.showFuelConsumption();
    }
}

constructor Vehicle(double horsepower, double weight, double aerodynamics, double topspeed)调用window() constructor Vehicle(double horsepower, double weight, double aerodynamics, double topspeed)

As far as we can see, you're never updating the text of your JLabels. 据我们所知,您永远不会更新JLabel的文本。 You will need to call setText on each JLabel after calculating the new corresponding value for that label. 在为该标签计算新的对应值之后,需要在每个JLabel上调用setText

However, in your situation, your JLabel objects are created as local scope variables in the window() method, and so they're no longer easily accessible (technically there is a way to access them since you added them to your JPanel , but that's unnecessarily cumbersome). 但是,根据您的情况,您会在window()方法中将JLabel对象创建为局部范围变量,因此它们不再易于访问(从技术上讲,由于您已将它们添加到JPanel ,因此有一种访问它们的方法,但这就是不必要的麻烦)。

Since TestConsumption.printVan() is apparently used to calculate the acceleration and fuel consumption, to make life easier, I suggest promoting JLabel accel and JLabel fuel to instance variables, and then making individual methods to calculate the two values in TestConsumption . 由于TestConsumption.printVan()显然用于计算加速度和油耗,为了使生活更轻松,我建议将JLabel accelJLabel fuel提升为实例变量,然后采用单独的方法来计算TestConsumption的两个值。 So your action event might look something like this: 因此,您的动作事件可能看起来像这样:

sportCar.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        userHorsepower = JOptionPane.showInputDialog("Enter Horsepower");
        horsepower = Double.parseDouble(userHorsepower);

        userWeight = JOptionPane.showInputDialog("Enter Weight");
        weight = Double.parseDouble(userWeight);

        userTopspeed = JOptionPane.showInputDialog("Enter Topspeed");
        topspeed = Double.parseDouble(userTopspeed);

        aerodynamics = 0.5;
        userInput = "Sports Car";

        // These static methods would be added to your TestConsumption class
        acceleration = TestConsumption.calculateAcceleration(...whatever params required for this calculation...);
        fuelConsumption = TestConsumption.calculateFuelConsumption(...whatever params required for this calculation...);

        accel.setText("Acceleration: " + acceleration);
        fuel.setText("Fuel Consumption: " + fuelConsumption);

        panel.repaint();
}});

Alternatively, you don't have to promote the JLabels to instance variables; 另外,您也不必将JLabel提升为实例变量。 so long as you declare accel and fuel at the top of the window() method before you set up the ActionListener for both buttons, they will be accessible in the event action through the actionPerformed method's scope enclosure. 只要在为两个按钮设置ActionListener 之前window()方法的顶部声明accelfuel ,它们就可以通过actionPerformed方法的作用域附件在事件操作中访问。

Some Side notes: 一些注意事项:

Remember that the Java naming convention for variable names is to begin them with a lower case letter. 请记住,变量名的Java命名约定是以小写字母开头。 So your Van and SportCar variables should be van and sportCar . 因此,您的VanSportCar变量应为vansportCar I have written them as such in my example. 我已经在示例中将它们写成这样。 While it doesn't cause any issues, syntactically, it makes it difficult to know at a glance whether one is looking at a class or variable name. 从语法上讲,虽然它不会引起任何问题,但使人们一眼便知道是在看一个类还是在看变量名是很困难的。

As far as I can tell, your TestConsumption class doesn't need to extend Vehicle . 据我所知,您的TestConsumption类不需要扩展Vehicle It is not a vehicle; 它不是车辆; it seems to be both the starting point of your application, and a helper class (the static methods). 它似乎既是应用程序的起点,也是助手类(静态方法)。

This appears to be a school assignment, so I am not certain whether you've been explicitly told to design your program in this manner, but from a design perspective, you're combining your conceptual "view" and "model" together. 这似乎是学校的任务,所以我不确定是否明确要求您以这种方式设计程序,但是从设计的角度来看,您正在将概念性的“视图”和“模型”组合在一起。 A JFrame is not a vehicle; JFrame不是车辆。 it is a window, a view element used to help represent your data. 它是一个窗口,一个视图元素,用于帮助表示您的数据。 You may find it will help clean up your code by extracting vehicle-specific fields and methods (such as acceleration , topspeed , etc), in to a separate class called Vehicle , which you can then subclass with SportCar and Van (as you seem to be doing as indicated in TestConsumption ). 您可能会发现它将特定于车辆的字段和方法(例如acceleration ,最高topspeed等)提取到一个名为Vehicle的单独类中,将有助于清理代码,然后您可以将其与SportCarVan子类化(您似乎按照TestConsumption指示进行TestConsumption Your JFrame subclass (lets call it MainWindow or something like that instead), would be responsible only for updating its data representations (meaning our accel and fuel JLabels, in this case). 您的JFrame子类(我们称其为MainWindow或类似名称)仅负责更新其数据表示形式(在这种情况下,这意味着我们的accelfuel JLabel)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM