Version 5.8
Copyright © 2009, 2010, 2011 , 2012 Lars Vogel
20.05.2012
| Revision History | |||
|---|---|---|---|
| Revision 0.1 | 14.02.2009 | Lars Vogel |
created |
| Revision 0.2 - 5.8 | 16.02.2009 - 20.05.2012 | Lars Vogel |
bug fixes and enhancements |
Table of Contents
The following assumes that you have already basic Eclipse RCP development experience. See the Eclipse RCP Tutorial for details. .
Eclipse 4 is based on OSGi and therefore supports its modularity. Plug-ins define their external API, and consume API from other plug-ins.
The modularity provided by OSGi is completely available in Eclipse 4. Consuming OSGi services is very well supported in Eclipse 4, as OSGi services can get injected into other components via dependency injection.
In Eclipse 4 the application is described via an application
model
with the
Application.e4xmi
default filename.
Other plug-ins can extend this base application model with contributions.
These model contributions are registered in Eclipse 4 via the
org.eclipse.e4.workbench.model
extension point. This extension point is defined in the
org.eclipse.e4.ui.workbench
plug-in.
The
org.eclipse.e4.workbench.model
extension point allows you to define contributions to the application
model.
Model contributions can be done via files (fragments) or via code (processors).
The model contributions are read during startup and the contained information is used to build the runtime application model.
A model
fragment
is a file which typically ends with the
.e4xmi
extension. It specifies additional model elements.
It defines which model element it extends and the new model elements which should be added to this model element. For example a fragment can define that it extends a certain menu with additional menu entries.
A processor allows you to contribute to the model via program code. A processor allows the dynamic creation of model elements, therefore this approach has the highest flexibility.
Fragments contribute new model elements to existing containers, e.g. new menu entries to existing menus.
Fragments
allow to define the position of these new model
elements via the
Position in List
attribute. The following values are allowed:
Table 1. Position in List attribute
| Value | Description |
|---|---|
| first | Positions the element on the beginning of the list. |
|
index:
Example index:0 |
Places the new model elements at position
theindex.
|
before:
theotherelementsid
|
Places the new model elements before the model element with the
ID
theotherelementsid.
|
after:
theotherelementsid
|
Places the new model elements after the model element with the
ID
theotherelementsid.
|
Fragments
of independent plug-ins
are processed in arbitrary order by the
Eclipse runtime,
therefore
first
or
index
might not always result in the desired outcome.
If you want to contribute to an element of the application model you must specify the ID of the element to which you are contributing.
In general it is good practice to always define IDs in your application model.
The programming model of Eclipse 3.x primarily uses extension points to define contributions to the application. These extensions define new parts, new menus, etc.
This approach is no longer used in Eclipse 4 applications. All contributions are made via fragments or processors.
The application model of a running application consists of different components: the base application model and model contributions via other plug-ins. In addition to that user changes are also recorded and applied to the runtime model.
Changes during runtime, e.g. the user moves a part, are written back to the model. While the application is running, the model objects can be changed. For example, parts are closed or opened.
Theses changes are
recorded and
saved
independently in a
workbench.xmi
file in the
.metadata/.plugins/org.eclipse.e4.workbench
folder.
If user changes should be deleted, you can specify the
clearPersistedState
parameter as a launch parameter.
The different components of the runtime application model need to be combined.
Eclipse 4 creates the application model at first based on the base application model and applies the model contributions to it. User deltas are applied afterwards. If these deltas do not apply anymore, e.g. because the base model has changed, they will be skipped.
The deltas are applied to the model based on the IDs of the user interface component.
In fragments you contribute to an existing model element which is defined via its ID. You also have to specify the Featurename to which you want to contribute. A Featurename is a direct link to the structure of the application model.
The following table lists some Featurename values and their purposes.
Table 2. Contribution, Featurename and Element id
| You want to contribute to | Featurename | Element id |
|---|---|---|
| Command to the application | commands | ID of your application |
| Handler to the application | handlers | ID of your application |
| New MenuItem / HandledMenuItem to existing menu | children | ID of the menu |
| New menu to the main menu of the window | children | ID of your main menu |
| New Part to existing PartStack | children | ID of your PartStack |
In this section you will add a menu entry, a command and a handler to your main application model via fragments.
Create a plug-in project called
com.example.e4.rcp.todo.contribute
without a
template and without an
Activator. The following description abbreviate the plug-in name to
*.contribute.
Add a dependency in your
MANIFEST.MF
file
to the following plug-ins:
org.eclipse.swt
org.eclipse.jface
org.eclipse.e4.core.di
org.eclipse.e4.ui.workbench
org.eclipse.e4.ui.di
Imported packages has to list
javax.inject
with
1.0.0
as a minimum version.
Create the
com.example.e4.todo.contribute.handler
package and
the following class.
package com.example.e4.rcp.contribute.handler; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; public class OpenMapHandler { @Execute public void execute(Shell shell) { MessageDialog.openInformation(shell, "Test", "Just testing"); } }
Use the Eclipse 4 wizard to create a new fragment via the following
menu:
→ → → → → . Select the
com.example.e4.rcp.todo.contribute
plug-in as the container and use
fragment.e4xmi
as the name for the file.
Select the Model Fragment node and press the button.
Use
com.example.e4.rcp.todo.application
as the
Element id. This is the ID of the
Application
model element in
your
Application.e4xmi
file.
You also need to define to which feature you will be adding to. Use commands as Featurename. Make sure you still have the Model Fragment selected and use the button to add a Command to your model fragment.

