I am facing one problem in my JavaFx application.
Preface: I don't want to be specific to my application only but want to be generalized so that people like me will get an idea on similar situation.
Background: Implementing a Javafx application using fxml file and multi-threading concept.
Summary: I tried make an application which basically uses multi threading to do some task, and once multi- threading is completed, it will sequentially move to another task. While doing the multi-threading the Main GUI freezes.
What I did,
//This is Main class
Parent Root -> defined on top
public Parent createContent(){
try{
root = FXMLLoader.load(getClass().getResource("Layout.fxml"));
}catch { .....}
}
public void start(){
stage.setScene(new Scene(createContent()));
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws Exception {
Thread.sleep(1000);
return null ;
}
};
task.setOnSucceeded(event->{
stage.show();
});
new Thread(task).run();
}
public static void main(String[] args) {
launch(args);
}
// This is inside the controller on button click event
@FXML
private void start(ActionEvent event) { <---- This one is button click event
Thread t1 = new Thread(new Mul());
t1.start();
Thread t2 = new Thread (new Mul());
t2.start();
}
// Finally
public class Mul implements Runnable {
public void type() {
for (int a = 0; a < 200000; a++) {
System.out.println( Thread.currentThread().getName()+ " says " + a);
}
}
@Override
public void run() {
type();
}
}
Now, here is the outcome. If I just start the threads from the controller then My main application does not freezes while the thread are running in background. However, since the application runs in a sequence, i.e the next step only works when the threads complete their work
I can use t1.join() and t2.join() , but doing so will freezes my main application(Main application here is the main GUI) and I cannot proceed with it until the threads are completed.
What could be the optimal solution, so that I can use multi threading without blocking the main application or What am I doing wrong here? (info, I came to this solution by following up different suggestions from Stack overflow and google)
Why not do
If you really want to "chain" different tasks, call one from the other's
onSucceeded
handler:Obviously this is cleaner if you make
Mul
aTask
subclass instead of aRunnable
, and it's better to use anExecutor
with daemon threads, etc, but this should give you the idea.