search
JavaFX tutorial

mvvmFX: Model-View-ViewModel with JavaFX

Alexander Casall
Framework image via Shutterstock

The framework mvvmFX provides tools to implement the Model-View-ViewModel design pattern with JavaFX. After one year of development it was now released in a first stable version 1.0.0.

The design pattern “Model-View-ViewModel” was first published by Microsoft for .Net applications and is nowadays also used in other technologies like JavaScript frameworks.

As with other MV* approaches the goal is the separation between the structure of the user interface and the (UI-) logic. To do this MVVM defines a ViewModel that represents the state of the UI. The ViewModel doesn’t know the View and has no dependencies to specific UI components.Capture1

Instead the View contains the UI components but no UI logic and is connected with the ViewModel via Data-Binding.

A simple example is the preparation of a welcome message in the ViewModel:

Capture2

One of the benefits of this structure is that all UI state and UI logic is encapsulated in a ViewModel that is independent from the UI.

But what is UI logic? The UI logic defines how the user interface reacts to input from the user or other events like changes in the domain model. For example the decision whether a button should be active or inactive.

Because of the independence from the UI the ViewModel can be tested with unit tests.

In many cases there is no need for complicated integration tests anymore where the actual application is started and remotely controlled by the test tool. This simplifies test-driven-development significantly.

Due to the availability of Properties and Data-Binding JavaFX is eminently suitable for this design pattern. mvvmFX adds helpers and tools for the efficient and clean implementation of the pattern.

The following example will give an impression of the development process with MVVM.

In the example there is a login button that should only be clickable when the username and the password are entered.

Following TDD the first step is to create a unit test for the ViewModel:

@Test
public void test(){
  	LoginViewModel viewModel = new LoginViewModel();

  	assertThat(viewModel.isLoginButtonDisabled()).isFalse();

  	viewModel.setUsername("mustermann");
 	assertThat(viewModel.isLoginButtonDisabled()).isFalse();

viewModel.setPassword("geheim1234");
assertThat(viewModel.isLoginPossible()).isTrue();
}

After that the <i>ViewModel</i> can be implemented:

public class LoginViewModel implements ViewModel {

private StringProperty username = new SimpleStringProperty();
private StringProperty password = new SimpleStringProperty();
private BooleanProperty loginPossible = new SimpleBooleanProperty();

public LoginViewModel() {
		loginButtonDisabled.bind(username.isEmpty().or(password.isEmpty());
}

  	// getter/setter
}

Now this ViewModel has to be connected with the View. In the context of mvvmFX the “View” is the combination of an fxml file and the related controller class. It is important to keep in mind that the JavaFX controller is part of the View and should not contain any logic.

Its only purpose is to create the connection to the ViewModel.

public class LoginView implements FxmlView<LoginViewModel> {
@FXML
  	public Button loginButton;

  	@FXML
  	public TextField username;

  	@FXML
  	public PasswordField password;

  	@InjectViewModel //is provided by mvvmFX
  	private LoginViewModel viewModel;

	//will be called by JavaFX as soon as the FXML bootstrapping is done
  	public void initialize(){
username.textProperty()
.bindBidirectional(viewModel.usernameProperty());
password.textProperty()
.bindBidirectional(viewModel.passwordProperty());

loginButton.disableProperty()
.bindBidirectional(viewModel.loginPossibleProperty());
  	}
}

Please note that the View has a generic type that is the related ViewModel type. This way mvvmFX can manage the lifecycle of the View and the ViewModel.

Additional Features

Capture3The shown example uses FXML to define the structure of the user interface. This is the recommended way for development but mvvmFX supports traditional Views written with pure Java code too.

Another key aspect of the library is the support of Dependency-Injection frameworks.

This is essential to be able to use the library in bigger projects.

At the moment there are additional modules provided for the integration with Google Guice and JBoss Weld/CDI to allow an easy start with these frameworks. But other DI frameworks can be easily embedded too.

mvvmFX was recently released in a first stable version 1.0.0. It is used for projects by Saxonia-Systems AG. The framework is developed as open source (Apache licence) and is hosted at Github. The authors are looking forward to get feedback, suggestions and critical reviews.

For the future development the focus lies on features that are needed for bigger projects with complex user interfaces. These includes a mechanism with that many ViewModels can access common data without the introduction of a mutual visibility and dependency to each other (Scopes).

Additionally there are helpers to implement navigation between views and the management of master-detail interfaces. One source of inspiration is microsofts framework PRISM, an application framework that provides many needed tools for the development of applications.

Author
Alexander Casall
Alexander Casall is a developer at Saxonia Systems AG, with a focus on multi-touch applications using JavaFX.

Comments
comments powered by Disqus