• Oct
    • 23
    • 2011

JavaFX 2.0, FXML and Spring

Posted by In Uncategorized

This entry is part 1 of 15 in the series Building JEE applications in JavaFX 2.0

Richard Bair recently posted the results of his experiments with FXML Dependency Injection using Guice. I’m a big fan of Guice but Spring is the most popular application development framework for enterprise Java (that’s what their website says anyway), mainly because it offers much more than just a DI framework, with support for databases, transactions, remoting, security and much more.

As such, I’m intending for this post to be the first in a series, called Building JEE applications in JavaFX 2.0, where I’m going to explore various options for doing just that. This is new territory for everyone, so I welcome all feedback and comments that can help us refine the ‘best practices’ in this ares.

In this first post I’m just going to do a direct port of Richard’s FXML+Guice example into Spring. A lot of people still think Spring is all about XML configuration files, but it has evolved a lot since those early days. I’m going to use Spring’s annotation based configuration to create a pure Java example (i.e. zero Spring XML) that looks almost identical to the Guice one.

For those that want to skip the details and get straight to the code, you can find it here: http://code.google.com/p/jfxee/source/browse/trunk/jfxspring/

Note that this is a Maven project – I’m not going to go into detail on this in this post (I will later though), but it is a very simple project structure. If you’ve not used Maven before you can add your own ant scripts to the project or work out how to use Maven (both Eclipse and IntelliJ can open the pom.xml for you and just work).  

Step 1: create a Person bean:

This is pretty much the same as Richard’s


public class Person
{
    private String firstName;

    public Person(String firstName)
    {
        this.firstName = firstName;
    }

    public String getFirstName()
    {
        return firstName;
    }
}

Step 2: create a SampleController

This is similar to Richard’s however instead of using Guice’s @Inject annotation, we use Spring’s @Autowire one (I’ve annotated the parameter but you could use constructor injection if you want):

import org.springframework.beans.factory.annotation.Autowired;

public class SampleController
{
    @Autowired
    private Person person;

    public Person getPerson()
    {
        return person;
    }

    public void print()
    {
        System.out.println("Well done, " + person.getFirstName() + "!");
    }
}

Step 3: create the FXML file

This is identical to Richard’s, except I used the getPerson().getFirstName() instead of a getPersonName() – Richard could have done the same, no real difference on this.

<?xml version="1.0" encoding="UTF-8"?>

<?language javascript?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<StackPane fx:id="root" xmlns:fx="http://javafx.com/fxml">
    <children>
        <Button fx:id="printBtn" onAction="controller.print()" />
        <fx:script>printBtn.text = 'Click Me ' + controller.getPerson().getFirstName() + '!';</fx:script>
    </children>
</StackPane>

Step 4:  Create a Spring Application Context

Here’s where things start to get interesting. Instead of the Guice ‘Module’ we need to define a Spring equivalent. In this case I have defined a class called SampleAppFactory (but you can call it anything) – the important bit is that it is annotated with Spring’s @Configuration. Each of the methods that are then annotated with @Bean belong to the context and Spring can do magic wiring for us. In our case the SampleController will get wired up with the Person because of the @Autowired annotation on it.

For anyone used to Spring XML, this class is pretty much a direct replacement of the XML configuration file:

import org.springframework.context.annotation.Configuration;

@Configuration
public class SampleAppFactory
{
    @Bean
    public Person person()
    {
        return new Person("Richard");
    }

    @Bean
    public SampleController sampleController()
    {
        return new SampleController();
    }
}

Step 5: Build a custom FXML loader

We can easily build the Spring equivalent of Richard’s GuiceFXMLLoader. It just needs to load the controller from the application context instead of the Guice Injector. In my next post I’m going to look at how we can simplify this and clean things up a little.

import javafx.fxml.FXMLLoader;
import org.springframework.context.ApplicationContext;

import java.io.IOException;
import java.io.InputStream;

public class SpringFxmlLoader
{
    private ApplicationContext context;

    public SpringFxmlLoader(ApplicationContext context)
    {
        this.context = context;
    }

    public Object load(String url, Class<?> controllerClass) throws IOException
    {
        InputStream fxmlStream = null;
        try
        {
            fxmlStream = controllerClass.getResourceAsStream(url);
            Object instance = context.getBean(controllerClass);
            FXMLLoader loader = new FXMLLoader();
            loader.getNamespace().put("controller", instance);
            return loader.load(fxmlStream);
        }
        finally
        {
            if (fxmlStream != null)
            {
                fxmlStream.close();
            }
        }
    }
}

Step 6: Create an ‘Application’ to launch it all

This is quite similar to the Guice approach, except we load our application context instead of the Guice injector:

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SampleApp extends Application
{
    public static void main(String[] args)
    {
        launch(args);
    }

    public void start(Stage stage) throws Exception
    {
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext(SampleAppFactory.class);
        SpringFxmlLoader loader = new SpringFxmlLoader(context);

        Parent root = (Parent) loader.load("/sample.fxml", SampleController.class);
        Scene scene = new Scene(root, 320, 240);
        scene.getStylesheets().add("/fxmlapp.css");
        stage.setScene(scene);
        stage.setTitle("JFX2.0 Sprung");
        stage.show();
    }
}

That’s it! As you can see the code is extremely similar to Guice so the choice between Guice and Spring should depend on the other features offered by each and how these may benefit you. I’m going to stick with Spring for this series, but a lot of what I go through could easily be adapted back to Guice.

Continue Reading→
    • Oct
    • 23
    • 2011

Better Controller Injection

Posted by In Uncategorized

This entry is part 2 of 15 in the series Building JEE applications in JavaFX 2.0

There are two things about our controller injection in our last post that I’m not entirely happy with. The first is that the SampleApp is the one responsible for loading the FXML file and wiring it up to the controller. We have a factory class for our UI (SampleAppFactory) so ideally all the work of creating and wiring up all the GUI elements should be done in here.

The second s that Richard’s post came from his earlier exploration of future directions for FXML and the discussions around that. Some of these features are not available yet, so Richard has found some creative ways to demo the concepts using scripting and the namespace. We probably don’t want to be using this style of coding for commercial apps so until the next release of FXML we need to work with what we’ve got – i.e. we need to have an explicitly named controller class in the FXML and let the loader instantiate our class and do our bindings. This has some drawbacks but using Spring (or Guice’s) annotation based configuration, we can make it work well enough.

For those that want to skip the details and just see the code: http://code.google.com/p/jfxee/source/browse/trunk/jfxspring2

So let’s first revert to the standard way of loading controllers in FXML and ditch the magical namespace and scripting. This standard way is well documented in the official FXML guide: http://download.oracle.com/javafx/2.0/api/javafx/fxml/doc-files/introduction_to_fxml.html

Our controller is now going to be defined and created in the FXML file, but using Spring’s (or Guice’s) annotation based injection we can still inject all the dependencies (so long as we use field injection and not constructor injection). One challenge though will be that both our controller and our view need to be available through the factory. The controller needs to be  exposed in order to get the Person bean injected into it, but our view needs to be exposed so that it can be added to the scene. The complication is that the FXML loader creates both in a single call, so we need to get creative.

There are a lot of ways to solve this problem, but the one that works best both now and for future benefits is to give the controller a reference to its view. Anyone wanting the view, can then just access the controller from the factory and retrieve the view from it.

So if we revert our controller back to the more traditional form, giving it access to its view is a simple case of binding the root node of the FXML to a variable in the controller. To keep life simple we’re not going to bother including the Person name on the button for now – we’ll add this back in later, it just confuses things at this stage. Here’s how it looks:

SampleController.java

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import org.springframework.beans.factory.annotation.Autowired;

public class SampleController
{
    @FXML private Node view;
    @Autowired private Person person;

    public Node getView()
    {
        return view;
    }

    public Person getPerson()
    {
        return person;
    }

    public void print(ActionEvent event)
    {
        System.out.println("Well done, " + person.getFirstName() + "!");
    }
}

sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?language javascript?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<StackPane fx:id="view"
           fx:controller="com.zenjava.jfxspring.SampleController"
           xmlns:fx="http://javafx.com/fxml">
    <children>
        <Button text="Click Me" fx:id="printBtn" onAction="#print" />
    </children>
</StackPane>

Great, we now have a nice, simple, traditional controller. The whole point of this however was to get dependency injection working. Haven’t we lost this now that the controller is being created by the FXMLLoader? Not quite, luckily with Spring’s annotation based configuration we are free to create the controller anyway we want, the injected properties are set only when we return the controller from a factory method marked with @Bean. Let’s update our factory then to use the new controller. At the same time we will also remove the FXML loading from the SampleApp class and move it inside the factory – this was the second problem we wanted to solve.

Here’s how our factory now looks:

import javafx.fxml.FXMLLoader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;

@Configuration
public class SampleAppFactory
{
    @Bean
    public Person person()
    {
        return new Person("Richard");
    }

    @Bean
    public SampleController sampleController() throws IOException
    {
        return (SampleController) loadController("/sample.fxml");
    }

    protected Object loadController(String url) throws IOException
    {
        InputStream fxmlStream = null;
        try
        {
            fxmlStream = getClass().getResourceAsStream(url);
            FXMLLoader loader = new FXMLLoader();
            loader.load(fxmlStream);
            return loader.getController();
        }
        finally
        {
            if (fxmlStream != null)
            {
                fxmlStream.close();
            }
        }
    }
}

And here’s the start method for our SampleApp class. We’ve been able to remove the FXMLLoading from here – the application has no knowledge of how the views are loaded. If we wanted to change the view to be a normal Java class instead of FXML neither the controller, nor the application would need to be updated. Only the factory, which is responsible for creating the view, would need to be changed as you would expect.


public void start(Stage stage) throws Exception
{
    AnnotationConfigApplicationContext context
            = new AnnotationConfigApplicationContext(SampleAppFactory.class);

    SampleController sampleController = context.getBean(SampleController.class);
    Scene scene = new Scene((Parent) sampleController.getView(), 320, 240);
    scene.getStylesheets().add("fxmlapp.css");
    stage.setScene(scene);
    stage.setTitle("JFX2.0 Sprung");
    stage.show();
}

All in all, a somewhat cleaner setup.

It’s worth noting that there are some definite limitations and disadvantages to using the traditional controller binding approach. All of these have been raised with the JFX team (in JIRA) and several are being actively explored for future releases. In my opinion, although these drawbacks are annoying, at this stage they are worth living with since by using the official controller option we don’t have to use scripting or namespaces, so our app will be easier to maintain and be better supported by RAD tools and will be easier to get help and find docco on.

For the record however the limitations to be aware of are these:

  • The Controller class is specified in two places – the FXML and then cast-to in the factory. If you forget to update your FXML (very easy to do) then you will get a class cast exception in the factory. Ideally we would not have to specify the controller in the FXML at all.
  • You cannot use constructor injection – since the FXML is instantiating the controller, it must have an empty constructor.
  • Callback methods for button clicks must have an ActionEvent as part of the signature. This is easy to forget and will result in a runtime method. With the scripting option you did not have this restriction (the tradeoff being that you could not get the MouseEvent for mouse-style callbacks).
  • You cannot use the same FXML definition with different instances of a controller, i.e. you cannot attach sample.fxml to a controller other than SampleController without duplicating the FXML file.
  • You are limited to a single controller per FXML file, so you couldn’t have sample.fxml trigger callbacks in both SampleController and another controller.
  • You cannot share the same controller across multiple views as the loader will create a new controller for each FXML file. You couldn’t reuse the same SampleController instance used by sample.fxml with another fxml file, there will be two instances of SampleController created.
  • FXML does not support controller base classes. If your controller extends a base class and that base class has an @FXML annotated field on it, it will not get picked up by the FXMLLoader. You must define all @FXML attributes in the actual controller class itself.
There are probably a few other minor limitations but they are the big ones that I can think of.
In the next post we're going to look at what happens when you have a couple of controllers and ways to share information and navigate between them.

Continue Reading→
    • Oct
    • 24
    • 2011

Multiple Controllers with Shared Resources

Posted by In Uncategorized

This entry is part 3 of 15 in the series Building JEE applications in JavaFX 2.0

In this post we’re going to create two controllers that share a common resource. We will start with something simple and unimpressive in this post and refine it into something more useful in subsequent posts.

For now we will create two controllers, one that allows us to edit our Person object, and another that provides a friendly welcome message for that person. Here’s how it will look:

To keep things simple, I’ve just placed the two views on the same top-level page and we’re not using property bindings so you will have to hit the ‘save’ button before hitting the ‘show welcome’ button. The goal here is to simply show how two controllers can share resources – we’ll create a more architecturally elegant solution soon enough.

Our code now consists of two controllers, EnterDetailsController and WelcomeController, and these each have a corresponding FXML file, EnterDetails.fxml and Welcome.fxml. These are pretty unexciting and straight forward – you can check out the code directly for more details. The only interesting thing in our controllers is that they both define the following:


@Autowired private Person person;

This tells Spring that we want the Person to be injected (aka ‘wired up’) automatically.

In our factory, we now load each of the controllers in separate methods in the factory and annotate these methods with @Bean. Spring will then inject the same person instance into each. Even though we create a new Person in the person() factory method, Spring knows to cache the result and reuse it for all injection because of the @Bean annotation.

Our factory now looks like this:

@Configuration
public class SampleAppFactory
{
    @Bean
    public Person person()
    {
        return new Person();
    }

    @Bean
    public WelcomeController welcomePageController() throws IOException
    {
        return (WelcomeController) loadController("/Welcome.fxml");
    }

    @Bean
    public EnterDetailsController enterDetailsController() throws IOException
    {
        return (EnterDetailsController) loadController("/EnterDetails.fxml");
    }

    protected Object loadController(String url) throws IOException
    {
        InputStream fxmlStream = null;
        try
        {
            fxmlStream = getClass().getResourceAsStream(url);
            FXMLLoader loader = new FXMLLoader();
            loader.load(fxmlStream);
            return loader.getController();
        }
        finally
        {
            if (fxmlStream != null)
            {
                fxmlStream.close();
            }
        }
    }
}

That’s it – sharing resources in a nice way via Dependency Injection is actually incredibly simple. It ought to be, that’s really what dependency injection is all about!

Of course, our example is still pretty raw and clunky but we’ll work on this over the next few posts to clean it all up.

The full source code for this post can be found at: http://code.google.com/p/jfxee/source/browse/trunk/jfxspring3/

Continue Reading→
    • Oct
    • 25
    • 2011

Views within Views, Controllers within Controllers

Posted by In Uncategorized

This entry is part 4 of 15 in the series Building JEE applications in JavaFX 2.0

GUIs are like onions (and Ogres) – they have layers. There are very few GUIs out there that show a single screen and that’s it. In traditional desktop applications we often end up with a screen full of complex sub-views, some tab panes perhaps, and often way too many popup dialogs. In a web app, we usually end up with a series of interconnected pages that hyperlink between each other, many of which contain sub-pages of information within them.

In either case we end up with the problem of how to embed and link our views and yet still keep them as nice, contained, reusable modules of code. At the core of it, all the presentation frameworks and architectures out there aim to address this issues in some way or another and FXML is no different. We just specify <fx:include> in our FXML file and the loader will magically pull in a second FXML file and drop it into our parent file. Great!

But there’s a problem. We’ve just come up with a great way to use dependency injection with our controllers and share resources between them, but this requires us to expose our controllers through the factory with the @Bean annotation. If the FXMLLoader magically creates our sub-views and sub-controllers for us, we’re back to square one.

So we need another way. In fact we need to make a mental gear change for this and come at it from another angle. The FXML approach assembles views by creating aggregates of other views, the controllers are somewhat of an afterthought. Sub-controllers have no real knowledge of their parent or child controllers, yet the views do. When we stop and think about this, shouldn’t it be the other way around? Our controllers should be the ‘brains’ of the operation, the views are just there to look pretty and smile.

Looking at if from this new angle, what we really need is a way to assemble controllers with sub-controllers and have these tell their corresponding views how to connect up with each other. As it turns out we’ve just put a mechanism in place for doing just that – dependency injection and a factory is exactly what we need to make this work.

In the rest of this post, I’m going to walk through a small example that has a three controllers. The MainController provides the outer container and a way to switch between the two sub-controllers (Page1Controller and Page2Controller) using a tab pane style approach. I’ll keep the controllers deliberately simple to get the idea across and, as usual, we’ll add more complexity in later posts.

Our end GUI is going to look something like this:

Let’s start with the simple stuff. Our two sub-pages will be simple, dumb controllers and views, just to give us something to work with. You can see the code for these here:

Now for the interesting stuff. Our MainController needs to provide a way to switch between the views – two buttons will do for this for now. It also needs a place for the sub-views to appear, and in our FXML this will just be a panel that acts as a container. Our FXML looks like this:

Main.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane fx:id="view"
            fx:controller="com.zenjava.jfxspring.MainController"
            xmlns:fx="http://javafx.com/fxml">

  <styleClass> <String fx:value="welcome"/> </styleClass>

  <top>
    <HBox spacing="4">
      <children>
        <Button text="Show Page 1" onAction="#showPage1"/>
        <Button text="Show Page 2" onAction="#showPage2"/>
      </children>
    </HBox>
  </top>

  <center>
    <BorderPane fx:id="contentArea"/>
  </center>

</BorderPane>

So it’s left to our MainController to actually show the appropriate view when each button is selected. To do this it needs to get hold of the Page1 and Page2 controllers and then it can happily access the views for each. Using Spring’s @Autowired annotation we can easily achieve this, so long as all three controllers are exposed by our factory class. It all looks a little like this:

MainController.java

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.layout.BorderPane;
import org.springframework.beans.factory.annotation.Autowired;

public class MainController
{
    @FXML private Parent view;
    @FXML private BorderPane contentArea;

    @Autowired private Page1Controller page1Controller;
    @Autowired private Page2Controller page2Controller;

    public Parent getView()
    {
        return view;
    }

    public void showPage1(ActionEvent event)
    {
        contentArea.setCenter(page1Controller.getView());
    }

    public void showPage2(ActionEvent event)
    {
        contentArea.setCenter(page2Controller.getView());
    }
}

SampleAppFactory.java

import javafx.fxml.FXMLLoader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;

@Configuration
public class SampleAppFactory
{
    @Bean
    public MainController mainController() throws IOException
    {
        return (MainController) loadController("/Main.fxml");
    }

    @Bean
    public Page1Controller page1Controller() throws IOException
    {
        return (Page1Controller) loadController("/Page1.fxml");
    }

    @Bean
    public Page2Controller page2Controller() throws IOException
    {
        return (Page2Controller) loadController("/Page2.fxml");
    }

    protected Object loadController(String url) throws IOException
    {
        // as before (see full code for details)
    }
}

In the end, embedding views and controllers is actually quite simple with this approach. Architecturally it feels pretty clean, each of our child controllers is a stand-alone, reusable piece of code. Our parent controller has some fairly intimate relations with its children, and often this will be OK. In a lot of cases however, we will want a parent that is less tightly bound to its children. In the next post we’ll have a go at achieving that.

The full code for this post can be found at: http://code.google.com/p/jfxee/source/browse/trunk/jfxee4

Continue Reading→
    • Oct
    • 26
    • 2011

Generic Controllers

Posted by In Uncategorized

This entry is part 5 of 15 in the series Building JEE applications in JavaFX 2.0

Now that we’ve created a few of these Controllers we’re seeing a bit of similarity between them. They all have an attached view and up until now we’ve duplicated the same code in all of them for dealing with these.

Let’s take this opportunity then to clean things up a little and define a generic controller framework. This base framework will be very simple for now, but as we start to head into more complicated areas of JEE application building (such as threading, communicating with servers, and navigating between controllers) this Controller setup is going to provide us with a strong foundation to build on.

Our first step is to create a Controller interface that all controller instances will implement. The only thing we need to know from our controllers at this stage is their attached view, so the interface will provide for this:

import javafx.scene.Node;

public interface Controller
{
    Node getView();
}

Next we can create an abstract base class and we can move the duplicated code from our controllers into this so it’s defined in one nice spot:

import javafx.scene.Node;

public abstract class AbstractController implements Controller
{
    // Problem! This value will not be set by the FXMLLoader since the
    // loader does not detect annotated fields in base classes
    @FXML private Node view;

    public Node getView()
    {
        return view;
    }
}

This looks pretty good, but unfortunately the current version of FXML does not map fields that are defined in a base class of the controller, even if that field is annotated with @FXML. There is a JIRA issue for this, but for the time being we have to find a work around.

Our cheat here is to manually inject our view into our controller when loading it in the factory. Luckily we can get hold of the root of the view from the FXMLLoader and then we can just pass this to our Controller in code.

Our factory load method now looks like this:

protected Controller loadController(String url) throws IOException
{
    InputStream fxmlStream = null;
    try
    {
        fxmlStream = getClass().getResourceAsStream(url);
        FXMLLoader loader = new FXMLLoader();
        Node view = (Node) loader.load(fxmlStream);
        Controller controller = (Controller) loader.getController();
        controller.setView(view);
        return controller;
    }
    finally
    {
        if (fxmlStream != null)
        {
            fxmlStream.close();
        }
    }
}

And we’ve had to expose a setView() method on our controller Interface, and implement this in our AbstractController class. This is not ideal since we don’t want anyone actually ever calling this setView() method, but it does get the job done.

Controller.java

import javafx.scene.Node;

public interface Controller
{
    Node getView();

    /**
     * This method is needed only to allow the loadController() method in SampleAppFactory to
     * inject the view into this controller. Ideally FXML would allow us to specify @FXML on
     * in AbstractController on the 'view' field and this method would not be needed.
     */
    void setView(Node view);
}

AbstractController.java

import javafx.scene.Node;

public abstract class AbstractController implements Controller
{
    private Node view;

    public Node getView()
    {
        return view;
    }

    public void setView(Node view)
    {
        this.view = view;
    }
}

It’s a simple case now to refactor all of our controllers to use these base classes. For more details see the full source code for this post at: http://code.google.com/p/jfxee/source/browse/trunk/jfxee5/

Continue Reading→
    • Nov
    • 03
    • 2011

Client Server with JavaFX 2 and Hessian (+Guice +FXML)

Posted by In Uncategorized

This entry is part 6 of 15 in the series Building JEE applications in JavaFX 2.0

Ok, due to popular demand, I’m going to fast track a bit of this walk through. I had planned to do more on the client end first, but it seems everyone wants to know how to build a client-server app (apparently that Internet thing has really taken off).

