-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Load FXML in background thread with FluentViewLoader #451
Comments
This sounds interesting and could improve performance of loading a lot. However, I don't think it's possible with the current implementation. To implement this we would need to first check if it is even possible to load FXML files from another thread with FXMLLoader. I don't think this is possible because typically you need to be on the FX-Thread to create instances of JavaFX controls. If I'm wrong and loading FXML files from outside of FX thread is possible the second step would be to introduce a new initialization mechanism that is guaranteed to be executed on the FX thread. This would be the easy part. For example we could introduce a new interface that we check at loading time and invoke the new initialize method. alternatively you could use |
I think it is possible to load FXML within a Task, here is an example in SO: http://stackoverflow.com/questions/34873673/load-fxml-as-background-process-javafx I modified the helloworld mini-example to load the FXML file using FluentViewLoader in a JavaFx Task according to your recommendation of using
|
Thanks for the example code. It looks interesting. Do you see a performance win with this approach? To support this directly in the framework I think of two aspects:
CompletableFuture<ViewTuple<MyView, MyViewModel>> loadingResult = FluentViewLoader.fxmlView(MyView.class).loadAsync();
CompletableFuture<MyView> viewFuture = loadingResult.thenApply(ViewTuple::getView);
Parent root = viewFuture.get(); Personally, instead of
public class MyView implements FxmlView, InitializeOnFxThread {
public void initialize() {
// don't use this.
}
@Override
public void initializeOnFxThread() {
// use this on FX thread
}
} In the ViewLoader we can make sure that this is invoked on the FX Thread by wrapping it internally in a However, While I have an idea of how this could look in the code I'm still not sure if we should add this to the library. Especially the Initialize Interface isn't obvious and it's not clean that the components itself are depending on how the ui is loaded. Maybe we should only document the solution that you described here? |
Thank you very much for your time, the solution you propose is very elegant. However in this case I prefer to use JavaFx Tasks over CompletableFuture, because they provide the possibility of monitoring the execution of the task, in this case the loading of FXML files, as well as creating a more friendly experience for the end user. I will formulate a more elaborate solution proposal using JavaFx Tasks that we can discuss later. |
Manuel, Have you considered the InputStream version of the FXMLLoader.load() call? Maybe there's a speedup if IO is done in a separate thread producing sets of bytes for the FluentViewLoader? |
Hi carl. In general I don't think that putting the loading in a separate thread will bring us a real performance win because then the whole loading process is still done in one big step. It just on another thread so the ui isn't blocked. |
No, you're right. I ran a few test programs that loaded the FXML into byte arrays using various numbers of Threads. IO isn't the performance bottleneck. |
Ok, to sum up the discussion:
|
Added a wiki page for this topic: https://github.com/sialcasa/mvvmFX/wiki/Asynchronous-Operations I will close this issue for now. |
Could be possible loading large FXML scenegraphs in background thread and then execute initialization code in UI thread?
The text was updated successfully, but these errors were encountered: