Аналог await Task.Delay(1000) в JavaFX

119
23 января 2021, 22:30

господа. Есть такое задание: разработать программу, изображающую на экране работающие электронные часы с цифровым индикатором, а также с индикацией в отдельных окнах даты и дня недели. Предусмотреть в программе установку времени, даты, дня недели, а также пуск часов. Написал следующую функцию для хода часов:

 public void Tick (){
    String secBuf = TSec.getText();
    sec = Integer.parseInt(secBuf);
    sec++;
    secBuf = Integer.toString(sec);
    TSec.setText(secBuf);
        if(sec >= 60){
    String minBuf = TMin.getText();
            min = Integer.parseInt(minBuf);
            min++;
            minBuf = Integer.toString(min);
            TMin.setText(minBuf);
    sec = 0;
            secBuf = Integer.toString(sec);
            TSec.setText(secBuf);
    if(min >= 60){
                String hourBuf = THour.getText();
                hour = Integer.parseInt(hourBuf);
                hour ++;
                hourBuf = Integer.toString(hour);
                THour.setText(hourBuf);
                min = 0;
                minBuf = Integer.toString(min);
                TMin.setText(minBuf);
                if(hour >= 24){
                    hour = 0;
                    hourBuf = Integer.toString(hour);
                    THour.setText(hourBuf);
                }
    }
        }
}

Также есть функция, которая запускается при нажатии "Пуск часов":

@FXML
private void MPuskAct(ActionEvent event) {
     while(true) {
        Tick();
        try {
        TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

При запуске программы и нажатии на эту кнопку происходит коллапс, программа виснет и не отвечает. Также я пробовал писать вместо TimeUnit.SECONDS.sleep(1); такую вещь: Thread.sleep(1000);, но результат тот же. Покопавшись на форумах, я понял, что тут проблема в потоках, но не понимаю, как их разграничить. В С# есть await Task.Delay(1000), но в Java я такого найти не смог. Можете что-то подсказать похожее? Заранее спасибо.

Answer 1

Учитывая что в данной задаче периодически нужно менять содержимое JаvaFX-контролов, то правильнее будет использовать что-то из JavaFX, напр. javafx.animation.Timeline:

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.util.Duration;
// ...
private Timeline oneSecTick;
public void initialize() {
    // ...
    oneSecTick = new Timeline(new KeyFrame(Duration.seconds(1), event -> Tick()));
    oneSecTick.setCycleCount(Timeline.INDEFINITE);
}
@FXML
private void MPuskAct(ActionEvent event) {
    oneSecTick.play();
}
private void Tick() {
    // ...
}

Полный запускаемый пример, все в одном классе:

import java.time.LocalTime; 
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class JavaFXClock extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    private Timeline oneSecTick;
    private Label label;
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Clock");
        oneSecTick = new Timeline(new KeyFrame(Duration.seconds(1), event -> tick()));
        oneSecTick.setCycleCount(Timeline.INDEFINITE);
        label = new Label("--:--");
        Button btn = new Button();
        btn.setText("Start");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                oneSecTick.play();
            }
        });
        VBox root = new VBox(16);
        root.getChildren().add(label);
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
    private void tick() {
        label.setText(LocalTime.now().toString());
    }
}
READ ALSO
Mozilla декодирует url в адресной строке

Mozilla декодирует url в адресной строке

Mozilla декодирует закодированный url в адресной строкеИз-за чего получаю bad request, т

82
Настройка компилятора TypeScript

Настройка компилятора TypeScript

Есть ли способ заставить Классы в TypeScript компилироваться в Фабричные Функции, где приватные свойства и методы не будут попадать в прототип?...

119
Найти экземпляр объекта/класса Javascript

Найти экземпляр объекта/класса Javascript

Хочу написать "патч" для одной веб игры (На JS), весь код минифицирован, поэтому лезть в него не самая лучшая идея

126
JavaScript print . Как распечатать документ без лишних footer header

JavaScript print . Как распечатать документ без лишних footer header

Как распечатать документ без footer и headerНе знаю как это по другому назвать, поэтому прошу прощение

103