Reputation: 1676
I want to open a new window from the task but for some reason after line Stage stage = new Stage
the code stops executing, but there is no error.
Task<Void> task = new Task<Void>() {
@Override protected Void call() throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Stage stage = new Stage();
System.out.println("Print");
stage.setTitle("My New Stage Title");
stage.setScene(new Scene(root, 100, 100));
stage.show();
return null;
}
};
It never prints out the message 'Print'.
Upvotes: 0
Views: 1112
Reputation: 45786
The reason your Task
is failing is because you are creating a Stage
on a thread other than the JavaFX Application Thread. The Javadoc of Stage
states:
Stage objects must be constructed and modified on the JavaFX Application Thread.
This means when you attempt to create a Stage
on the background thread that the Task
is running on it will result in an IllegalStateException
with a message telling you that you aren't on the JavaFX Application Thread. To solve this issue wrap all code that creates and/or modifies a Stage
in a Platform.runLater(Runnable)
call.
Side Note: It would probably be better to not create the Stage
in the Task
at all. Rather, in your case, simply return the result of FXMLLoader.load(URL)
and create the Stage
when handling the success of the Task
.
Task<Parent> task = new Task<Parent>() {
@Override
protected Parent call() throws Exception {
return FXMLLoader.load(getClass().getResource("sample2.fxml"));
}
};
task.setOnSucceeded(event -> {
Parent root = task.getValue();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();
};
You say there is no error but you also don't show any code that would display an error if one does occurr. When a Task
fails it sets the cause of failure in the exception
property. To handle the case when a Task
fails you can:
exception
propertyEventHandler
to handle a WorkerStateEvent.WORKER_STATE_FAILED
event and query the exception
property
task.setOnFailed(EventHandler)
or task.addEventXXX(EventType, EventHandler)
where XXX
is either Filter
or Handler
protected void failed()
method in your Task
implementation and query the exception
property
failed()
method will always be called on the JavaFX Application Threadcall()
method before re-throwing itUpvotes: 1
Reputation: 46
You need an Executor to start the thread
Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t;
});
exec.execute(task);
Upvotes: 0