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 which provide functionality. The Eclipse platform defines several services, which can be used in an Eclipse plug-in. To access them you can use dependency injection.
Services are technically defined as OSGi services.
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 most important servcies are:
Table 1. Workbench Services
| Service | Description |
|---|---|
| EModelService | Gives access to the model and allow to modify the model, e.g. add and remove elements. |
| ESelectionService | Allows to retrieve the current workbench selection. |
| ECommandService | Allows to access, change and trigger commands. |
| EHandlerService | Allows to access, change and trigger handlers. |
| EPartService | Provides API to access parts, e.g. find parts by their ID. |
| IEventBroker | Provides functionality to send event data and to register for certain events. |
| StatusReporter | Allows to report Status objects, nice interface compared to standard IStatus reporting. |
| EMenuService | Registers a popup menu (MPopupMenu) for an SWT control |
| org.eclipse.e4.core.services.Logger | Provides logging functionality |
| IThemeEngine | Allows to switch the CSS 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.
EBindingService
EContextService
org.eclipse.jface.window.IShellProvider - allows access to a
Shell
EPartService allows to find and perform actions on
Parts
(Views or Editors) in the application model. For example you can find
Parts, hide them or show them.
Unfortunately if the Part "Visible" attribute was initially set
to
false
(not visible), you also need to interacted with the model element
directly
to ensure that the part gets displayed, via calling its model
property directly.
@Inject private EPartService partService; // Get the part detailsTodoPart = partService.findPart("de.vogella.e4.tododetails"); // Hide the part partService.hidePart(detailsTodoPart); // Show the part // The next line detailsTodoPart.setVisible(true); 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
EModelService
service gives access to the model and allows to modify it, e.g.
add and
remove model elements.
It can get injected via
@Inject EModelService.
The
findElements()
method allows to search for specific model elements. The following
shows an example for using the
findElements()
method:
package de.vogella.e4.modelservice.handlers; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; 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 get the model service from 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 List<MPart> findElements = service.findElements(application, "mypart", MPart.class, null); System.out.println("Found part(s) : " + findElements.size()); // Find objects by type List<MPart> parts = service.findElements(application, null, MPart.class, null); System.out.println("Found parts(s) : " + parts.size()); // Find objects by tags List<String> tags = new ArrayList<String>(); tags.add("justatag"); List<MUIElement> elementsWithTags = modelService.findElements(application, null, null, tags); System.out.println("Found parts(s) : " + elementsWithTags.size()); // Get the MWindow and change its size List<MWindow> windows = modelService.findElements(application, null, MWindow.class, null); if (windows.size()>=1){ MWindow mWindow = windows.get(0); System.out.println("Got the window"); for (int i = mWindow.getWidth(); i >= mWindow.getWidth() - 100; i--) { while (!display.readAndDispatch()){ mWindow.setWidth(i); wait10(); } } } } private void wait10(){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }
Here is an example how to find the perspective for a
View.
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); } }
The following example shows how to access a MPartSashContainer with
the
mypartsashcontainer
ID and how to set the container data 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++; } }
The
ESelectionService
service allows to retrieve the current workbench selection.
A
client
can get
the selection service via:
@Inject ESelectionService.
If you want to change the current selection with a
setSelection()
method call.
The consumer 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 ESelectionService selectionService; viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); Object firstElement = selection.getFirstElement(); selectionService.setSelection(selection.getFirstElement()); } });
@Inject public void setTodo(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) Todo todo) { if (todo != null) { // Do something with the value } }
The
ECommandService
and
EHandlerService
allows to work with commands and handlers.
A client can get the selection service via dependency injection. These services allow to create and change commands and handlers.
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. We assume that the used
AboutHandler
handler class already exists.
Command command = commandService.getCommand("com.example.mycommand"); // Returns true System.out.println(command.isDefined()); // Activate Handler, assume AboutHandler() class exists already handerService.activateHandler("com.example.mycommand", new AboutHandler()); ParameterizedCommand cmd = commandService.createCommand("com.example.mycommand", null); //Some methods on command are only there for legacy reasons //and return nonsense //Return null and false System.out.println(command.getHandler()); System.out.println(command.isEnabled()); // Test if execution works fine System.out.println(handerService.canExecute(cmd)); handerService.executeHandler(cmd);
Currently some methods are only used in the compatibility layer. See also Bug report for command API
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.