Eclipse Riena Tutorial(转)
Eclipse Riena aims at providing a foundation for building enterprise client/server applications. It also delivers a very interesting simplification of the Eclipse RCP workbench concept and comes with an elaborated UI and navigation concept. In this tutorial I will focus on the client-side aspects of Riena and show you:
- How to setup Eclipse for Riena development
- How to run the Riena examples
- How to create a Riena application from scratch
- How to use Riena’s navigation tree
- How to implement views and controllers and use Ridgets to connect both
I assume you know how to work with OSGi bundles and Eclipse extension points and have some knowledge about Eclipse RCP development.
Setting up the target platform
Use Eclipse for RCP/Plug-in Developers
and start with a blank workspace. At first, create a new target definition “Riena” using Preferences > Plug-in Development > Target Platform
. Initialize the target definition without a template and add Equinox Core SDK
, Eclipse RCP SDK
, Riena Core SDK
and Riena SDK Samples
from the Galileo
software site (RCP will be only visible if you uncheck Group by category
in the dialog). Your target definition should look like this:
Running the examples
Import org.eclipse.riena.example.client
using File > Import > Plug-ins and Fragments
into your local workspace.
All example plug-in projects contain shared run configurations. Run SWT ExampleApplication
from the list of run configurations (you need to “add required bundles” in the run configuration). This example contains the Riena playground
with examples for all UI features of Riena:
There are more example projects, have a look at Riena Getting started for information about all the example projects.
Creating a new application
Let’s create a new Riena application from scratch (without fancy wizards and templates). Create a new plug-in with the following settings:
- Targeted to run with Eclipse 3.5
- Generate an activator
- Plug-in will make contributions to the UI
- Don’t create a rich client application
- Don’t use a template
Add org.eclipse.riena.client
as required bundle. This exports all other dependencies which are required for building Riena applications.
A Riena application is a regular RCP application with lots of additions and customizations. So we have to register a new application using the org.eclipse.core.runtime.applications
extension point:
Create the application class and let it extend org.eclipse.riena.navigation.ui.swt.application.SwtApplication
. Implement the getBundle
method using the bundle activator and overwrite the createModel
method to assign a label to the application (we will learn more about these node
objects in a second):
public class SampleApp extends SwtApplication {
@Override
protected Bundle getBundle() {
return Activator.getDefault().getBundle();
}
@Override
protected IApplicationNode createModel() {
IApplicationNode applicationNode = super.createModel();
applicationNode.setLabel("Sample application");
return applicationNode;
}
}
Launch the Eclipse application - you should see a completely empty Riena application:
Navigation
Riena applications are based on a tree navigation model. The root node is the application node which is created in the application class.
Under the root node there are subapplication
nodes which are represented as tabs. Below them you see the modules
of the subapplication. Modules are the only nodes that can be closed by the user. Modules are grouped together in modulegroups
. Below the modules you have a tree of submodules
. Submodules are the actual “views” of the application.
Unlike Eclipse RCP, which has a very flexible and customizable user interface, Riena restricts the workbench to show only the navigation tree and the currently selected node of the navigation tree to simplify the application usage for end-users:
The navigation tree of a groupware application might contain elements like these:
The navigation view for such a calendar subapplication would be shown like this:
Navigation nodes are contributed using the extension point org.eclipse.riena.navigation.assemblies
. A very simple assembly might look like this:
assembly
An assembly is a container for navigation elements which are “mounted” in the navigation tree. The full navigation structure is assembled from the contents of assemblies at runtime. Every node in the tree has a unique id which is called typeId
. The parentTypeId
attribute specifies to which node the elements in the assembly are to be added. The root application node has the special type id application
. Independent from this, the assembly itself has its own id
(remember, the assembly is only a container for nodes and has no representation in the tree itself). The name
attribute for the assembly
is just a label for the Eclipse extension editor. Assemblies that specify an autostartsequence
are mounted automatically in the tree when the application starts (in the order specified by the sequence). Elements without an autostartsequence
can be added programmatically using the navigation API.
subapplication
A subapplication represents a separate and independent part of a Riena application. You have to specify a label
(displayed on the tab) and a name
(only for the extension point editor). The typeId
is the id of the node by which the subapplication node can be referred.
A Riena subapplication maps to an Eclipse RCP perspective using the view
attribute. For every subapplication you have to define a perspective using org.eclipse.ui.perspectives
. Specify org.eclipse.riena.navigation.ui.swt.views.SubApplicationView
as class / perspective factory for the perspective.
modulegroup
A modulegroup simply groups modules visually.
module
A module groups the submodules (views / forms) of your application. Typically modules describe a use case or a document that has a distinct meaning to the user. Module nodes are the only nodes that can be closed by the user (except if they are unclosable
). If a module has only one submodule, the submodule is not shown separately and the submodule is activated automatically when the module is activated.
submodule
A submodule is a view of your application. Submodules can form a hierarchy, so you can add submodules into submodules. Additionally to the already known attributes you have to map the submodule to an Eclipse RCP view
and a controller
class.
For information about navigation have a look at Riena Navigation
Model-View-Controller
Riena components are structured according to the Model-View-Controller (MVC) pattern. A view is built using SWT widgets, but it does not expose these widgets. The view is only responsible for the UI, it doesn’t know a thing about the data model and the application flow. The model represents the data behind the UI. The controller is responsible for all the logic and for connecting the view with the model:
View
Submodule views are regular Eclipse RCP views that are registered using org.eclipse.ui.views
and extend org.eclipse.riena.navigation.ui.swt.views.SubModuleView
. You create your widgets here as usual. All controls that are relevant for the controller are registered with an id using addUiControl
:
public class AddressView extends SubModuleView<SubModuleController> {
@Override
protected void basicCreatePartControl(Composite parent) {
parent.setLayout(new RowLayout());
Label lblName = new Label(parent, SWT.NONE);
lblName.setText("Name:");
Text textName = new Text(parent, SWT.NONE);
addUIControl(textName, "name");
Label lblStreet = new Label(parent, SWT.NONE);
lblStreet.setText("Street:");
Text textStreet = new Text(parent, SWT.NONE);
addUIControl(textStreet, "street");
Button btnSave = new Button(parent, SWT.NONE);
btnSave.setText("Save");
addUIControl(btnSave, "btnSave");
}
}
You can also use UIControlsFactory
which creates and registers a control in one step:
UIControlsFactory.createLabel(parent, "Name:");
UIControlsFactory.createText(parent, SWT.NONE, "name");
UIControlsFactory.createLabel(parent, "Street:");
UIControlsFactory.createText(parent, SWT.NONE, "street");
UIControlsFactory.createButton(parent, "Save", "btnSave");
Model
The model represents the data behind the UI. It is built using regular Java objects (Pojo). In this example, this might be a very simple address object:
public class Address {
private String name, street;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
Controller
The controller is responsible for obtaining the model, for connecting model and view and for implementing all logic that model or view cannot implement by themselves. Submodule controllers extend org.eclipse.riena.navigation.ui.controllers.SubModuleController
.
All widgets which are registered in the view are provided to the controller as a Ridget
. A Ridget
encapsulates a view widget and provides operations to work with the widget without accessing the widget directly (this abstraction is aimed at testability - you can test your controllers without the SWT views).
To bind the address object and handle the button click you can use TextRidget
and ActionRidget
like this:
public class AddressController extends SubModuleController {
@Override
public void configureRidgets() {
final Address address = new Address();
ITextRidget name = (ITextRidget) getRidget("name");
ITextRidget street = (ITextRidget) getRidget("street");
IActionRidget btnSave = (IActionRidget) getRidget("btnSave");
name.bindToModel(address, "name");
street.bindToModel(address, "street");
updateAllRidgetsFromModel();
btnSave.addListener(new IActionListener() {
@Override
public void callback() {
System.out.println("Save: " + address);
}
});
}
}
For more information about all the available Ridgets have a look at Riena Snippets.
What else?
Riena has a lot more to offer than the few aspects I showed in this tutorial, for example:
- UI Filters - How to filter navigation and UI elements by id
- Look and Feel - How to customize the UI look and feel of your application
- Injecting services and extensions - How to inject OSGi services and Eclipse extension information in your objects
- Remote services - How to build remote services on the client/server-side using OSGi
- Riena concepts and features - And more!
P.S.
I hope this tutorial helps you to get started with Eclipse Riena.
If you want to learn more, I’m offering a training course about Eclipse Riena: Eclipse Riena training (in German).