Построчный вывод в Label в JavaFX

Новичок. Изучаю JavaFX и использую так же SceneBuilder.

Поставленная мной задача:

"после запуска приложения надпись Pin Code в объекте Label выводится построчно через небольшое количество времени(в идеале еще при этом добавить звук)."

Я так понимаю нужно сделать цикл с задержкой.

Проверила свой код в консоле и он выводит построчно правильно, но как я поняла(поправьте, если это не так) метод initialize() сначала проходит, и только потом запускается сцена уже с полным текстом.

Пыталась вынести отдельно в метод и пройтись с помощью PauseTransition, но не помогло.

Так же пробовала через Thread.sleep(), но результат тот же, сначала проходит инициализация, а только потом показывается сцена.

Класс EntryController:

import javafx.animation.PauseTransition;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.util.Duration;

public class EntryController {

    @FXML
    private Label printPinCode;

    public void pause(String text) {
        PauseTransition wait = new PauseTransition(Duration.seconds(1));
        wait.setOnFinished((e) -> {
            printPinCode.setText(text);
            wait.playFromStart();
        });
        wait.play();
    }

    @FXML
    void initialize() {
            String textStartWindow = "Pin Code";
            String newText = "";
            for (int i = 0; i < textStartWindow.length(); i++){
                newText += textStartWindow.charAt(i);
                pause(newText);
            }
    }

Класс Main:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/form/pin-code.fxml"));

        stage.setTitle("ATM --> Start");
        stage.setScene(new Scene(root));
        stage.show();
    }
}

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Alina Klishyna

Я смогла найти решение!

Решение:

public void printLineByLine(String text, Label output) {
    Timeline timeline = new Timeline();
    KeyFrame keyFrame = new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>() {
        int i = 0;
        @Override
        public void handle(ActionEvent actionEvent) {
            if (i <= text.length()) {
                output.setText(text.substring(0, i));
                i++;
            } else {
                timeline.stop();
            }
        }
    });
    timeline.getKeyFrames().add(keyFrame);
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.play();
}

@FXML
void initialize() {
    printLineByLine("Pin Code", pinCodeLabel);
}

Немного покопавшись в инете поняла что Thread.sleep() не подходит так как оно блокирует поток JavaFX, и если нам нужна анимация, то лучше воспользоваться Timeline. Timeline обрабатывает круг KeyFrame и после его истечения снова повторяет, благодаря Animation.INDEFINITE

→ Ссылка