Построчный вывод в 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 шт):
Я смогла найти решение!
Решение:
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