Version 5.8
Copyright © 2009, 2010 , 2011, 2012 Lars Vogel
02.02.2012
| Revision History | |||
|---|---|---|---|
| Revision 0.1 | 14.02.2009 | Lars Vogel |
created |
| Revision 0.2 - 58 | 16.02.2009 - 02.02.2012 | Lars Vogel |
bug fixes and enhancements |
Table of Contents
Services are software components (based on an interface or class) which provide functionality. The Eclipse platform defines several services. The classes in the application model can access them via dependency injection.
To use an Eclipse service you
specify
the service dependency via an
@Inject
annotation and the Eclipse framework will inject this component into
your class.
The typical naming convention for Eclipse services is that they start with an E " and end with service e.g. E*Service.
The following table gives an overview of the most important available platform services.
Table 1. Platform Services
| Service | Description |
|---|---|
| EModelService | Find elements in the model, create or clone snippets and insert new elements into the model structures |
| ESelectionService | Retrieve and set the current workbench selection. |
| ECommandService | Access, create, change and trigger commands. |
| EHandlerService | Access, change and trigger handlers. |
| EPartService | Provides API to access parts, e.g. find parts by their ID. It allows you to switch Perspectives and to hide and show Parts. |
| IEventBroker | Provides functionality to send event data and to register for certain events. |
| StatusReporter | Allows you to report Status objects, concise interface compared to standard IStatus reporting. |
| EContextService |
Activate and deactivate keybindings defined as
BindingContext
in the application model.
|
| IThemeEngine | Define themes and switch the styling at runtime. |
Other available services are:
org.eclipse.e4.core.services.Adapter - An adapter can adapt
an
object to the specified type, allowing clients to request
domain-specific
behavior for an object. It integrates
IAdaptable
and
IAdapterManager.
org.eclipse.e4.core.services.Logger - Provides logging functionality
There are additional services available which depend on SWT.
EMenuService - Registers a popup menu (MPopupMenu) for an SWT control.
org.eclipse.jface.window.IShellProvider - allows access to a
Shell
The
EModelService
service gives access to the model and allows you to modify it, e.g.
add and
remove model elements. It also contains functionality to clone
application model snippets,
which
can be added to the application.
It can get injected via
@Inject EModelService.
The
findElements()
method allows you to search for specific model elements. The
following
code
shows an example for using the
findElements()
method.
package com.example.e4.rcp.todo.handlers; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.basic.MWindow; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.swt.widgets.Display; public class ModelServiceExampleHandler { @Execute public void execute(MApplication application, EModelService service, Display display) { System.out.println("Got Model Service: " + (service != null)); // Alternatively to get the model service // via the application EModelService modelService = (EModelService) application.getContext() .get(EModelService.class.getName()); // both services are identical System.out.println("Got Model Service: " + (service != modelService)); // Find objects by ID findObjectsById(application, service); // Find objects by type findObjectsByType(application, service); // Find objects by tags findObjectsByTag(application, service); // Get the MWindow and change its size getWindowAndChangeSize(application, service, display); } // Example for search by ID private void findObjectsById(MApplication application, EModelService service) { List<MPart> findElements = service.findElements(application, "mypart",MPart.class, null); System.out.println("Found part(s) : " + findElements.size()); } // Example for search by Type private void findObjectsByType(MApplication application, EModelService service) { List<MPart> parts = service.findElements(application, null, MPart.class, null); System.out.println("Found parts(s) : " + parts.size()); } // Example for search by Tag private void findObjectsByTag(MApplication application, EModelService service) { List<String> tags = new ArrayList<String>(); tags.add("justatag"); List<MUIElement> elementsWithTags = service.findElements(application, null, null, tags); System.out.println("Found parts(s) : " + elementsWithTags.size()); } // Example: Get the MWindow and change its size private void getWindowAndChangeSize(MApplication application, EModelService service, Display display) { List<MWindow> windows = service.findElements(application, null, MWindow.class, null); if (windows.size() >= 1) { MWindow mWindow = windows.get(0); System.out.println("Got the window"); int endSize = mWindow.getWidth() - 100; for (int i = mWindow.getWidth(); i >= endSize; i--) { while (!display.readAndDispatch()) { mWindow.setWidth(i); wait10(); } } } } private void wait10() { try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }
Here is an example of how to find the Perspective for a part.
package com.example.e4.rcp.todo.handlers; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; import org.eclipse.e4.ui.workbench.modeling.EModelService; public class FindPerspectiveHandler{ @Execute public void execute(MApplication application, EModelService service) { System.out.println("Called save"); MUIElement element = service. find("com.example.e4.rcp.parts.tododetail", application); MPerspective perspective = service.getPerspectiveFor(element); System.out.println(perspective); } }
In Eclipse 4.2 the model service does not find menu and toolbar model entries as well as handlers. It is expected that this will be changed in a release after Eclipse 4.2.
The following example shows how to access a
PartSashContainer
with the
mypartsashcontainer
ID and how to set the
container data
parameter for its children. This will
re-arrange (layout) the
parts
in the container.
@Execute public void execute(EModelService service, MWindow window) { MPartSashContainer find = (MPartSashContainer) service. find("mypartsashcontainer", window); List<MPartSashContainerElement> list = find.getChildren(); int i = 0; // Make the first part in the container larger for (MPartSashContainerElement element : list) { element.setContainerData("80"); if (i > 0) { element.setContainerData("20"); } i++; } }
EPartService
allows you to find and perform actions on
parts
in the application model. It also allows you to
switch
Perspectives
and to create new
parts
based on
PartDescriptors.
The following example shows how you can find
parts, hide them or show them.
If the
Visible
attribute of the
part
was initially set
to
false
(not visible), you need to call the
setVisible(true)
method of the model element
to ensure that the
part
gets displayed.
@Inject private EPartService partService; // Get the part detailsTodoPart = partService.findPart("de.vogella.e4.tododetails"); // Hide the part partService.hidePart(detailsTodoPart); // Required if initial not visible detailsTodoPart.setVisible(true); //Show the part partService.showPart(detailsTodoPart, PartState.VISIBLE);
The following example shows, how to save all parts in the application model which are marked as dirty.
package com.example.e4.rcp.todo.handlers; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.workbench.modeling.EPartService; public class SaveHandler { @Execute void execute(EPartService partService) { partService.saveAll(false); } }
The following example shows how you can switch to another Perspective.
package com.example.e4.rcp.todo.handlers; import java.util.List; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; public class SwitchPerspectiveHandler { @Execute public void execute(MApplication app, EPartService partService, EModelService modelService) { MPerspective element = (MPerspective) modelService.find("secondperspective", app); // Now switch perspective partService.switchPerspective(element); } }
If you defined a
PartDescriptor
in your application model you can use the
EPartService
to create a
part
from this template.

package com.example.e4.rcp.todo.handlers; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; public class OpenPartHandler { @Execute public void execute(EPartService partService) { // Create a new Part based on a PartDescriptor // in the Application model MPart part = partService .createPart("com.example.e4.rcp.todo.partdescriptor.fileeditor"); part.setLabel("New Dynamic Part"); // If multiple parts of this type is allowed // in the application model, // then the provided part will be shown // and returned partService.showPart(part, PartState.ACTIVATE); } }
Each
part
has the attribute
MDirtyable
available. This attribute can get injected in the Part. If you
call the
setDirty(true)
method the
part
informs the Eclipse platform that is has data to save.
You can use the
PartService
to call a method in the
part
which is annotated with
@Persist
to save the data in the
PartService.
The following snippet demonstrates how to use the
MDirtyable
model property in a part to flag it as a Part which should be saved
by
the corresponding workbench action.
import javax.annotation.PostConstruct; import javax.inject.Inject; import org.eclipse.e4.ui.di.Persist; import org.eclipse.e4.ui.model.application.ui.MDirtyable; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; public class MySavePart { @Inject MDirtyable dirty; @PostConstruct public void createControls(Composite parent) { Button button = new Button(parent, SWT.PUSH); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { dirty.setDirty(true); } }); } @Persist public void save() { System.out.println("Saving data"); // Save the data // ... // Now set the dirty flag to false dirty.setDirty(false); } }
The
ESelectionService
service allows you to retrieve and set the current global
selection in
your application. Other classes in the application model can define
annotated methods for certain type and are called
by the
Eclipse
framework if the selection changes for these types.
A
client
can get
the selection service via:
@Inject ESelectionService.
You can change the current selection with the
setSelection()
method.
@Inject ESelectionService selectionService; // viewer is a JFace Viewer viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); selectionService.setSelection(selection.getFirstElement()); } });
A client can retrieve the last global selection directly from the
ESelectionService
via the
getSelection()
method. The
getSelection(partId)
method allows you to retrieve the selection of a specific
part.
It is preferred that a class which is part of the application model
uses dependency inject to retrieve
the current selection. This class
defines a method with a named (@Named) parameter (IServiceConstants.ACTIVE_SELECTION) and a type. The Eclipse framework makes sure that
selections are
only injected if they have the fitting type.
@Inject public void setTodo(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) Todo todo) { if (todo != null) { // Do something with the value } }
The
ECommandService
and
EHandlerService
provide the functionality to work with commands and handlers, e.g.
create and change them.
A client can get these services injected via dependency injection.
For example via the handler service you could add a handler to the
IEclipseContext
of a perspective, even though the application model does not foresee
this.
The following example shows how to add a new handler to an existing
command. It assumes that the
AboutHandler
handler class already exists.
Command command = commandService.getCommand("com.example.mycommand"); // Check if the command is defined System.out.println(command.isDefined()); // Activate Handler, assume AboutHandler() class exists already handlerService.activateHandler("com.example.mycommand", new AboutHandler()); ParameterizedCommand cmd = commandService.createCommand("com.example.mycommand", null); // Check if the command can get executed System.out.println(handlerService.canExecute(cmd)); // Execute the command handlerService.executeHandler(cmd);
Currently some methods are only used in the compatibility layer.
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.