如何从在不同类中运行的TimerTask更新JavaFX应用程序线程?

时间:2016-08-25 21:13:59

标签: java multithreading javafx

Timer类

public class LureTimer{

    private int totalTime = 0;
    private int minutes = 0;
    private static Timer mTimer;
    private boolean timeRunning;
    private static LureUI mLureUI;

    private StringProperty theTime = new SimpleStringProperty(this, "theTime", "Test");


    public void startTimer(){
        System.out.println("Started");
        mTimer = new Timer();
        mLureUI = new LureUI();
        theTimer();
        timerStarted();
    }


    public void theTimer() {
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (totalTime != 59) {
                    totalTime++;
                    timePrint();
                } else {
                    totalTime = 0;
                    minutes++;
                    timePrint();
                }
                checkTime();
            }
        }, 0, 1000);
    }

    private void checkTime() {
        if(minutes == 30){
            stopTimer();
        }
    }

    public void timePrint(){
        if (totalTime < 10 && minutes < 10) {
            System.out.println("0" + minutes + ":0" + totalTime);
            setTheTime("0" + minutes + ":0" + totalTime);
        } else if (totalTime >= 10 && minutes < 10){
            System.out.println("0" + minutes + ":" + totalTime);
            setTheTime("0" + minutes + ":" + totalTime);
        }else {
            System.out.println(minutes + ":" + totalTime);
           setTheTime(minutes + ":" + totalTime);
        }
    }

    public boolean isTimeRunning() {
        return timeRunning;
    }

    public void timerStarted(){
        timeRunning = true;
    }

    public void timerStopped(){
        timeRunning = false;
    }

    public void stopTimer(){
        mTimer.cancel();
        timerStopped();
        resetCounters();
        System.out.println("Timer stopped");
    }

    private void resetCounters() {
        totalTime = 0;
        minutes = 0;

    }

    public String getTheTime() {
        return theTime.get();
    }

    public StringProperty theTimeProperty() {
        return theTime;
    }

    public void setTheTime(String theTime) {
        this.theTime.set(theTime);
    }

}

用户界面

public class LureUI extends Application {

    private Button button;
    private Button button2;
    private LureTimer mLureTimer = new LureTimer();
    private Label mLabel;



    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Lure Monitor");
        button = new Button("Start Timer");
        button2 = new Button("Stop Timer");

        button.setOnAction(e -> mLureTimer.startTimer());
        button2.setOnAction(e -> mLureTimer.stopTimer());

        VBox layout1 = new VBox();
        layout1.setSpacing(10);
        mLabel = new Label();
        mLabel.textProperty().bind(mLureTimer.theTimeProperty());
        layout1.getChildren().addAll(mLabel, button, button2);
        layout1.setAlignment(Pos.CENTER);

        Scene scene = new Scene(layout1, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();

    }


}

当我运行这个时,我得到一个异常......

  

线程中的异常&#34; Timer-0&#34; java.lang.IllegalStateException:未启用   FX应用程序线程; currentThread = Timer-0

我的目标是让UI类中的mLabel从使用theTimer()设置时间的timePrint()方法进行更新。

From reading other posts我可以看到解决方案是Platform.runLater(),但这会运行一个新的Runnable对象,如何使用TimerTask实现相同的结果?

1 个答案:

答案 0 :(得分:1)

Laser

给出的答案
public void theTimer() {
    mTimer.schedule(new TimerTask() {
        @Override
        public void run() {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    if (totalTime != 59) {
                        totalTime++;
                        timePrint();
                    } else {
                        totalTime = 0;
                        minutes++;
                        timePrint();
                    }
                    checkTime();
                }
            });
        }
    }, 0, 1000);
}

使用Lambda:

public void theTimer() {
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                Platform.runLater(() -> {
                    if (totalTime != 59) {
                        totalTime++;
                        timePrint();
                    } else {
                        totalTime = 0;
                        minutes++;
                        timePrint();
                    }
                    checkTime();
                });
            }
        }, 0, 1000);
    }
相关问题