Используйте PauseTransition
:
btn.setOnAction(e->{
pane.getChildren().addAll(lb);
PauseTransition pause = new PauseTransition(Duration.seconds(0.3));
pause.setOnFinished(e -> pane.getChildren().removeAll(lb));
pause.play();
});
Причина, по которой ваш подход не работает, заключается в том, что JavaFX эффективно использует один поток для рендеринга и обработки пользовательских событий. Он будет обновлять экран с фиксированным интервалом (60 раз в секунду в текущей реализации), но по причинам синхронизации необходимо дождаться любых ожидающих событий, которые в данный момент обрабатываются, чтобы завершить сначала. Таким образом, исходный код добавляет метку, делает паузу на 0,3 секунды, а затем удаляет метку. Поток приложения FX занят для всего этого процесса, поэтому среда FX никогда не имеет возможности перерисовать сцену, пока она происходит.
Суть в том, что вы никогда не должны блокировать поток приложения FX, вызов sleep()
или выполнение длительных операций.
Обновление в ответ на дополнительный вопрос в комментарии:
Чтобы отключить всю обработку событий, вы можете вызвать setDisable(true)
на root узел сцены. Поэтому, чтобы предотвратить обработку событий во время отображения метки:
btn.setOnAction(e->{
pane.getChildren().addAll(lb);
pane.setDisable(true);
PauseTransition pause = new PauseTransition(Duration.seconds(0.3));
pause.setOnFinished(e -> {
pane.getChildren().removeAll(lb));
pane.setDisable(false);
});
pause.play();
});