Я пытаюсь написать код, который заставит вещи появляться на экране с заранее определенными, но нерегулярными интервалами, используя javafx. Я попытался использовать таймер (java.util, а не javax.swing), но, оказывается, вы можете Не изменяйте что-либо в приложении, если вы работаете из отдельного потока. (Как и таймер) Может ли кто-нибудь сказать мне, как я могу заставить таймер взаимодействовать с приложением, если они оба являются отдельными потоками?
Таймеры и javafx
Ответ 1
Если вы касаетесь любого компонента JavaFX, вы должны сделать это из потока платформы (который по сути является потоком отправки событий для JavaFX.) Вы делаете это легко, вызывая Platform.runLater()
. Так, например, это совершенно безопасно для этого:
new Thread() {
public void run() {
//Do some stuff in another thread
Platform.runLater(new Runnable() {
public void run() {
label.update();
javafxcomponent.doSomething();
}
});
}
}.start();
Ответ 2
Вам не нужно java.util.Timer
или java.util.concurrent.ScheduledExecutorService
планировать будущие действия в потоке приложений JavaFX. Вы можете использовать временную шкалу JavaFX как таймер:
new Timeline(new KeyFrame(
Duration.millis(2500),
ae -> doSomething()))
.play();
В качестве альтернативы вы можете использовать метод удобства из ReactFX:
FxTimer.runLater(
Duration.ofMillis(2500),
() -> doSomething());
Обратите внимание, что вам не нужно обертывать действие в Platform.runLater
, потому что оно уже выполнено в потоке приложений JavaFX.
Ответ 3
berry120 отвечает с java.util.Timer тоже, чтобы вы могли сделать
Timer timer = new java.util.Timer();
timer.schedule(new TimerTask() {
public void run() {
Platform.runLater(new Runnable() {
public void run() {
label.update();
javafxcomponent.doSomething();
}
});
}
}, delay, period);
Я использовал это, и он отлично работает