So in this post we’re going to build a very simple hello world client-server application, using HTTP. We’re going to use Hessian to make all our client-server communication nice and easy. There are a whole load of other communication options out there but Hessian is simple, lightweight and just works.

By the looks of it people are favouring Guice over Spring at this stage, due to the concept of it being ‘lightweight’. As such, I’m going to stick with Guice as our DI toolkit for the front-end. In later posts we’ll have a look at changing over to Spring, which really starts to show its advantages when we start working with database transactions and security.

This topic is a little more in-depth than some of the previous stuff. If you’ve never written a servlet or basic web application before, you may want to brush up on this first. Also, we’re going to use some JavaFX threading which is only lightly documented at this stage, and the API is just a little raw still too in my opinion. It may be a bumpy ride for some.

The full source code (as a multi-module maven project) can be found at: http://code.google.com/p/jfxee/source/browse/trunk/jfxee7/

Step 1: Design your application

We’re going to keep things as simple as we can. We will have a simple client that allows the user to enter their first and last name. The client will then pass these details to the server and the server will return a simple welcome message based on the name entered.

If we get everything right, our client will end up looking like the following:

Step 2: Create a Service interface

The great thing about Hessian is that it allows us to define our client-server protocol in pure Java objects. It works in a very similar way to RMI, where you define an interface for your server, which your server implements and client accesses. Hessian then provides the magical wiring underneath our interface to serialize our data and send it (over HTTP) to the server, where it gets deserialized and passed into our server implementation. Pretty sweet.

For our example, our service interface is very simple and looks like this:

public interface HelloService
{
    String sayHello(Person person);
}

This is our ‘contract’ between the client and the server. The client will call the sayHello method and the server will implement it.

We could pass two strings into the sayHello method for the first name and last name, but to make things a little bit interesting and show the power of Hessian, I have chosen to encapsulate all this in a Person bean. Hessian will magically handle all the serialization for this.

Our person bean is a standard serializable Java bean and looks like this:

import java.io.Serializable;

public class Person implements Serializable
{
    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName()
    {
        return firstName;
    }

    public String getLastName()
    {
        return lastName;
    }
}

Step 3: Create a Service implementation

Now that we’ve defined the contract between our client and server, we need to have our server fulfill that contract. We’re keeping things simple in this example: our server will simply build a message out of the Person details and send this back to the client. In a real world application, your server will likely hit a database, provide some security and do all the other things that a serious application does, but we won’t worry about that here.

Our service is just another Java object that implements the HelloService interface we defined above. The only special thing about it is that it extends HessianServlet, which is a custom servlet provided by the Hessian platform. All the magic happens in here and by simply extending it we have a ready-to-roll server implementation. Too easy.

Our service implementation looks like this:

package com.zenjava.jfxee7;

import com.caucho.hessian.server.HessianServlet;

public class HelloServiceImpl extends HessianServlet implements HelloService
{
    public String sayHello(Person person)
    {
        // in the real world, use a logging API like slf4j or log4j
        System.out.println(String.format("The server received a request from %s %s",
                person.getFirstName(), person.getLastName()));

        return String.format("The server says hello %s %s!",
                person.getFirstName(), person.getLastName());
    }
}

Step 4: Run your server as a web application

The next step is to publish our service as a web service. I’m going to assume you are at least a little familiar with creating normal servlets and building webapps. If not, you probably want to google these topics – there’s a wealth of information out there on this, just ask Google.

To publish our service we create a web.xml that loads our HelloServiceImpl as a servlet. The HelloServiceImpl is no different to any other servlet and can be exposed in exactly the same way:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <servlet>
        <servlet-name>HelloService</servlet-name>
        <servlet-class>com.zenjava.jfxee7.HelloServiceImpl</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloService</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>

From here you simply have to bundle your application into a war file and then deploy it to a server. I use Maven for all my builds and this makes this step extremely easy. Check out the example POM for this. If you’re using ANT (maybe it’s time to upgrade :) ) then you might find something like this helpful: http://javabeanz.wordpress.com/2009/02/12/how-to-create-a-war-file-using-ant/

The resulting war file can be deployed to any servlet friendly server. I use good old Tomcat but you can use Jetty, Resin or any of the other free ones out there. If you’re insane, you can pay for one of the commercial JEE servers (but really, don’t bother).

Step 5: Create a view and controller

Our server is now deployed and running, and we’re ready to build our client. The first part is easy, we just build a GUI to service our needs. I’m going to use the same Guice + FXML approach as in my last post but you could use the Spring approach, or even roll it all by hand and use no Dependency Injection at all if you’re into an old-fashion style.

Here’s our view:

<?xml version="1.0" encoding="UTF-8"?>

<?language javascript?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox fx:id="view"
      fx:controller="com.zenjava.jfxee7.HelloController"
      spacing="6"
      xmlns:fx="http://javafx.com/fxml">

    <styleClass><String fx:value="enterDetails"/></styleClass>

    <children>

        <Label fx:id="messageLabel" text="Waiting for your input">
            <styleClass><String fx:value="message"/></styleClass>
        </Label>

        <Label text="First Name"/>
        <TextField fx:id="firstNameField"/>

        <Label text="Last Name"/>
        <TextField fx:id="lastNameField"/>

        <Button text="Connect to Server" onAction="#submit"/>

    </children>
</VBox>

And here’s our controller:


import com.google.inject.Inject;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;

public class HelloController
{
    @FXML private Node view;
    @FXML private Label messageLabel;
    @FXML private TextField firstNameField;
    @FXML private TextField lastNameField;

    public Node getView()
    {
        return view;
    }

    public void submit(ActionEvent event)
    {
        // todo implement this to talk to the server
    }
}

Step 7: Use Guice to load the UI and inject the service

In order for our client to connect to the server, all it needs to do is use the HelloService interface we created earlier and use Hessian to load this. The following code will do the trick:

HessianProxyFactory factory = new HessianProxyFactory();
String serverUrl = "http://localhost:8080/hello";
HelloService helloService = (HelloService) factory.create(HelloService.class, serverUrl);
// use the helloService object now and hessian will magically make the calls on the server for you

This is basic Hessian stuff – we use the HessianProxyFactory to create a new instance of our HelloService for us, passing in the URL of our server. The factory then creates a ‘proxy’ (in this case, you could call it a ‘stub’), that implements the interface by making HTTP calls onto the servlet on the server side. The Proxy and the servlet work together to serialize the data between each other and make the actual call on the server. From our end, it’s all just nice simple Java.

We could create this proxy anywhere in our code and use it via plain Java calls and for this simple little scenario that would do the job. In our last post however we looked at ways to use Guice to load our controllers and provide Dependency Injection and this is a great candidate for this. As our project gets bigger and we end up with more controllers wanting to use more services, this DI is really going to pay off.

In order to inject our service using Guice, we first add the following line to our HelloController:

@Inject private HelloService helloService;

And now we can just wire up everything in our Guice module. I’m going to use instance injection in this case, but you could use the provider style approach just as easily. The instance injection approach looks like so:

import com.caucho.hessian.client.HessianProxyFactory;
import com.google.inject.AbstractModule;
import javafx.fxml.FXMLLoader;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;

public class HelloClientModule extends AbstractModule
{
    protected void configure()
    {
        try
        {
            HessianProxyFactory factory = new HessianProxyFactory();
            String serverUrl = "http://localhost:8080/hello";
            HelloService helloService = (HelloService) factory.create(HelloService.class, serverUrl);
            bind(HelloService.class).toInstance(helloService);

            bind(HelloController.class).toInstance((HelloController) loadController("/Hello.fxml"));
        }
        catch (MalformedURLException e)
        {
            // NOTE: this is not best-practice for exception handling. Check the
            // Guice documentation for better ways.
            throw new RuntimeException(String.format("Error connecting to server"), e);
        }
        catch (IOException e)
        {
            // NOTE: this is not best-practice for exception handling. Check the
            // Guice documentation for better ways.
            throw new RuntimeException(String.format("Error loading FXML file"), e);
        }
    }

