MVC in Pentaho Xul applications can be acheived by architecting your application using the pattern we will detail here. As a refresher, the purpose of the MVC pattern is separation of concerns in UI applications. The idea is to keep a clear separation between the data we would like to display and how that data is being displayed. In Pentaho Xul framework the view layer is represented at least partially represented in a xul dom object (typically coming from a xul file). I say "partially" because you could consider view logic to be part of the view and view logic is not included in the xul dom.
The diagram below shows how Pentaho Xul MVC would operate in an example UI widget project Foo. Starting from the left we see that the xul file foo.xul is represented in your application as a XulDom. The XulDom is what we consider to be the View of our MVC implementation The Xul framework by way of the XulDom is responsible for instantiating and laying out UI components, however, as we mentioned earlier view logic is not handled by the XulDom. The responsiblity for handling view logic rests on the Controller and can be thought of as being component-state events or non-component-state events. These two classes of events are handled differently in the Controller.
Data Binding and Component-state Events
It is the responsibility of your Controller implementation to setup bindings between your XUL components and your data model (a POJO/Java Bean). What do we mean by "binding"? Binding is a way to associate bean properties so that when one changes, the other is kept in sync. Binding can be unidirectional or bidirectional, but we won't get into that here. We will assume that a binding is always bidirectional meaning when either side of the binding changes, the other will reflect the change. This is useful in UI applications because we can tie, say, a text box's value to a model bean String property. Consider the snippet below of a controller's onLoad method. Following the Foo theme, notice how you can create a binding between a model's name property and a XUL component's value property.
Behind the scenes this bind method is retrieving a XulComponent by id "nameTextBox" and linking the name property of the model to the value property of the XulComponent instance. Now let's say in addition to binding the name property to a text box we want to wire the enabled state of an OK button to a boolean bean property on the model. We would just add another bind call that ties the two properties together, notice the "!" expression which does an in-flight negation of boolean value (very helpful with XulComponents which use disabled rather than enabled properties).
In the diagram you will see that the XulDom fires "events" to the FooController. Events in this contex
- represented as a Java Bean (with property change support)
- contains view logic such as enablement and visibility, i.e. the state of UI components
- applies form validation
- represented in the xul dom
- creation of ui components
- layout of ui components
- represented as a Java class that implements XulEventHandler
- binds UI state to the model
- performs UI action handling (not related to component state) such as launching of dialogs