• Dec
    • 11
    • 2011

JavaFX and MVP – a smörgåsbord of design patterns

Posted by In Uncategorized
This entry is part 8 of 15 in the series Building JEE applications in JavaFX 2.0

Things are getting pretty exciting in the land of JavaFX. The platform seems to be gaining traction and we’re starting to see a real community build up around the forums and the open source channels. As a result we’re also seeing more developers moving beyond the ‘hello world’, and ‘colourful circles’ stage and setting their sights on real application development. With that comes a need for design patterns and best practices and these are currently lacking, or at least lacking in documentation.

In this post, I’m going to run through a few options for implementing the Model View Presenter (MVP) pattern using JavaFX. If you’re not familiar with MVP it’s basically the latest re-branding of the MVC pattern. The ‘Controller’ has been replaced with a ‘Presenter’ but the same big concepts apply. To be honest there’s so many variations and interpretations on MVC that you may already be using MVP under the guise of MVC anyway. This article does a decent job of quickly outlining the key differences, but there are loads more articles on the web. Martin Fowler, has provided a lot of analysis on MVP as well, and has split the term further.

We’re not going to get too hung up on theoretical purity and academic classifications however. Our goal is to get a usable pattern in place that just works, making it easier to develop and maintain a complex, production grade project. The theoretical semantics can be left to the academics who don’t have to build real world apps for a Monday deadline.

First Contact

First things first, we need an application to build. Something a little more complex than HelloWorld but still simple enough for us to easily work with. A very basic contact management system (i.e. an address book) should do the job. We’ll call it ‘First Contact’, and for the sake of simplicity it will have only two screens: a search screen that lets you filter the list of contacts, and a detail screen that lets you view and edit the basic details of each Contact.

The ‘search’ screen will look a little like this:

And the ‘detail’ screen will look something like:

The Business Layer

We’ll design the system as if the data was coming from a remote server (and probably a database) but since this post is all about UI design patterns we will just provide a local stub for this and not worry about the remote aspects (though you can easily use my earlier post on using Hessian to replace the local implementation with a remote one).

Our business layer consists of just a simple Contact bean, a ContactService interface for accessing the store of contacts and a local stub-implementation of this service for us to work with. The code for each of these is fairly trivial:

A note on Dependency Injection

If you’ve read my previous posts you’ll know that I’m a bit of a Dependency Injection (DI) fan, and I’d definitely recommend using either Guice or Spring as a DI toolkit to wire up your JavaFX applications.

I realise however that DI can seem like a magical and perhaps complex thing for a lot of people unfamiliar with it (a lot of desktop developers have not had a lot of exposure to it yet). I’m going to let you in on a little secret though: there is no magic to dependency injection. Seriously, all it means is to pass an instance into anther class rather than instantiating or looking it up from within that class itself. This has the rather fancy name of “Inversion of Control”, which just means the bean is no longer in control of looking up the resources, the thing that creates the bean has to look it up and pass it in.

So this:

public class MyClass
{
    private MyOtherClass myOtherClass;

    public MyClass()
    {
        this.myOtherClass = new MyOtherClass(); // or jndi.lookup("myOtherClass"), etc;
    }
}

becomes this:

public class MyClass
{
    private MyOtherClass myOtherClass;

    public MyClass(MyOtherClass myOtherClass)
    {
        this.myOtherClass = myOtherClass;
    }
}

If you’ve never taken the plunge into DI before, you’re probably wondering what all the fuss is about; if it’s just passing variables around, why is everyone always banging on about it. The answer to that is that while the pattern itself is incredibly simple, when you combine it with things like aspect-oriented-programming, annotations, mock objects for testing, etc this tiny shift starts to have powerful advantages.

So, in the interest of not scaring anyone off, and just to demonstrate how simple DI actually is, I’m going to avoid using any DI framework in these patterns. You won’t see any Guice or Spring in the following code. I’ll still use DI (i.e. I’ll pass variables in instead of instantiating them) but I’ll just wire it all up in plain, regular Java with no magical help from Guice or Spring.

Obviously, I’d recommend that you get familiar with and use a DI toolkit in your apps – depending on how I go for time, I may post the Spring and Guice equivalents of the below MVP patterns in a future post. If you’re keen to see this, post a comment to let me know.

The Patterns

Enough pre-amble, let’s get to it! Below are five different ways to build the same First Contact GUI outlined above. They all work, they are all OK. Some people will like one and others will prefer another. I have my favourites but it is totally up to you which one you choose to use.

Option 1: Keeping it Simple

In this option we use the most basic approach possible. Since we’re using MVP we obviously have a Model a View and a Presenter for each component on the screen.

Our View is focused solely on the visual representation of the screen; it is what the user sees. The View builds the layout of the controls and sets the styling but does none of the processing logic. When a user action occurs (such as a button click) the View passes this on to the Presenter for handling.

Our Presenter is then responsible for the ‘control’ logic. In this case it is responsible for interacting with our ContactService to load and save contact information. The Presenter is responsible for all threading and error handling. It is the brains behind the view and in many ways is the ‘boss’ of the view. If a button is clicked in the view, it is the Presenter that decides what happens and it then tells the View what information to show.

In this simple MVP scenario, our Model is just the Contact bean, which we defined as part of our Service model. It is a regular Plain Old Java Object returned by the ContactService. Unlike the more traditional MVC approach, the model in this case is somewhat temporal; the Presenter grabs a fresh Contact or list of Contacts from the Service every time the screen is loaded and passes this to the View. Once the data is loaded into the fields within the view, the bean is then discarded. In this approach our Model is more like a Data Transfer Object (DTO), used to transfer the data between our view and our ‘true’ model, which is the database hidden by our server.

Looking at our proposed UI, we obviously have two main screens: the ‘search’ screen and the ‘detail’ screen. As such, we’ll need a View and a Presenter for each of these. We’ll step through the more interesting bits of these now, but for reference, the full code for each of these is here:

Looking at our two views, the ContactSearchView and ContactDetailView, we see that these just create the controls needed and lay them out appropriately. When it comes time to handle a button click however, they simply call onto their Presenter (which has been passed into them via the constructor following the DI pattern).

In both views, the data they display (i.e. the search results and the contact details) is passed to them and neither view has any knowledge of how that data was loaded or the semantics behind that data. The ContactSearchView for example has no idea whether the terms in the search TextField match the data in the results ListView – this is not it’s job, like a good soldier, it just does what it is told, whether that’s right or not.

The Presenters are the more interesting players in this game. At the request of the View, these Presenters perform some threading to access the ContactService. This threading is overkill when we have a local service implementation (as we currently do), however if you are making remote calls you need to use Threads (see this slightly outdated post about it). I use a Task here, and given our Presenters are simply calling onto a service, Tasks are nearly always sufficient. You could easily substitute a Service but that is only useful if the code you are executing within the thread is complex and you want to reuse that code in several places.

So we have our two Views and two Presenters and they are nice, stand-alone modules. We need to integrate them however into our bigger application and provide a way to switch between these two views. To do this I have introduced another View, called the MainView, and a corresponding Presenter, called the MainPresenter. The MainPresenter contains the ‘search’ and ‘detail’ presenter and it controls which one is currently active and showing. The MainView is basically just a BorderPane with a header. Its content area (i.e. its center) acts much like a ‘CardLayout’, allowing the MainPresenter to swap the SearchView and DetailView in and out.

We provide both the ContactSearchPresenter and the ContactDetailPresenter access to the MainPresenter (via DI), so that they can request a change in the currently active screen. For example, the ContactSearchPresenter detects when a Contact has been selected in the search results and then it asks the MainPresenter to show the details for that Contact. This provides us with some reasonable decoupling, although it would be even better to use an event bus of some kind to control this navigational change. That’s one of the things JFX Flow does however, so if you want to go down that road I would suggest looking into JFX Flow before rolling your own solution (see option 5 below).

All we need to do now is wire up our three modules. As mentioned in the pre-amble, I’m not going to use Spring or Guice, which just means I have to do a bit more coding. All I really have to do is create a Factory for the whole UI and provide a factory method for each of the components of the application. To wire everything up I just call onto the factory methods as needed. This is really quite simple and you can see the code for yourself here:

Finally we just create an Application class to be the entry point for our First Contact application. Since most of the heavy lifting happens in our factory, the Application class is really quite simple; it just needs to create a new factory and extract the MainView from this and add it as the root of the scene. The code for this can be seen here:

Option 2: Interfaces for the purists

This second option is very similar to Option 1, however we introduce interfaces for all our Views and Presenters. This approach will probably be popular with purists and people from a strong dependency injection and aspect-oriented-programming background as it allows you to totally decouple your view and presentation implementations from each other. GWT developers also may find this approach comfortable as it is the recommended GWT design pattern (not surprising, since Guice and GWT are close friends).

Others, especially those coming from a more script-oriented language, such as Flash or JavaScript will probably be horrified by this ‘unnecessary’ bloat. This is a legitimate drawback to this approach – you end up with a lot of classes. I admit to being quite partial to this approach however (probably because of my JEE background, where this sort of thing is common place and familiar) but it is not for everyone. I also like FXML and as you’ll see in option 4, FXML does not lend itself to using this form of the pattern, so the debate becomes irrelevant if you’re using FXML anyway.

The code changes are really quite simple, where we had a single View before we now have a View (which is an interface) and a ViewImpl (which is the implementation of that View). Similar for the Presenter. These classes all then reference each other only by their interface, and only the factory class actually has any awareness of the implementations, which is what any purist will tell you is “as it should be”.

We end up with the following:

And our Factory now looks like this:

One of the big benefits of this approach is that it allows you to easily use Mock objects to test your components (although UI testing is still a messy topic at best so the benefits of this are only valid if you are going to put in the effort to actually test your GUI).

Option 3: MVP with a PresentationModel

In this option we introduce the concept of a PresentationModel, which is a model that represents the state of the view. In the case of the search view, for example, the model holds the current text in the search text field and the list of results showing in the results list.

So we end up with a Model for each of our three modules, like so:

Our Presenters then populate these models when they get data back from the server (instead of passing the data to the view directly). Our Views bind to the model properties (bidirectionally), so that whenever a change happens on the model it is reflected on the screen, and vice versa.

Our MainModel may look a little weird. Why does a Model have a Node in it? Remember that this is a ‘presentation’ model, and the ‘state’ of the MainView is really which sub-view it is showing. A node in the model is ok in this case. If we wanted to get pedantic (and someone always does) then we could have an enumerated type for the currently showing sub-view and this could be our model value, with the MainView mapping that to the appropriate Node. If you like that sort of stuff however, you might want to have a look at JFX Flow, which uses a ‘Place’ to represent the current active page and a whole lot more.

One positive with this approach is that it does allow us to make use of JavaFX bindings, which have been sadly unhelpful in our other options. On that basis, you would think the resulting code would be simpler and cleaner, but I don’t find it overly nice – there’s a lot of extra code for no obvious gain that I find useful. You are free to make up our own mind.

This pattern could be a lot more useful if we weren’t designing for a client-server application. If our Model could live in memory on the client side then having a shared model between the screens might become a lot more useful. These kind of applications are not overly common these days though (I haven’t had to make one since 2002).

You could also argue that we already have a PresentationModel in our other options. Each JavaFX Control contains a ‘model’ of sorts. For a TextField, this is the ‘text’ property, for a ListView it is the list of items. In this scenario however we create a model that is ‘control agnostic’ (meaning the model has no idea what type of control is being used to display the data) and then we expose that model to both the view and the presenter.

A quick academic side note: if we look at Fowler’s descriptions of MVP, then this approach is more in line with his Supervising Presenter pattern, whereas our previous options have been more the flavour of his Passive View pattern (where we use a DTO to pass the attributes to the view, and this DTO just happens to be our domain object).

Option 4: FXML and the MVP compromise

If you haven’t had a chance to play with FXML yet, I recommend giving it a go. FXML is an XML-based toolkit for building JavaFX scenes using a syntax that is simple enough for designers and junior coders to use, while still allowing your power coders to hook in and do the real work.

I’m usually the last person to advocate anything other than data being defined in XML and I’ve always hated XML GUI coding tools in the past. It’s strange then that I’ve come to like FXML but the key difference between FXML and other XML coding toolkits that I’ve seen is the clear separation of roles between view and control. In many other platforms, the XML ends up as a scripting language, and it is so verbose and clumsy for this that the resulting scripts are almost comical. In FXML the XML part is used only for layout, for any actual coding/logic, there is a natural fall-out to a ‘backing bean’ or controller.

