Skip to content

Asynchronous Operations

Manuel Mauky edited this page Dec 16, 2016 · 1 revision

Long-running operations shouldn't be executed on the JavaFX UI Thread to prevent blocking of the UI. On this page we want to describe some aspects of this topic, what problems exist and how you can avoid or fix them.

Loading mvvmFX Scenes in a background thread.

If you have a big component hierarchy it may be useful to load this hierarchy in a background thread to prevent a blocking of the UI. At the moment mvvmFX doesn't an provide explicit API for this use case. However, @rguillens has described in #451 how you can still implement asynchronous loading of mvvmFX components. The first step is to trigger the loading process in a background thread, for example by using a JavaFX Task:

@Override
public void start(Stage stage) throws Exception {

	Task<Parent> loadTask = new Task<Parent>() {
		@Override
		protected Parent call() throws Exception {
			return FluentViewLoader.fxmlView(MainView.class).load().getView();
		}
	};

	loadTask.setOnSucceeded(event -> {
		stage.setScene(new Scene(loadTask.getValue()));
		stage.show();
	});

	new Thread(loadTask).start();
}

In most applications this will already work. However, you have to keep in mind that with this approach the initialize method of the view classes won't be invoked on the JavaFX Thread anymore. In many cases this won't be a problem at all but for some use cases you may run into exceptions because of this. To fix such cases you should wrap your initialization logic in a Platform.runLater call like this:

public class MyView implements FxmlView<MyViewModel> {

    public void initialize() {
        Platform.runLater(() -> {
            // ui initialization
        });
    }
}