有一种解决方法,可以让类互相调用?

时间:2019-06-10 11:16:17

标签: java javafx

我正在尝试使用JavaFX来编写秒表。但是我对Java还是很陌生,但仍然存在真正理解OOP的问题。我需要不得不类调用彼此的方法。我知道应该避免使用静态方法和变量。 gui有启动和停止按钮,应启动和停止计时器。我设置了"TimerClass"。内部有一个方法,一旦被激活,它每秒就会运行一次代码。因此,当我按下开始按钮时,我希望这种情况发生。这似乎已经起作用。但是变量"secondsPassed"每隔一秒就会更新一次,我的GUI上的标签也需要更新。

我可以将lblTime Button和相应的方法设为静态。 我也听说过以某种方式设置构造函数,使每个实例都可以等于另一个现有实例。但是我仍然对它的理解还不够,无法使用它。 (Java: classes with instance of each other) 我也尝试创建一个"helper class"。这是为了避免不得不相互实例两个类。但是助手类仍将是"TimerClass"的另一个实例。 我有一些代码可以显示到目前为止我已经尝试过的内容。

package application;

import application.TimerClass;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

public class Controller {
    TimerClass timerClass = new TimerClass();

    @FXML
    Button btnStart;
    @FXML
    Button btnPause;
    @FXML
    Label lblTime;

    public void btnStartAction() {
        timerClass.timerStart();
    }

    public void btnPauseAction() {
        timerClass.timerPause();
    }

    public void setLblTime(int input) {
        lblTime.setText(""+input);
    }

}
package application;

import application.Controller;
import application.Helper;

import java.util.Timer;
import java.util.TimerTask;

public class TimerClass {
    static int secondsPassed = 0;

    Controller controller = new Controller();
    TimerClass timerClass = new TimerClass();
    Helper helper;

    public TimerClass(TimerClass input){
        this.helper = timerClass;
    }

    public TimerClass() {

    }

    Timer mytimer = new Timer();
    TimerTask timerTask = new TimerTask() {

        @Override
        public void run() {
            secondsPassed++;
            System.out.println("" + secondsPassed);
        }
    };

    public void timerStart() {
        mytimer.scheduleAtFixedRate(timerTask, 1000, 1000);
    }

    public void timerPause() {
        mytimer.cancel();
    }

    public int getSecondsPassed() {
        return secondsPassed;
    }

}

谢谢!

2 个答案:

答案 0 :(得分:4)

您无需相互实例化这些类。实际上,这不是一个好主意,因为Controller类的实例与您的场景使用的实例不同。

相反,您应该将现有的类传递给TimerClass。 (请注意,您可能希望“隐藏”界面后面的Controller,以使TimerClass更具可重用性。)

public class TimerClass {
    // don't make this static
    // otherwise you won't be able to use multiple instances at the same time
    volatile int secondsPassed = 0; 

    private final Controller controller;


    public TimerClass(Controller controller) {
        this.controller = controller;
    }

    TimerTask timerTask = new TimerTask() {

        @Override
        public void run() {
            secondsPassed++;
            // update on the JavaFX application thread
            Platform.runLater(() -> controller.setLblTime(secondsPassed));
        }
    };

    public void timerStart() {
        mytimer.scheduleAtFixedRate(timerTask, 1000, 1000);
    }

    public void timerPause() {
        mytimer.cancel();
    }

    public int getSecondsPassed() {
        return secondsPassed;
    }

}
public class Controller {
    TimerClass timerClass = new TimerClass(this);
    ...
}

您可能想看看以下答案中的第一个建议:https://stackoverflow.com/a/9966213/2991525

答案 1 :(得分:0)

嘿,Leonhard到目前为止做得不错,看来您对到目前为止的事情有一个不错的了解。如果我对问题的理解正确,请告诉我,因此您按下了一个名为“开始”的按钮。该按钮使秒数开始滴答,此外,您还具有显示正在经过的秒数的标签,但是该标签不会更新以显示当前秒数吗?

首先想到的是为开始按钮设置一个布尔值。

if (** when the user clicks the button **) {
      buttonBoolean = !buttonBoolean; //this just turns false to true; and true to false.
}

然后在添加秒数的方法中,执行'if'语句以检查开始按钮是否处于打开状态。

if (buttonBoolean == true) {
    seconds++;
    setLabelValue = seconds;
}

如果为true,则更新秒数并将标签的值设置为更新的值。

让我知道这是否有帮助!