So if FXML provides the controls and visual layout for our screen it is obviously a prime candidate for replacing the Java-based View’s we’ve defined in our previous options. This is good news, but it’s not all roses however. FXML has been designed with RAD tooling in mind (i.e. visual screen design tools), and seems to draw from backgrounds that are a little less rigorous in their design patterns than Java normally encourages.

As a result there are a number of areas where using FXML forces us to compromise on our pure MVP pattern. Here’s a few of them:

  • You have to specify your presenter (which FXML directly calls a controller) implementation inside your FXML. This breaks a fundamental concept of MVP, that the view and presenter should be decoupled as much as possible, and means you cannot reuse your view with another controller without copying the whole view again.
  • You can’t use interfaces for your presenter (as per option 2 above), since FXML needs a concrete class to instantiate.
  • The FXML loader instantiates the controller in internal code that we have no access to, so to make this work with a DI framework you have to jump through hoops to get setter injection to work (and constructor injection doesn’t work at all).
  • In order to access the fields of your view within your presenter (i.e. to show data on the screen), you have to expose the fields directly to the presenter using @FXML annotations. This means your presenter ends up knowing far too much intimate detail about your view.

There are a number of other smaller issues (like Controller inheritance not being supported) but for me, the end result is still better than not using FXML – the compromises are worth the benefits of the concise view syntax and simple notation for designers (i.e. it’s not too far a stretch for someone who know how to write HTML). There are also a couple of enhancements in the pipeline for JFX 2.1 that will improve (but not completely solve) some of these issues. You can make up your own mind whether the benefits are worth it to your or not.

So how does this FXML/MVP compromise look? First, the easy bits. We can directly convert our Views to FXML. This is very simple and the resulting code is quite a bit nicer:

There is one hurdle however, there’s no easy way to define our custom list renderer (i.e. the CellFactory) in FXML, it’s just too cumbersome. We end up having to define this within our presenter, which is not ideal.

Our Presenters are quite significantly different. Instead of interacting with a nice, contained view, the Presenters now have to access the plumping of the view directly. That is, they need to get a reference to the actual controls they want to interact with and manipulate them directly.

It’s worth noting that in the next release of FXML there is plans for bidirectional binding support, which will improve this somewhat, but it is unlikely to decouple our Presenter completely from the internal workings of the FXML defined View. The custom CellFactory is one example of this, and another is the need to have our callbacks include ‘view’ events such as the ActionEvent parameter needed for the ‘search’ method.

Here’s how our FXML-based Presenters look:

As I mentioned, we also now have some extra complexities in loading and wiring up our Presenters. The FXMLLoader does the instantiating for us, so we can’t use constructor based injection, instead we have to fall back to manually calling ‘set’ for every resource needed by each view.

