Skip to content
Advertisement

Ordinary object variable or JavaFX object property?

I’m working on an JavaFX app and trying to follow Model-View-Controller pattern. I have implemented the Model with ordinary java objects(Double, Integer, String…) thinking I would re-use the model in non-JavaFX projects. However, I found it very difficult to make the View update automatically when the Model changes without properties. Before I change every variable into a property, I would like to ask if it is right to implement the Model only with JavaFX properties.

Advertisement

Answer

I helped design and (re-)architect a large Java GUI app for my company when we switched from Swing to JavaFX. One of the foundational decisions we made upfront was to embrace JavaFX properties wholesale. We used them in all of the model code, even in backend code that didn’t have any ties to the GUI.

Very important: this went hand-in-hand with designing our model to be single threaded. In particular, all model updates had to be done on the JavaFX thread. There was significant resistance to this idea since our previous application was heavily multithreaded and folks were reluctant to give that up. Long story short, we switched all of our I/O and computations to be non-blocking. It was a lot of work but it worked out in the end. It turns out a single thread can do a lot of work if you never block. This decision almost singlehandedly eliminated all of our race conditions and other multithreading bugs, which is a huge win in my book.

Using JavaFX properties was a great decision and I heartily recommend it. Code style-wise, we saw a lot of upsides: it’s easy to listen to property changes, easy to add reactive code that dynamically updates other properties, easy to register functional-style bindings that could let us use idioms like map and reduce throughout our code.

The only real style downside saw was the addition of a lot of boilerplate. It basically takes 4-6 lines of code to declare a new property. You need the property variable, a getter, a setter, and a getter for the underlying property object. To save on vertical space I insisted that these items be compacted to one line each, and that they be kept together rather than spread throughout the source file. For example:

/** User's first and last name. */
private final StringProperty nameProperty = new StringProperty("name");
public ReadOnlyStringProperty nameProperty() { return nameProperty; }
public String getName() { return nameProperty.get(); }
private void setName(String name) { nameProperty.set(name); }
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement