MVC stands for Model-View-Controller, and JavaFX is fundamentally structured for it, along with similar patterns like MVP and MVVM. JavaFX’s support for events, properties, binding and FXML documents all help facilitate this. They’re there to allow you to to separate the business logic from the user interface.

Separate Views should be created for different user requirements

Every element of the JavaFX MVC pattern is defined by one or more Java objects. In fact, MVC in JavaFX can be implemented both with and without the use of FXML.

I personally prefer to use FXML to structure and create my View objects, because of its simplicity, the in-built links to Controller and CSS files and the convenience of the FXMLLoader. However, once loaded into memory, the View is still just a collection of Java objects.

With that in mind, in this article, I’ll go through how to implement the MVC pattern in both hybrid (Java/FXML) and Java-only systems.

JavaFX MVC is deployed entirely in Java, although some elements are loaded from other files

To apply MVC in JavaFX, we’ll need to apply three principles:

  1. View logic should be included in the Controller and defines how information is displayed and interacted with
  2. Business logic should be included in the Model and defines how data can be accessed, created, stored and changed
  3. Each View should have one simple and consistent narrative or purpose. In many complex applications there can even be multiple views within a window. In fact that often helpfully breaks down the responsibilities and enables the code to be reused elsewhere in the program.
The MVC pattern facilitates re-use of code across multiple windows or apps with minimal modification of code

The MVC Pattern overall should facilitate re-use of code across multiple windows or apps with no modification of the modular elements.

Without MVC, we tend to commit to tighter coupling between the business logic and the view logic. That means that if you need to make changes to anything from behaviour to data validation, you’re committing to significant refactoring.

What you’ll get from this article

In this article, you’ll get everything you need to design, implement and structure a JavaFX project using MVC structure.

Table of contents:

There are a lot of different ways to implement MVC in JavaFX. The implementation depends on the complexity of the user interface, preference, and environment. Correspondingly, this article comes with a disclaimer that this is my advice on how to create relatively simple JavaFX apps with a reusable, modular MVC pattern.

Roles and responsibilities of Model, View and Controller

The MVC pattern fundamentally separates the responsibilities for data, control and visualisation into separate objects. These objects should work together to process user input, store data, and visualise it to the screen.

The MVC design pattern in JavaFX powers event-driven UI design

By creating MVC architecture using the FXML/Java hybrid, we can separate view logic from business logic, and in the process we’ll generate reusable classes that we can use over and over again.

You keep mentioning them… but what are business logic and view logic?

That’s a fair question, and there can be some overlap (where the view logic implements some higher principle based on the business rules or logic), but here are some examples of each:

Business Logic

  • What format should a user’s street address take?
  • What happens if two users sign up, simultaneously taking the last spot
  • Should a user be able to update their email address, and how should it be validated?

View Logic

  • What happens when a User clicks the ‘OK’ button?
  • How many records should I display in my table at one time?
  • Which fields need to be complete before the OK button is activated?*

*Some view logic – like “which fields need to be complete before the OK button is activated” will be based on business logic (and business rules), such as “users must have both an email address and a postcode.

The MVC design pattern can seem confusing, because as soon as you mention it, people start talking about domain models, aggregate roots, and repository patterns.

There’s nothing wrong with a good aggregate root (as my mum always used to say