0

Here it is said that we have 2 options to implement MVVM with JavaFX - it depends whether we want to use JavaFX-Properties in our model or not.

As I understand if my model doesn't have javafx properties then I add fx properties to ViewModel. However, I can't understand what I should do if my model has fx properties. What should I do this case? Something like this:

class ViewModel {
   private ObjectProperty<Person> personProperty = new SimpleObjectProperty<>();
   ...
   personProperty.set(person);
}

or I should duplicate all the properties of the Person in ViewModel and bind every ViewModel property to Person properties, to get View -><- ViewModel -><- Model? Could anyone explain what to do this case?

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • 1
    I don't know if I truly understand the question but here are my two cents. Properties used in this manner are usually used to keep up with a selection in a `TableView` or `ListView`. @James_D has a great example [here](https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx). – SedJ601 Mar 21 '19 at 14:49
  • 1
    @Sedrick The link you provided is about `MVC`. My question is about `MVVM` that is quite a different pattern. – Pavel_K Mar 25 '19 at 14:27

1 Answers1

2

There are 2 solutions with their own advantages and drawbacks.

If you want to stay 100% true to the MVVM pattern your View may not know any model classes. Therefore it's not allowed to give a personProperty from the ViewModel to the View. Instead you have to duplicate the fields of the model class as properties in the ViewModel, for example "firstnameProperty". These properties can now be used (typically by data-binding) in the View. The View doesn't know anything about a model class 'Person'. Instead it only knows the properties that the ViewModel provides.
However, now you have to keep these properties in sync with the actual model instance in the ViewModel. To make this easier some time ago I've created the ModelWrapper util as part of the mvvmFX framework. In addition to classic Java POJOs it also supports classes with JavaFX Properties. You can see the a usage example in the tests of the class here. It uses a Model class with JavaFX properties (here). This is the recommended approach. However, depending on the complexity of your model classes this can get tricky. For complex models with a deep structure you might need to write your own logic to keep the properties in sync with your model classes. This is one of the trickiest parts of MVVM pattern.

The other approach is to relax the limitations of the MVVM pattern and to pass the Model instance to the View. This can be a solution if your Model class has lots of fields and it would be to much code to duplicate each field in the ViewModel. However, this way you are introducing a dependency from your View to your Model which is agains the idea of MVVM.

Manuel Mauky
  • 2,116
  • 4
  • 21
  • 25
  • I've read your answer again and the following question rose in my head - what about tables? The table is in View, but how can't the table know about Model (which instances are shown in the table)? As I understand in this case ViewMode has ObservableCollection of Models, but the code that builds cells (from Model fields) is in View, so View knows Model. Could you explain? – Pavel_K Apr 11 '19 at 16:12
  • @Pavel_K One solution is to create a separate class (i.e. `PersonTableViewModel`). This class acts like a Data-Transfer-Object between Model and View. It wrapps the actual model instance and has getters for all columns of the table. The parent-ViewModel provides an observableList of these table-VMs for the view. You can see an example [here](https://github.com/sialcasa/mvvmFX/blob/develop/examples/contacts-example/src/main/java/de/saxsys/mvvmfx/examples/contacts/ui/master/MasterTableViewModel.java). This class can also enhance values for the table view. – Manuel Mauky Jul 22 '19 at 12:04