    protected Object loadController(String url) throws IOException
    {
        InputStream fxmlStream = null;
        try
        {
            fxmlStream = getClass().getResourceAsStream(url);
            FXMLLoader loader = new FXMLLoader();
            loader.load(fxmlStream);
            return loader.getController();
        }
        finally
        {
            if (fxmlStream != null)
            {
                try
                {
                    fxmlStream.close();
                }
                catch (IOException e)
                {
                    System.out.println("Warning: failed to close FXML file");
                }
            }
        }
    }
}

And then to launch our application, we simply have:


import com.google.inject.Guice;
import com.google.inject.Injector;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class HelloClient extends Application
{
    public static void main(String[] args)
    {
        launch(args);
    }

    public void start(Stage stage) throws Exception
    {
        Injector injector = Guice.createInjector(new HelloClientModule());
        HelloController helloController = injector.getInstance(HelloController.class);
        Scene scene = new Scene((Parent) helloController.getView(), 320, 240);
        scene.getStylesheets().add("styles.css");
        stage.setScene(scene);
        stage.setTitle("JFX2.0 Sprung");
        stage.show();
    }
}

Step 8: Call the server in a background thread

So we have a server and a client, and our controller has access to the server via the HelloService. Now we can just make the following call in our controller right?

public void submit(ActionEvent event)
{
    Person person = new Person(firstNameField.getText(), lastNameField.getText());
    String messageFromServer = helloService.sayHello(person);
    messageLabel.setText(messageFromServer);
}

There’s two problems with this though: threads and exceptions.

Now that the call to sayHello() is actually a remote call to a server it could be slow. Depending on the network speed it could take seconds for the client and server to do all the socket and serialization work. Java FX (like Swing) uses a single thread for application processing. If we lock this thread up waiting for the server to respond then our UI will become unresponsive as the application thread won’t be able to process mouse moves or even redraw the screen (this is a slight simplification of how threads and rendering work in JFX but from our point of view this is enough for us to know).

As well as the threading issue, we’ve also introduced a lot more room for things to go wrong: the server may be down, the client may have lost internet connection, the wrong URL may have been entered, etc. These will all be thrown as runtime exceptions so we could just ignore them and have the system crap out but this is not very nice for our users. Ideally we need to start handling these errors and show the user a friendlier message, such as “Hey mate, did you forget to plug in your network cable again?”, so they can actually do something about it and try again.

Fortunately JFX has an answer to both of these problems, and that answer is the Worker/Task/Service framework. Unfortunately this is not a simple toolkit to use (although if you are familiar with SwingWorker you will have a good head start) and even more unfortunately there is extremely little documentation on this as yet. The only real guide that I’ve found is this post from Richard that uses an early version of the framework while still in beta. The API has been tidied up a little since and Richard also neglected to give us too much detail on how to actually handle the response from the server, or handle errors.

We can muddle through it however, and by piecing all the bits together here’s a threading approach that works:

public void submit(ActionEvent event)
{
    // extract person details from the screen
    final Person person = new Person(
            firstNameField.getText(),
            lastNameField.getText()
    );

    // pass the details to the server in a worker thread
    final Task task = new Task()
    {
        protected String call() throws Exception
        {
            return helloService.sayHello(person);
        }
    };

    // handle the result
    task.stateProperty().addListener(new ChangeListener()
    {
        public void changed(ObservableValue source,
                            Worker.State oldState, Worker.State newState)
        {
            if (newState.equals(Worker.State.SUCCEEDED))
            {
                messageLabel.setText(task.getValue());
            }
            else if (newState.equals(Worker.State.FAILED))
            {
                 // always log your system errors with stack trace (please!!!)
                messageLabel.setText("Oh no, a system error, we're all going to die!");
                Throwable exception = task.getException();
                exception.printStackTrace();
            }
        }
    });

    // start the task in a thread
    messageLabel.setText("Contacting server...");
    new Thread(task).start();
}

As you can see this approach uses a ‘Task’, which is the simplest unit of the Worker framework. The Service base class is much more powerful (you can cancel active threads for example) but is more complex to use. For an example of using a Service, check out this forum topic: https://forums.oracle.com/forums/thread.jspa?messageID=9928424&#9928424

We also have pretty simple exception handling here. Ideally we would check the type of the Exception thrown and provide an error message to match. To do this we just use a big if-else statement and instanceof like so:

else if (newState.equals(Worker.State.FAILED))
{
    Throwable exception = task.getException();
    if (exception instanceof HessianConnectionException)
    {
         messageLabel.setText("Couldn't connect to the server, sorry about that.");
    }
    else
    {
         // always log your system errors with stack trace (please!!!)
         messageLabel.setText("Oh no, a system error, we're all going to die!");
         exception.printStackTrace();
    }
}

A note on building, deploying and running

Above are all the bits and pieces we need for our client and server communication and if you’re familiar with web applications and this style of development that’s probably all you need to know. Simply deploy your generated WAR file to your web server, edit the URL in the client to match and then run HelloApplication. Sorted.

For anyone who is not familiar with this stuff however, there are a few gotchas to be aware of when it comes to deploying and running. Firstly is how to package all of this up. You have two separate applications now, a client and a server, but they both share the common service API. You could bundle all the classes together and deploy it this way if you’re being lazy, but you should really separate them to avoid bloat, especially the client which typically is downloaded.

In my setup, I have one module (bundles into a jar) for the ‘common’ code, which includes the HelloService interface and the Person bean. Then my ‘client’ module has all my client code (bundled into a jar) and my ‘server’ module has all my server code (bundled into a war). The client and server then reference back to the ‘common’ module as if it were a third party library. It’s a little more complicated but it is the cleanest separation – you are free to make your own setup work for you.

