In this post I'll explain the components of the view layer (View and Mediator), how they should interact and some best practices on how to use them.

The View

This class is where you'll use the JavaFx components to build your UI. It's also responsible for displaying notifications, opening new windows or just about anything that it related to the UI (and which should happen on the UI thread).
I prefer to create my UI with pure Java code instead of using FXML. It's fast, easier to use with Guice and it's giving me more control over my code. Therefore my structure is based on this.
To keep the Views focused on their tasks, you should follow these rules.

Rule 1: Don't let your View extend JavaFx components

The View should never extend a JavaFx component, it should only use JavaFx components. This rule is also known as "composition over inheritance".
Our View classes will have a getView() method which will create and return the top-level component/container of that view. That way the actual view is only instantiated when the getView() method is called. This has several benefits:

Remember from the previous post, the View classes are mapped in Guice and injected in the View classes where they will be used. By not extending a JavaFx component, the cost of creation will be lower when Guice creates and injects these Views.

You can extend any other class you want because the design doesn't force you to extend JavaFx components.

The API of your view will not be cluttered with all the methods of the JavaFx component

Rule 2: The View should never contain application logic

The view can contain view logic (like when to play an animation), but should never contain application logic.
Application logic can sometimes take up several 100ms. If you do this on the UI thread, then during this time the UI will not be able to update anything, so it will feel unresponsive. Therefore it's very important to run your application logic on a separate thread (which in this structure will be in a Command).
If some application logic should be executed in response to a button click, it should call the mediator to delegate this to the application logic layer.

Rule 3: Put your view behind an interface

You should create an interface for your View class. This interface should contain the methods that can be called by the Mediator.
Creating such an interface has several advantages:

You create an API for your View which clearly indicates what it can do.

The mediator can work against this API, so it isn't tied to a certain View implementation. This is especially handy when writing unit tests for your mediator because you can create a mock for the view and inject that into the mediator.

How it looks like in code

Now how does this look like in code when you apply the rules above? I'll show you some code of a view which shows a list of events. The user can select one of the events by clicking on them.

First we have the View interface:

public interface IEventListView {
/**
* Asks the view to update the list of events with this new list.
*/
void updateEventList(List<EventVO> events);
}

The Mediator

The Mediator is the postman between the view and the application logic. It is receiving messages (calls) from the View and it passes them on to Commands. It also passes on messages that are coming from the application logic to the view. Again, some rules apply here.

Rule 1: The mediator should not contain any application logic

The mediator runs on the UI thread, so it should not contain any application logic as this can make your application unresponsive. It should instead create a command (by using the CommandProvider class) and start the command which will then execute the application logic.
By following this rule we avoid duplicate code and make sure that application logic can always be found in one layer instead of being scattered in multiple layers, which in the end makes your application more maintainable.

Rule 2: The mediator should have an interface

The Mediator should have an interface which defines which actions it can perform. These methods can then be called in the view.

In some cases it can be handy to inject a Model into the mediator to directly access the application state without having to write a command for it. But to avoid excessive use of this, you should only listen to changes on the model, get simple data from it or set simple things on it. If the data needs to be manipulated in any way, don't access the model directly but create a command instead which will contain this logic. So be very careful when accessing the Model from your Mediator.

Conclusion

In this post we've covered the View layer and the rules that should be followed. It also showed how the View and the Mediator communicate with each other. In the next post I'll cover the application logic layer were we'll see how heavy application logic will be offloaded to a separate thread in a consistent way.

Robotlegs was one of my inspirations for this structure, but I removed the event "magic". So instead of dispatching an event to trigger a command you have to construct it with the commandProvider.

Also, in this structure I just let Guice do its work to wire everything up. For example in Robotlegs the view does not have a reference to the mediator, in my structure it does. It let's Guice create the mediator when the view is initialized and it allows for direct communication (which makes it easier to follow the flow of your application when compared to events).

So I haven't ported any Robotlegs logic (ie. I didn't create any classes which mimic to Robotlegs logic). I just used Guice and created a CommandProvider class which uses the Guice injector class to create and return a command.

I'll put the full sample application on github so you can have a look.

For simple cases I would just inject my model into the mediator and add a changelistener to the bindable property on the model.

For more advanced cases I would go for the AS3Signals/C# event way. A signal/C# event isn't something which exists in standard Java, but someone made a java library for this: http://www.redirecttonull.com/?p=13I would then create a signal class for each event type and map it in Guice. Then I would inject the signal in the model which can then dispatch the signal when required.Then you can inject the signal into any part of your application that needs to listen to these kind of events.

mmm, good question. It could indeed lead to some nasty threading issues. Like in this case:1. A model is being updated in a background thread2. The model then dispatches the signal 3. A mediator has attached a listener to this signal and the listener will be triggered4. The mediator asks the view to update some of its components with the new state --> threading issue because the view is being updated in the background thread, while it can only be manipulated in the UI thread.

Or that's as far as I understand it. Certainly something I will explore a bit more to find a good solution for this.