You can see all the gory details here:

  • FirstContactAppFactory.java
  • All in all, a definite compromise on purity for the sake of convenience. I personally feel it is one worth making and am using FXML in all my applications. You can make up your own mind.

    Option 5: JFX Flow and MVP

    And finally, we have JFX Flow, which is a framework I’ve put together to provide some extra tools when working with JEE style applications, especially those you want to look more like a browser-based web-app. If you haven’t done so yet, check out the runnable showcase on the homepage for a general overview.

    JFX Flow can actually be used with any of the design patterns above. It is however designed with FXML in mind and encourages a pattern similar to that outlined in option 4. One of the biggest changes however, is that you don’t need a MainPresenter or MainView at all. These are provided for you out of the box with JFX Flow via the Browser class.

    The FXML for the JFX Flow option is identical to option 4, with no actual changes needed. The Presenters are similar in structure, however there are a couple of key changes.

    • Each Presenter needs to extend the JFX Flow AbstractActivity* base class.
    • Since we no longer have a MainPresenter, we need to use a NavigationManager instead. Each Presenter gets registered with Browser with a unique ‘place name’ that the NavigationManager can be used to navigate to.
    • We can use the activated() method to detect when a Presenter is made the active page. Any parameters needed for the page are passed to fields marked with the @Param annotation.
    • When we execute a task, instead of creating a new Thread directly we make use of the AbstractActivity.execute(Task) method. This gives us better error handling and blocks the screen while the load is in progress – two things we conveniently ignored in our earlier patterns.

    * Note: In JFX Flow I have opted for the term ‘Activity’ instead of Presenter and you will see this throughout the documentation. The two terms are interchangeable and just for consistency in this post I have left it as Presenter in the sample code. The Activity term has been popularised by GWT and I feel is a better fit than either ‘Controller’ or ‘Presenter’ (especially since JFX Flow does not dictate the use of either of these). The end result is quite nice and logical: a user navigates to a ‘Place’ to carry out an ‘Activity’.  

    Here are the JFX Flow versions of our Presenters:

    Our factory is where the Presenters are registered with the Browser:

    And our Application entry point now needs to use the Browser instead of the MainView:

    If we run this application as is, we see a GUI like following:

    Notice that the Browser bar has appeared for us, and we now have a back, forward and refresh buttons all for free. As we navigate between screens we see page transitions (the default is to fade in and fade out, but you can configure your own), and the screen will be blocked while our background threads are running.

    This is all pretty neat and more powerful than our previous patterns (otherwise there wouldn’t be much point to JFX Flow!). However it is not exactly the task we were given. We wanted to build an app identical to the others and currently we have this toolbar up the top and we don’t see our nice blue header.

    Luckily we can change that. The JFX Flow Browser provides a setHeader() method which can be used to completely replace the toolbar at the top. All we have to do is create a small class for our header and set this in its place. I’ve been lazy and just done this in code, but you could of course do this in FXML as you want:

    This is a very simple way to customise the Browser, however JFX Flow fully supports you totally redesigning your Browser and structuring it however you want. You can set the header (or set it to null) as described, or provide your own custom skin class, and if that isn’t enough for you, the tools are there to piece together your own Browser completely and build whatever layout you want with side-docking panes, shortcut bars and history lists (I’m working on this docco for this, promise!).

    Conclusion

    Well I hope that’s been a helpful introduction to JavaFX with the MVP pattern. There are plenty of other ways to put together a clean JFX application (and I’d love to hear from people out there if they have any improvements or alternatives) but the ones listed above should provide you with a nice base to work off.

    Obviously I have a strong preference to the JFX Flow approach and would suggest that your life will be a lot easier when building large, page-based GUIs if you make use of this framework. When it comes to design patterns however, it’s a case of finding the right shoe for the foot: I hope this article helps a few of you on your path to finding your Cinderella.

    Series Navigation<< JFX Flow early accessJavaFX and Maven >>

    25 Comments

    • csh
      January 4, 2012

      As far as I understood and did in the past, the Presentation Model only has a View and the Model. No need for a Presenter. I’d put all the logic from the Presenter class together with the Model class.

      Opinions about that?

      also see: http://blogs.adobe.com/paulw/archives/2007/10/presentation_pa_3.html

    • toni
      February 1, 2012

      Hello zonski. I started to play around with jfxflow. i am very happy to us it.. its very nice!!
      I am now having several Activities.. for all of them i have to set the NavigationManager like setNav…
      How can i solve this Depenencies with Guice in MainModule. Actually i see DI now as something really helpful but i don’t see the a nice solution for setting NavigationManager’s :-( I would be very glad to have some help for this issue.. Thank you very much for your effort!! Best regards, T.

    • zonski Author
      February 2, 2012

      If you use Spring or Guice you just need to have your Activity be included as part of your appcontext/module and then have your NavigationManager included in that same appcontext/module. Then in your activity use the @Inject annotation to have your NavigationManager be injected into it.

      For some tips on having your activities be included in the app context see: http://www.zenjava.com/2011/10/23/better-controller-injection/

      If you use this as a base, just then have another @Bean method that returns your NavigationManager (you will also need to wire up your Browser so that it uses this same NavigationManager).

      Hope that helps, I have been sidetracked recently with a client project (that is using JFX Flow so it has allowed me to test out some ideas, etc) but I am planning to spend some more time in this space very soon.

    • Alan
      March 4, 2012

      I would love to see you using Spring or anything and handle that with DI.
      I don’t know much about it, would be nice.
      Thanks for the time for putting this up.

    • zonski Author
      March 4, 2012

      Hi Alan,

      I have done a Spring-based implementation in this blog here: http://www.zenjava.com/2012/02/20/porting-first-contact-to-spring/

      Cheers

      • Alan
        March 5, 2012

        Very cool!
        Thanks man, sure will check it out and try it!

    • Slavko
      March 20, 2012

      Hi! I need a little help implementing the pattern #4. Namely, I’m using a resource bundle for GUI labels, prompts etc. in my FXML templates, and I just can’t seem to make this pattern work. I keep getting exceptions, like: javafx.fxml.LoadException: Base location is undefined. I just don’t know what am I doing wrong, so can you tell me does this has something to do with my resource bundles, or is it something else? Thanks!

    • zonski Author
      March 20, 2012

      Hi Slavko,

      This is just a weird thing in the FXMLLoader. Since I don’t use resources in my example I haven’t had to do this, but when you manually create the FXMLLoader (instead of using the static load methods), you need to specify a whole lot of things that should really be there by default.

      Try this:

      FXMLLoader loader = new FXMLLoader();
      loader.setBuilderFactory(new JavaFXBuilderFactory());
      loader.setLocation(getClass().getResource(“/fxml/your-fxml-file.fxml”));
      loader.load(getClass().getResourceAsStream(“/fxml/your-fxml-file.fxml”));

      • Slavko
        March 20, 2012

        YES! It’s working! Thanks!!!

        For those to whom it may concern: you have to add one more line on the zonski’s code:
        loader.setResources(ResourceBundle.getBundle(“path.toYour.resourceFile”));

    • zonski Author
      March 21, 2012

      Ah yea, I missed the most important one, sorry about that!

      For an example of the whole load process, check out the FxmlLoader from JFX Flow:
      http://code.google.com/p/jfxflow/source/browse/trunk/src/main/java/com/zenjava/jfxflow/actvity/FxmlLoader.java

    • Slavko
      March 21, 2012

      Oh, I thought that you’ve left me to do some thinking… :) Thanks for the link, it’s very helpful!

    • Slavko
      March 21, 2012

      Me again… :) There is one concern I have with this (DI) pattern: memory optimization. With this setup, all the application’s objects exist in the memory, whether they’re necessary or not. If an average standalone app has, say, 30 odd screens, that’s a lot of system memory consumed for no reason. Is there some way to release unnecessary controllers and views when? And load them again if necessary, of course…

    • zonski Author
      March 22, 2012

      This depends a little on the design of you GUI. Most of the ones I work with you tend to navigate through the screens in a pretty random way and its better to have all the screens loaded into memory rather than create and destroy them each time (which can slow things down, etc). Having 30 screens in memory is generally not a huge performance hit, but it does depend a lot on what you are showing on those screens (e.g. if they are just forms then its probably not too bad, but if they are large image editors, etc then you could run into trouble).

      It would be pretty easy however to change the MainPresenter so that instead of having each of the views injected into it, it could have a view factory injected for each of the view types. Then in the onShowX methods you would call the factory method to create a new view instance.

      The old view/presenter should get garbage collected when the new view is activated but to be clean you might want to also dispose of them. This can be done whenever a new view is shown, so in the onShowX method you could check for the last view and then call a dispose() method (i.e. create a ‘Presenter’ interface that has this dispose method on it that you call in a generic way). Then you could release resources in your dispose method.

      In fact I would recommend not using a factory and instead use activate(), deactivate() methods on your presenters. In these methods I would obtain and release the resources needed by the the view/presenter as needed. That way you keep just one instance of the view but the memory footprint is pretty light (components/controls don’t really take up much memory on their own) with images, etc, being loaded and discarded as needed.

      A lot of this is getting close to what JFX Flow does however, you might want to look at how the NavigationManager works in Flow for more ideas on lifecycle management. I’m not entirely happy with the way I’ve done the ‘Place’ and the @Param stuff in Flow though so this area might change before Flow makes it out of alpha (if I ever get time to do that!).

      • Slavko
        March 29, 2012

        OK, thanks!

    • mwalter
      April 1, 2012

      Hi! Isn’t it possible to use CDI instead of setters to inject the services into the presenters?

    • July 2, 2013

      I am actually glad to read this web site posts which contains
      plenty of helpful information, thanks for providing such statistics.

    • July 10, 2013

      That is a great tip especially to those new to the blogosphere.
      Brief but very accurate information… Thank you for sharing this one.
      A must read post!

    Leave a Comment