When you deploy your web application the server will have a base address (such as http://zenjava.com) where the server (e.g. Tomcat) is running. When you run locally this address will typically be http://localhost:8080. Depending on how you deploy your WAR file it may then be allocated a sub-domain. In Tomcat for example, if you name your WAR file ‘helloserver.war’ and then put this into Tomcat’s ‘webapps’ directory, the URL you will need to use in your HelloClientModule is “http://localhost:8080/helloserver/hello”.

Ultimately you will likely want to deploy your client via webstart and then you will want it all bundled into your server (but not on the server’s classpath just for some added complexity). I’m not going to confuse people further with this here, if you can’t work out the packaging side of it yourself just run the client from within the IDE for now. I am planning to post something on doing this sort of complex deployment using Maven (our best friend in this situation) in a future post.

The above is hopefully enough to get you started on the road to developing client-server Java FX 2 applications over the web.

Enjoy!

The full source code for this post (as a multi-module maven project) can be found at:http://code.google.com/p/jfxee/source/browse/trunk/jfxee7/

Continue Reading→
    • Nov
    • 27
    • 2011

JFX Flow early access

Posted by In Uncategorized

This entry is part 7 of 15 in the series Building JEE applications in JavaFX 2.0

I started this blog a few weeks ago with the grand plan of stepping you through the process of building a clean architecture for building JEE, web-style GUI applications using JavaFX 2. As I wrote the first few blogs, I realised that if we stepped through each little twist and turn on the journey to a complete framework we’d be here for a few years. I also started to think that most of you probably don’t care about the details, you just want something that you can use so you can get on with the real job of building your applications and making your users happy.

So, “here’s one I prepared earlier”. The more attentive of you will have already noticed a new new link called ‘JFX Flow‘ in the menu bar above. Go on, click on it. In fact, have a flick through the ‘showcase’ linked to from the main page just to get a feel for what I’m talking about here.

This is an alpha version of a framework I’ve put together with all of my ideas in it for building web-style applications in JavaFX. I’m still fleshing out the documentation (yea, I leave the least fun stuff till last too) The core features are good enough to use right now (I’m using it in two of my projects currently, one which is a decent way along), however some of the supporting features (such as dialogs) are still a little rough around the edges and I can’t guarantee the API for some of these won’t change a little over the next few weeks.

It’s all free and open source. I’ve also tried as much as possible to make it so that you guys can customise bits and pieces without having to rewrite everything. If you want your own funky Browser that’s all in 3D and has flying magical dragons on it, you can write one (assuming you know how to use the javafx.magical.dragon package) and just plug it in.

I’ve deliberately limited JFX Flow to the GUI aspects of a JEE system. It’s goal is to allow you to build GUIs that provide the user with a familiar and enjoyable experience, and at a code level support dependency injection, have nice threading and error handling, and use a clean separation of concerns (view vs control, etc).

You won’t see anything in there specifically for database or server communication however. JFX Flow provides the ‘presentation’ tier only. It has ways to integrate with the back-end tiers but it does not give you an end-to-end JEE stack. JEE is at its best when it provides the developer with the freedom to mix and match technologies at each level of the stack. Specific projects always have their own specific requirements. Sometimes you need to use message queues and XML, sometimes you can make pure-Java RPC calls and can use Hibernate, and sometimes you might have to integrate with something weird like Google’s App Engine, or a legacy mainframe system. JFX Flow aims to give you that power, while making the front-end a bit easier to develop.

I’m guessing a lot of you probably still want to know how to do all that database and server communication stuff though. That’s what the rest of this blog will be about. Now that we’ve got a JavaFX presentation layer for our JEE stack, we can start looking at how this can be used for common scenarios. Those of you already familiar with the business and data layers of the JEE stack can go on ahead, JFX Flow is ready for you to use. The rest of you, stick with me and let’s see what we can come up with. For now have a play with JFX Flow and let me know what you like, and don’t like.

Continue Reading→
    • 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.

    Continue Reading→
      • Feb
      • 17
      • 2012

    JavaFX and Maven

    Posted by In Uncategorized

    This entry is part 9 of 15 in the series Building JEE applications in JavaFX 2.0

    For JEE application development, Maven is, in my opinion, a requirement. Sure you can use Ant, and that will give you more ‘control’ over you build, but you’ll be spending a fair chunk of time managing your build scripts – time that you could spend actually building your application. The two big reasons you want to use Maven for your JEE build are:

    1. Dependency management: Maven provides a free, web-hosted central repository which contains just about every major distributable toolkit out there. When you use Maven, you simply specify the toolkits you want to use and the version numbers, and Maven will automatically download the jars you need and setup your classpath.
       
    2. Minimal configuration build: Maven uses “convention over configuration”, which means if you follow its directory structure and naming conventions, you can avoid writing massive amounts of XML config. When assembling WAR or EAR files, which have some funny rules regarding WEB-INF directories and the like, Maven just makes all of this simple.

    I’m not going to waste time selling you further on this (a quick web search will find you hundreds of articles comparing Maven to other build tools). What we’ll do here now is step through how to create a Maven project for running JavaFX applications. In this post, I’m only going to get us to the stage where we can run a simple, pure-client JFX app in out IDE, but we’ll grow on this later to build multi-module projects with client and server components, and include ways to build JNLP deployment bundles for web deployment.

    Step 1: Download and install Maven

    You can get the latest version from here: http://maven.apache.org/download.html. It’s just a zip file and doesn’t need any special ‘installing’. I usually just grab the latest ‘Binary Zip’ and extract it locally. I tend to put all my applications (like Tomcat, Maven, Java, etc) under c:\apps (on windows) as this makes it real easy to type on the command line if I ever need to.So for me, I unzip Maven to in c:\apps\maven\maven-3.0.1 but you can do whatever you like.

    Once you have unzipped it, the only thing needed to install it is to add a system variable called ‘M2_HOME‘ that points to the directory you just unzipped to, and then update the PATH variable to include ‘%M2_HOME%\bin’. If you run into any trouble with this, check out this very detailed installation guide:http://www.sonatype.com/books/mvnref-book/reference/installation.html

    Step 2: Create an empty project folder

    Most IDE’s will generate you a skeleton Maven project these days, and Maven itself has the concept of project templates (called ‘archetypes’) that you can use to quickly generate a ready-to-use project structure but we’ll give these a miss in this round so you can see just how little magic is actually needed.

    We need to create a new directory to house our project, Maven doesn’t care where we put this directory.  I tend to use c:\dev for all my projects (again because it is easy from the command line), so if we’re creating a project called ‘MyJfxProject’, I would put it in a folder called c:\dev\myjfxproject.

    Step 3: Create an initial POM file

    The heart of every Maven project is the POM (or Project Object Model). This is just an XML file called  ’pom.xml‘ that lives in the base directory of your project. It tells Maven what features you want to use in your build (e.g. are you building a JAR or a WAR). Unlike an Ant build script however, this file is generally pretty light however, there’s a lot Maven can work out just from your project structure.

    At a minimum we need to tell Maven three pieces of information: our group ID, which is typically your domain name (so I use ‘com.zenjava’), our artifact ID, which is just the name of our project (so in this case we’ll use ‘myjfxproject’) and the version, usually it’s good to start with version 1.0. You can also do some cool stuff with snapshot versions, but we won’t get sidetracked with them right now. Here’s how our initial pom.xmlshould look:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.zenjava</groupId>
        <artifactId>myjfxproject</artifactId>
        <version>1.0</version>
    
    </project>
    

    Step 4: Create our source file structure

    Maven requires us to follow its convention for structuring our project. It doesn’t matter where our project base folder is, but within this base folder we need to use the Maven hierarchy. There is a lot to this, but we just need a place to store our Java files at the moment, Maven requires us to put these in the directory src/main/java. Any Java files in that directory will be automatically compiled and included in our resulting build.

    You can (and should) use sub-directories to get packages like normal. In my case I use the base package com.zenjava, but you should use a domain that suits you (your registered web domain is best, but if you don’t have one, just make up something sensible – not using a package structure is bad form).

    We will also want some non-Java resources (such as properties files, images, CSS style sheets and FXML files) included in our project. Maven requires us to put these in the directory src/main/resources. Any files in these directories will be automatically included in our final JAR. You can use whatever directory structure you want within the resources directory, I typically create a directory for each resource type. So our initial directory structure should look something a little like the following.

    c:\dev\myjfxproject
    
    - pom.xml
    + src
      + main
        + java
          + com
            + zenjava
              + myjfxproject
                - MyJfxProjectApp.java
        + resources
          + fxml
            -  (FXML files)
          + images
            -  (image files files)
          + styles
            -  (CSS files)
    

    Step 5: Add JavaFX as a dependency 

    In the introduction of this blog, I made the bold claim that the Maven repository “contains just about every major distributable toolkit out there”. There’s one notable exception to this however: unfortunately and frustratingly, JavaFX is not in there!

    There’s a couple of reasons for this. Firstly, there’s a licencing issue. Somewhat disappointingly Oracle has used a licence that allows us to redistribute JavaFX but only if as part of a bigger application. You can’t just redistribute the JAR on it’s own. Putting the JFX JAR in any public Maven repository would blatantly violate this licence. Oracle’s not likely to change this unfortunately, but once JavaFX is fully open sourced into the OpenJDK project (sometime this year, I believe) we should be able to get around this.

    The second reason is a technical one. JavaFX uses a number of native files (e.g. DLLs on windows) and Maven does not handle native files overly well. Native files need to be added to the java system path, whereas Maven’s whole dependency management is focused around the more common java classpath. Other libraries that use native files have found ways around this (such as the JOGL toolkit), but to support this the actual libraries themselves have to load their native files in a certain way, which the JavaFX guys are not doing (and as yet, are not intending to do). JavaFX requires its native files to be in a relative subdirectory (namely rt/bin), and Maven just doesn’t support this.

    So this seems like a bit of a show stopper: if we can’t add JavaFX as a Maven dependency we can’t use JavaFX in Maven. Fortunately there are a couple of hack options we can use to cludge around this problem. None of the options are perfect and they all sacrifice some of the niceness that we expect when using Maven, but the cludges are just good enough to get us through and still take advantage of the other great features that Maven offers.

    The easiest option, and my recommended approach, for getting a JavaFX dependency into Maven is to use the ‘system‘ scope. If you’re a regular Maven user, you may not even be aware this exists (I wasn’t) as it is very rarely used. This special scope allows you to specify a system path, which can reference the JAR file on your local system, rather than downloading it from the central repository. Maven no longer provides version management and automatic updates for us, but our native issue is resolved because we can reference the jar in its default installation location, which has the natives files relative to it.

    To do this you first download and install the JavaFX SDK as per normal. Then you just add a dependency like the following to your POM (change the system path to point to your JFX installation directory):

    <dependencies>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>javafx</artifactId>
            <version>2.0</version>
            <scope>system</scope>
            <systemPath>C:/apps/jfx2.0/rt/lib/jfxrt.jar</systemPath>
        </dependency>
    </dependencies>

    The groupId, artifactId and version are actually arbitrary in this case (you can put whatever you like in there). Normally Maven would use these to find the JAR in the central repository but because we’re specifying the JAR with the ‘systemPath’, Maven will ignore these other values.

    Several alternate options exist for getting Maven and JavaFX to play nicely together but the above is the simplest and easiest. Probably the most powerful alternative is to use a “pre-loader” that extracts the native files from a JAR file installed into Maven when your application runs (the JFXtras project has code in it to assist with this). If you’re not wanting to take advantage of the JFX/JNLP deployment tools (more on this in future posts) then this can be a good option for bundling JFX in your final JAR. There’s a fair bit of work involved in assembling and maintaining the native JAR bundles however, so I personally tend not to use this approach.

    It’s my hope that through a few of us working with the JFX team on this Maven issue that we’ll end up with a much cleaner solution for this in the future. There’s not a great deal of Maven experience in the JFX team however so it is slow going, and the future plans to co-bundle JFX with the JDK are also an influencing factor in this discussion. If JFX ends up in the JDK then version management and distribution will be intimately linked between these two taking Maven out of the game altogether (adding a whole new bucket of versioning and deployment complexities). There’s work to be done here still.

    Step 6: Open your project in your favourite IDE 

    We now have a fully operational JavaFX project and we can open this in our IDE. I use IntelliJ, which has fantastic, built-inn support for Maven. I simply go to File -> Open Project and then select the pom.xml file for my project. The result is a ready to run project with the classpath all set to include my source code, resources and third party libraries (in this case we’ve only added JavaFX but you can add as many dependencies as you like). I can also edit my POM file whenever I like (to add dependencies for example) and IntelliJ will automatically download the corresponding JAR files and update the classpath instantly.

    I know that Eclipse also has strong support for Maven, as I have often worked with developers using Eclipse while I was using IntelliJ on the same project (which is another advantage of using Maven). I’m not totally up on the steps to getting this working but you should be able to find more info here: http://www.eclipse.org/m2e/

    Additionally NetBeans also has support for Maven. Again I am not sure of the exact details, but this wiki seems to provide the right sort of information: http://wiki.netbeans.org/MavenBestPractices

    If anyone has experience in using Maven with either Eclipse or NetBeans (or any other IDE out there), please post additional information in the comments below.

    Step 7: Build your JAR file

    With just this simple POM setup, we can now quickly and easily build the JAR file for our application. You can usually do this via your IDE, but using the command line is just as effective. On windows open a Command Prompt (Start -> Run -> cmd), then change directory into your project home directory (e.g. cd  c:\dev\myjfxproject) and type the following command:

    
    mvn clean package
    
    

    You will see a whole lot of log that should finish with “BUILD SUCCESS”. Assuming you get to this point, then the jar file containing all of your application code and resources can be found in the newly created ‘target’ directory. You can take this jar and use it as normal.

    Beyond the basics

    Building a single JAR file is pretty cool, but generally we will want to build a ready to run deployable application. We can use Maven to do all sorts of wonderful things, including building web deployable JNLP based deployment bundles and applets, as well as executable jars containing third party dependencies. Not to mention generating JavaDoc, automatically running unit tests, creating full project documentation and much, much more.

    This does get quite a bit more complex however, and this blog post is already too long, so I will leave these more advanced topics to later. We’ll weave some deployment options into our future posts, especially when we look at building WAR files for our JEE-based server.

    If you’re desperate for more info on a more complete JNLP-based deployment build process and you’re feeling comfortable with Maven then you can find some workable options buried in this forum discussion. As always, feel free to post further questions in the comment section below, or post on the JFX forum if you have more general questions.

    Continue Reading→
      • Feb
      • 20
      • 2012

    Porting “First Contact” to Spring

    Posted by In Uncategorized

    This entry is part 10 of 15 in the series Building JEE applications in JavaFX 2.0

    In an earlier post we looked at different design patterns for building First Contact, our simple JavaFX-based contact management system. To keep things simple I deliberately avoided using Spring (or Guice) for the dependency injection and instead manually injected all the dependencies. This is great for educational purposes but really we’re doing things the hard way – Spring provides all sorts of magical things for making this easier, so let’s take advantage of them.

    We looked at five different design pattern options for implementing First Contact, but moving forward let’s just pick one and work with that. I’m going to go with “Option 4: FXML and the MVP compromise” as it lets us use FXML for the presentation layer, which I think is a big win. Option 5 also uses FXML, but it is based on my third-party framework, JFX Flow and although I’m confident that JFX Flow is a nice little framework to use, I want it to leave it out of the equation at this stage so you can get a good, clean understanding of how everything is working. The pattern used in option 4 is very similar to what Flow expects, so switching between the two should be relatively trivial (and I’ll most likely do a port of our final First Contact app to JFX Flow when we get it all working).

    So to give us a base to work off, we’ll make a copy of the source code from option 4, and then we’ll modify this to use Spring for dependency injection. The final source code for this blog can be found at: http://code.google.com/p/jfxee/source/browse/trunk/first-contact/first-contact-spring/.

    Step 1: Add Spring dependencies

    The first thing we need to do is get hold of the Spring JARs and get them on our classpath. Since we’re using Maven (check out my previous post on using Maven if you haven’t done so already) all we need to do is add the dependencies for the relevant Spring libraries to our pom.xml. Spring is made up of a whole suite of modules that we could use, but our requirements at this stage are quite simple. We just need Spring’s basic ‘context’ module for dependency injection. Since we’re using Spring’s annotation-based configuration (because I hate writing XML if I can avoid it), we’ll also need both the CGLIB module and the standard javax.inject library, which the annotation stuff in Spring makes use of.

    We can update our pom.xml to look like this:

    <?xml version="1.0"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-spring</artifactId>
        <name>JFX Contact Management System</name>
    
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
    
            <!-- JavaFX -->
    
            <dependency>
                <groupId>com.sun.javafx</groupId>
                <artifactId>javafx</artifactId>
                <version>2.0.beta</version>
                <scope>system</scope>
                <systemPath>C:/apps/javafx/javafx-2.0.2_32bit/rt/lib/jfxrt.jar</systemPath>
            </dependency>
    
            <!-- Spring and supporting toolkits -->
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>3.0.6.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2</version>
            </dependency>
    
            <dependency>
                <groupId>javax.inject</groupId>
                <artifactId>javax.inject</artifactId>
                <version>1</version>
            </dependency>
    
        </dependencies>
    
    </project>
    

    We’re reaping the rewards of using Maven here – just by adding those few dependencies to the pom.xml, Maven will automatically download the necessary JARs and put them on our application classpath. How easy is that!

    Step 2: Simplify the First Contact Application Factory

    Without Spring, we had to hand roll our own application factory. If you’ve forgotten what this looked liked, take a moment to look through our old FistContactAppFactory class. In this class we manually created all our beans, kept references to them, and then used setter methods to wire up everything (i.e. give each object access to the other beans it needed). The general pattern was something a little like this:

    public class FirstContactApplicationFactory
    {
        private SomeObject someObject;
    
        public SomeObject getSomeObject()
        {
            if (this.someObject == null)
            {
                this.someObject = new SomeObject();
                this.someObject.setSomeOtherObject1(getSomeOtherObject1());
                this.someObject.setSomeOtherObject2(getSomeOtherObject2());
            }
            return this.someObject;
        }
    
        ...
    }
    

    And we repeat this over and over again for each object we want to use. Lot’s of boring, copy-paste code.

    With Spring we can get rid of most of this boiler plate code. First we annotate our FirstContactAppFactory class with the @Configuration annotation. This is just a marker, that lets Spring know this class is an application factory capable of providing beans for dependency injection.

    Once we’ve done that we can then annotate each of the factory methods with Spring’s @Bean annotation. By doing this, we tell Spring that the resulting object is a bean that can be injected into other classes. We also tell Spring that we want the result of the method to be a singleton (this is the default for all beans in Spring, though you can change it if you want): Spring will then make sure the bean is only created once and the result will be cached and reused for every subsequent method call.

    With Spring now doing our singleton caching we can get rid of the manual caching we were doing. Our new pattern looks a little like the following:

    @Configuration
    public class FirstContactApplicationFactory
    {
        @Bean
        public SomeObject getSomeObject()
        {
            SomeObject someObject = new SomeObject();
            someObject.setSomeOtherObject1(getSomeOtherObject1());
            someObject.setSomeOtherObject2(getSomeOtherObject2());
            return someObject;
        }
    
        ...
    }
    

    This has saved us a fair bit of work already, but we can go one step further. Those calls to the setter methods are actually dependency injection, which is what Spring does for us so we can drop those as well (we need to also add some annotations on our Beans for this to work – see the next step). Our new pattern is now as simple as this:

    @Configuration
    public class FirstContactApplicationFactory
    {
        @Bean
        public SomeObject getSomeObject()
        {
            return new SomeObject();
        }
    
        ...
    }
    

    Pretty simple! Below is the source code for the updated FirstContactAppFatcory. All it really does is create all our presenters and return them (using the FXML loader rather than creating a ‘new’ instance, but the pattern is the same). I’ve also dropped the ‘get’ from the method names, this is just a convention thing – Spring tends to leave these off for factory methods (since they are not strictly getters anymore), but you can name the methods whatever you want.

    @Configuration
    public class FirstContactAppFactory
    {
        @Bean
        public MainPresenter mainPresenter()
        {
            return loadPresenter("/fxml/Main.fxml");
        }
    
        @Bean
        public ContactSearchPresenter contactSearchPresenter()
        {
            return loadPresenter("/fxml/ContactSearch.fxml");
        }
    
        @Bean
        public ContactDetailPresenter contactDetailPresenter()
        {
            return loadPresenter("/fxml/ContactDetail.fxml");
        }
    
        @Bean
        public ContactService contactService()
        {
            return new SimpleContactService();
        }
    
        private <T> T loadPresenter(String fxmlFile)
        {
            try
            {
                FXMLLoader loader = new FXMLLoader();
                loader.load(getClass().getResourceAsStream(fxmlFile));
                return (T) loader.getController();
            }
            catch (IOException e)
            {
                throw new RuntimeException(String.format("Unable to load FXML file '%s'", fxmlFile), e);
            }
        }
    }
    

    There’s a whole lot more that Spring can do for us – we are definitely only using the most basic of its features at this stage. For now though, that’s all we need and as you can see it’s made our code significantly simpler and easier to maintain.

    Step 3: Inject dependencies using annotations

    In the previous step we took away all those explicit setter calls in our factory methods (i.e. the manual dependency injection calls). We need to annotate our beans as well so that Spring knows to inject these classes for us now. For each of our beans, where we were previously calling a set method, we need to annotate the corresponding property instead. In fact, we can get rid of the setter altogether (if you want to leave it in, you can, but I tend to get rid of them) as Spring can access our annotated properties, even if they are private member variables with no getters or setters.

    So something like this:

    public class MyPresenter
    {
        private String myProperty;
    
        public void setMyProperty(String myProperty)
        {
            this.myProperty = myProperty;
        }
    
        ...
    }
    

    Becomes as simple as this:

    public class MyPresenter
    {
        @Inject private String myProperty;
    
        ...
    }
    

    Again we’re just removing some of the minor annoying boiler plate code and telling Spring we want it to take care of the dependency injection for us. For some before and after examples, check out the following changes:

    Note for long-time Spring users: the @Inject annotation is just the newer standards-based version of @Autowired. They are more or less interchangeable, however using the standards one allows us to change frameworks (e.g. move to Guice) with minimal fuss.

    Step 4: Change how the factory is loaded at startup

    Our factory and our beans are now all dressed up for the Spring dance, but we’ve still got to kick off the music. In our previous FirstContactApp we were manually instantiating a new instance of our FirstContactAppFactory and then accessing the main presenter by calling getter methods. This isn’t going to give Spring a chance to get in there and do all that magic autowiring stuff for us, so we need to change this slightly.

    As you’d expect, the code for this is pretty simple. All we need to do is  use Spring’s AnnotationConfigApplicationContext and let it instantiate our Factory for us so we can then use Spring’s standard bean lookup mechanism to get our fully wired-up beans:

    public void start(Stage stage) throws Exception
    {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(FirstContactAppFactory.class);
        MainPresenter mainPresenter = context.getBean(MainPresenter.class);
        mainPresenter.showSearchContacts();
        Scene scene = new Scene(mainPresenter.getView(), 800, 600);
        scene.getStylesheets().add("styles.css");
        stage.setScene(scene);
        stage.setTitle("First Contact - JavaFX Contact Management");
        stage.show();
    }
    

    Wrapping it up

    That’s all the changes we need to make. If you run your updated FirstContactApp main method, you should see exactly the same GUI as from our previous post. We’ve not changed any of the functionality, just simplified the plumbing and removed a lot of redundant code.

    Using Spring to this level has already helped us somewhat but we’ve barely scratched the surface. The main reason I wanted to port this application across is that in my next post I’m going to look at hooking this all up to a database using JPA. Spring is really going to start to pay off in this environment, and after that, when we add Transactions, Remoting and possibly even a dash of Security, we’ll be really making the most of Spring’s power.

    Continue Reading→