Back to top

vogella training Training Books

Eclipse 4 Platform Services - Tutorial

Based on Eclipse 4.2

Lars Vogel

Version 5.8

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

Eclipse e4

This tutorial gives an overview of the available services of Eclipse 4 for developing Eclipse RCP applications and Eclipse plug-ins based on Eclipse 4.


Table of Contents

1. Overview
1.1. What are Eclipse platform services?
1.2. Overview of the available platform services
2. Model Service
2.1. What is the model service?
2.2. Searching model elements
2.3. Example: Search perspective and change attributes
3. Part service and editor like behavior
3.1. Overview
3.2. Overview
4. Selection service
4.1. Usage of the selection service
4.2. Retrieving the selection service
4.3. Changing the current selection
4.4. Getting the selection
5. Command and Handler service
5.1. Overview
5.2. Example
6. Thank you
7. Questions and Discussion
8. Links and Literature
8.1. Source Code

1. Overview

1.1. What are Eclipse platform services?

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.

1.2. Overview of the available platform services

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

2. Model Service

2.1. What is the model service?

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.

2.2. Searching model elements

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.

2.3. Example: Search perspective and change attributes

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++;
  }
} 

3. Part service and editor like behavior

3.1. Overview

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.

3.2. Overview

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.

Adding a PartDescripter to the model

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);
  }
} 

3.2.1. Example: Implement Editor behavior

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);
  }

} 

4. Selection service

4.1. Usage of the selection service

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.

4.2. Retrieving the selection service

A client can get the selection service via: @Inject ESelectionService.

4.3. Changing the current selection

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());
  }
}); 

4.4. Getting the selection

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
  }
} 

5. Command and Handler service

5.1. Overview

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.

5.2. Example

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.

6. Thank you

Please help me to support this article:

Flattr this

7. Questions and Discussion

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.

8. Links and Literature

8.1. Source Code

Source Code of Examples

http://wiki.eclipse.org/E4 Eclipse E4 - Wiki

Eclipse RCP

Eclipse EMF

Dependency Injection

List of the available services and their description

http://wiki.eclipse.org/E4/Contexts#Available_Services_in_Eclipse_e4