Answer the question
In order to leave comments, you need to log in
How to create a thread in JavaFX that will add a Label until the Stop button is clicked?
How to create a thread in JavaFX that will add a Label until the Stop button is clicked?
if you create something like this, then an error occurs - Not on FX application thread; currentThread = Thread-4
Thread addLabel = new Thread(new Runnable() {
@Override
public void run() {
while(start) {
vBox.getChildren().addAll(new Label("new label"));
}
}
});
Answer the question
In order to leave comments, you need to log in
JavaFX, like many other gui libraries, is single-threaded. When a window is created, an Event Dispatch Thread is created , inside which the event loop and event handlers will work. You should not attempt to interact with GUI elements from the main thread or any other thread - this will crash. You should not start threads inside event handlers - this will lead to a crash. If you need to change, for example, the label text from another thread, you will have to create a task for the EDT:
If you need to launch a long-running task inside a button click handler, you will have to use Task and Service :
public class Example extends Application {
...
btn.setOnAction(act -> {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
// Долгий код
return null;
}
};
}
};
service.start();
});
}
here it is better to use the reverse strategy.
we create a thread that thinks for a long time, and from it we somehow inform the gui thread so that it already creates a label.
I personally use either AnimationTimer or Platform.runLater
to change UI from JavaFx thread
but mostly AnimationTimer
boolean update=false;
AnimationTimer animationTimer=new AnimationTimer() {
@Override
public void handle(long now) {
// от здесь уже процесс от JavaFx, можешь спокойно обновлять UI
if(update){
update=false;
// обычно у меня так выглядет
// TODO обновление UI
}
}
};
animationTimer.start();
Platform.runLater(new Runnable() {
@Override
public void run() {
// здесь уже поток от JavaFx
}
});
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question