Developing Eclipse RCP applications following the MVC pattern
In this blog post I’ll show how Eclipse RCP applications can be developed following the MVC pattern. I’m going to use Spring DM to connect the controllers with their model and view components. Also, Eclipse Riena ridgets are utilized to access the view from the controller. This started as proof of concept, so I’m using a very simple example.
Creating the example application
The example is just a single view part embedded in an Eclipse RCP application containing two text fields for entering numbers and a button to calculate the sum of both numbers:

I assume you know how to create such an example application. The view code looks like this:
public class CalculatorView extends ViewPart {
public static final String VIEW_ID = "com.example.rcpmvc.calculator";
@Override
public void createPartControl(Composite parent) {
Text nr1 = new Text(parent, SWT.BORDER);
Text nr2 = new Text(parent, SWT.BORDER);
Button calculate = new Button(parent, SWT.NONE);
calculate.setText("Calculate");
Text result = new Text(parent, SWT.BORDER);
GridLayoutFactory.fillDefaults().numColumns(4).spacing(5, 3).margins(5, 5).applyTo(parent);
}
}
I’m going to use a variant of the MVC pattern that has been termed “Passive View” because the view is entirely passive and doesn’t know a thing about the application data or logic. You can read more about the general concept in Martin Fowlers wiki: Passive View.
May I introduce: Model, View and Controller
So we have our view. The respective model represents the data and the state of the UI. For this example, it might look like this:
public class CalculatorModel {
private int nr1, nr2, result;
public int getNr1() {
return nr1;
}
public void setNr1(int nr1) {
this.nr1 = nr1;
}
public int getNr2() {
return nr2;
}
public void setNr2(int nr2) {
this.nr2 = nr2;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
}
The idea of MVC/Passive view is that model and view are passive. They are working in their own world, holding data and viewing views. The action happens in the controller. The controller is responsible for connecting the model and the view and for intermediating between those two worlds:

The controller might look like this:
public class CalculatorController {
public CalculatorController(CalculatorView view, CalculatorModel model) {
// connect view and model here
}
}
We will have a look at the details of the actual implementation later on.
Connecting the MVC components
So we have these three objects. Who is responsible for creating and connecting them? In an Eclipse RCP application the workbench is responsible for creating the views. Everything else has to be done after the view has been created. Also, the components should not know about their partners directly.
This can be achieved using the Dependency Injection (DI) / Inversion of Control (IoC) paradigm. A component should not look up their companion objects itself. Instead, they get their dependencies injected from the outside. The developer describes how these components are to be wired separate from the actual components. In general, this helps with keeping all the components very loosely coupled.
I always liked the Spring implementation of that general concept, because it has been proven reliable on the server-side and can also be used in an OSGi environment via Spring Dynamic Modules. Have a look at Tutorial: Spring OSGi + Eclipse RCP to learn about how to use Spring in Eclipse RCP applications. Have a look at the Spring documentation to learn about Spring IoC container in general: Spring Framework - Reference Documentation
I’m borrowing the idea of connecting the MVC components in such a way from the Agile RCP framework. Unfortunately it has been a bit quiet around that project in the last year, so I’m only using the general idea: Let’s wire the controller with the view and the model using Spring, like this:
<bean id="com.example.rcpmvc.demo.calculator"
class="com.example.rcpmvc.demo.CalculatorController" scope="prototype">
<property name="view">
<bean class="com.example.rcpmvc.demo.CalculatorView"/>
</property>
<property name="model">
<bean class="com.example.rcpmvc.demo.CalculatorModel"/>
</property>
</bean>
The controller bean gets the view and the model injected. As this bean lives in the prototype scope, a fresh object is created every time the controller bean is requested. But who requests the controller bean?
We have to cheat a little bit here. The right moment to create such a controller bean is when the Eclipse RCP framework creates the view. To solve this, I created a SpringViewFactory based on Martin Lipperts SpringExtensionFactory. This factory creates the controller and hands out the respective view. I’m providing this class together with some more utility classes and an example project here: mvc_rcp.
This can be used to refer views by their controller bean, for example in view extensions:
<extension point="org.eclipse.ui.views">
<view
class="de.ralfebert.rcpmvc.spring.SpringViewFactory"
id="com.example.rcpmvc.demo.calculator"
name="Calculator"
restorable="true"/>
</view>
</extension>
Accessing the view components
Another question is how the controller accesses the view. It is worth pursuing to not use the SWT widgets directly. Instead one might want to use some kind of wrapper which could work even without the actual widgets. This is done mostly for testability, as writing tests using actual widgets is a cumbersome and non-trivial undertaking.
Also, the widget API is very low-level. Wouldn’t it be nice if the controller could use a bit more functionality out of the box in terms of working with the widget? (things like data binding, validation, etc.)
Of course we could write our own wrapper classes. But for some reason, I have stopped reinventing wheels and started to reuse whatever I can, even if I end up having a somewhat general purpose wheel that needs some improvements. As it turns out, the Eclipse Riena framework has exactly such wrapper classes called Ridgets. They encapsulate widgets, offer a lot of helpful API intented to be used by controller classes and will do the job for our task at hand. Also, ridgets can be used for RCP applications without buying all the other framework features. To learn more about Riena and it’s other capabilities, have a look at Eclipse Riena Tutorial.
Using the ridget classes solely without the Riena framework requires some setup work. I’m going to skip these details, as I provided some simple base classes in the mvc_rcp project for using Ridgets in Eclipse RCP applications: have a look at the code to learn what’s necessary to do this. Riena also comes with an example project called org.eclipse.riena.sample.app.client.rcpmail which shows how ridgets can be used for the RCP mail example application.
Using the provided utility classes, you can implement the calculator example easily. At first, subclass the view from PassiveViewPart. Use addUIControl or UIControlsFactory to assign IDs to the SWT widgets:
public class CalculatorView extends PassiveViewPart {
public static final String VIEW_ID = "com.example.rcpmvc.demo.calculator";
@Override
public void basicCreatePartControl(Composite parent) {
UIControlsFactory.createText(parent, SWT.BORDER, "nr1");
UIControlsFactory.createText(parent, SWT.BORDER, "nr2");
UIControlsFactory.createButton(parent, "Calculate", "calculate");
UIControlsFactory.createText(parent, SWT.BORDER, "result");
GridLayoutFactory.fillDefaults().numColumns(4).spacing(5, 3).margins(5, 5).applyTo(parent);
}
}
In this example, the text controls are named nr1, nr2 and result, the button is named calculate.
The controller class can be subclassed from ViewController (which is also provided in mvc_rcp). Implement the configureRidget method to wire the view with the model. You can access ridgets using getRidget and use all the API from the ridget classes to setup the view:
public class CalculatorController extends ViewController<CalculatorView, CalculatorModel> {
@Override
public void configureRidgets() {
ITextRidget nr1 = (ITextRidget) getRidget("nr1");
ITextRidget nr2 = (ITextRidget) getRidget("nr2");
final ITextRidget result = (ITextRidget) getRidget("result");
IActionRidget calculate = (IActionRidget) getRidget("calculate");
nr1.bindToModel(getModel(), "nr1");
nr2.bindToModel(getModel(), "nr2");
result.bindToModel(getModel(), "result");
calculate.addListener(new IActionListener() {
@Override
public void callback() {
getModel().setResult(getModel().getNr1() + getModel().getNr2());
result.updateFromModel();
}
});
updateAllRidgetsFromModel();
}
}
And here is the fully featured calculator:

That’s it for this time. Of course there are more things necessary to use this in real world applications. I basically did this as proof of concept and to see if anybody is interested in this. I’m looking forward to your comments!


This is great information. Thanks! I'd appreciate hearing more about your use of Passive Views, especially if you have any tips for writing controller unit tests.
By the way, you should really add your blog to Planet Eclipse. If you are already, just ignore this, but I don't think I've seen your posts there in the past.
Anyway, keep up the great work! This is really useful.
--- Patrick