Use com.example.e4.rcp.todo.contribute.command.openmap as ID and Open Map as name for the corresponding attributes of the command.

Create a new model fragment for the handler. The Element id is again the ID of your application ID, the Featurename is handlers. Add a Handler to this model fragment.

Use
com.example.e4.rcp.todo.contribute.handler.openmap
as ID for the handler.
Point to the
OpenMapHandler
class and your
Open Map
command.

Add another
Model Fragment
to contribute a new menu to your application model. You will
contribute
to the main menu with the
org.eclipse.ui.main.menu
ID. The
Featurename
is
children.

Add a
Menu
with the
Map
label and the
com.example.e4.rcp.todo.contribute.menu.map
ID.

Add a
HandledMenuItem
which
points to
your command. The process
of
defining these entries is
the same as
defining menus
in the
Application.e4xmi
and is therefore not described here in
detail.

In your
*.contribute
plug-in
add the
org.eclipse.e4.workbench.model
extension.

Right-click on the extension and select → .
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension id="modelContribution" point="org.eclipse.e4.workbench.model"> <fragment uri="fragment.e4xmi"> </fragment> </extension> </plugin>
Add the
*.contribute
plug-in to your
com.example.e4.rcp.todo.feature
feature.
Run the Todo product. You should see the new Map entry in the application menu. If you select this entry a message dialog opens.
If the menu entry is not displayed, ensure that your IDs are
correctly
entered and that you either use the
clearPersistedState
flag or clear the workspace data in your
Launch configuration.
Please note that your model entries should all have IDs.
In the following example you will replace an existing menu entry in the Eclipse 4 application.
Continue to use com.example.e4.rcp.todo.contribute plug-in for this tutorial.
Add the
following additional plug-ins to your dependencies to
your
MANIFEST.MF
file.
org.eclipse.e4.ui.services
org.eclipse.e4.core.contexts
Create the following dialog and handler classes. The handler will be used later on in the new menu entry.
package com.example.e4.rcp.todo.contribute.dialogs; import javax.inject.Inject; import javax.inject.Named; import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; public class ExitDialog extends Dialog { @Inject public ExitDialog(@Named(IServiceConstants. ACTIVE_SHELL) Shell shell) { super(shell); } @Override protected Control createDialogArea(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText("Closing this application may result in data loss. " + "Are you sure you want that"); return parent; } }
package com.example.e4.rcp.todo.contribute.handler; import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.workbench.IWorkbench; import org.eclipse.jface.window.Window; import de.vogella.e4.todo.contribute.dialogs.ExitDialog; public class ExitHandlerWithCheck { @Execute public void execute(IEclipseContext context, IWorkbench workbench) { ExitDialog dialog = ContextInjectionFactory. make(ExitDialog.class, context); dialog.create(); if (dialog.open() == Window.OK) { workbench.close(); } } }
Create now the model processor class.
package com.example.e4.rcp.todo.contribute.processors; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem; import org.eclipse.e4.ui.model.application.ui.menu.MMenu; import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement; import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory; public class MenuProcessor { // I get this via the parameter // of the process definition @Inject @Named("org.eclipse.ui.file.menu") private MMenu menu; @Execute public void execute() { // System.out.println("Starting processor"); // Remove the old exit menu entry if (menu != null && menu.getChildren() != null) { List<MMenuElement> list = new ArrayList<MMenuElement>(); for (MMenuElement element : menu.getChildren()) { System.out.println(element); // Separaters have no label hence we // need to check for null if (element.getLabel() != null) { if (element.getLabel().contains("Exit")) { list.add(element); } } } menu.getChildren().removeAll(list); } // Now add a new menu entry MDirectMenuItem menuItem = MMenuFactory.INSTANCE. createDirectMenuItem(); menuItem.setLabel("Another Exit"); menuItem.setContributionURI("bundleclass://" + "com.example.e4.rcp.todo.contribute/" + "com.example.e4.rcp.todo.contribute" + ".handler.ExitHandlerWithCheck"); menu.getChildren().add(menuItem); } }
In your
*.contribute
plug-in add a
processor
via an
org.eclipse.e4.workbench.model
extension.

The following assumes that you used org.eclipse.ui.file.menu as ID for your File menu in the main application model
Right-click on the processor and select
→ . The parameter with the ID is the model element which is later on
injected
into your Java class for the processor. Use
org.eclipse.ui.file.menu
as
id*
parameter.

Add this plug-in to your product and run your product. The old exit menu entry should be removed and you should see the new menu entry.
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.
http://wiki.eclipse.org/E4 Eclipse E4 - Wiki