Back to top

vogella training Training Books

Eclipse 4 Event System (EventAdmin) - Tutorial

Building Eclipse RCP applications based on Eclipse 4

Lars Vogel

Version 6.1

08.10.2012

Revision History
Revision 0.1 14.02.2009 Lars
Vogel
created
Revision 0.2 - 6.1 16.02.2009 - 08.10.2012 Lars
Vogel
bug fixes and enhancements

Using the Eclipse 4 event system within your application

This tutorial gives an overview about the event system of the Eclipse 4 application platform.


Table of Contents

1. Prerequisites
2. Communication within your Eclipse application
2.1. Event based communication
2.2. IEventBroker Service
2.3. Subscribing to event topics
3. Usage
3.1. Sending
3.2. Receiving
3.3. Eclipse Framework Events
4. Evaluation
4.1. Context Variables
4.2. Conclusion
5. Thank you
6. Questions and Discussion
7. Links and Literature
7.1. Source Code

1. Prerequisites

The following description is based on Eclipse 4 RCP tutorial .

2. Communication within your Eclipse application

2.1. Event based communication

In your application you frequently have the need to communicate between application components.

For example the user selects an object in a Tree widget and a part is updated with this information.

This example can be handled by the selection service. But frequently you want to propagate more than just a selection between the different components of your application. For example a non-visual component wants to send a data update to all relevant visual components.

For this purpose the Eclipse platform provides a global event based communication system, called the event bus. Software components can register for certain events and other components can send new events to the event bus.

The Eclipse platform will make sure that registered components will receive the messages. Eclipse 4 uses this event system for the complete internal communication.

2.2. IEventBroker Service

The Eclipse framework uses the event notification system for its internal communication based on the IEventBroker service. This communication service can also be used to communicate between your own application components.

IEventBroker is based on the OSGi EventAdmin service but has been wrapped with a simpler API. It also automatically removes any event subscriptions when the defining IEclipseContext is disposed.

The following plug-ins contain the IEventBroker functionality:

  • org.eclipse.e4.core.services
  • org.eclipse.osgi.services

Via the IEventBroker service you can send or post events. The classes in your application can register as event listeners for specific events. Other classes in your application use the service to send events.

2.3. Subscribing to event topics

You can subscribe to specific topics but also use wildcards to subscribe to all subevents. Subevents are separated by /.

package com.example.e4.rcp.todo.events;

public interface MyEventConstants {
  
  public static final String TOPIC_TODO_DATA_UPDATE = 
      "TOPIC_TODO_DATA_UPDATE/*";
  
  public static final String TOPIC_TODO_DATA_UPDATE_NEW = 
      "TOPIC_TODO_DATA_UPDATE/NEW";
  
  public static final String TOPIC_TODO_DATA_UPDATE_DELETE = 
      "TOPIC_TODO_DATA_UPDATE/DELETED";
  
  public static final String TOPIC_TODO_DATA_UPDATE_UPDATED = 
      "TOPIC_TODO_DATA_UPDATE/UPDATED";
} 

@Inject
@Optional
private void getNotified(@UIEventTopic(MyEventConstants.TOPIC_TODO_DATA_UPDATE) 
    String s) {
  if (viewer!=null) {
    viewer.setInput(model.getTodos());
  }
} 

3. Usage

3.1. Sending

The IEventBroker service can be injected via dependency injection.

@Inject
private IEventBroker eventBroker; 

The following code examples assumes that you have a class named MyEventConstants defined which contains a static final field (constant)) for the TOPIC_NEWDATA string.

The IEventBroker service collects all events and sends them to the registered classes. This can be done asynchronously or synchronously.

@Inject IEventBroker broker;

...
// asynchronously
broker.post(MyEventConstants.TOPIC_NEWDATA, "New data"); 

@Inject IEventBroker broker;
...
// synchronously sending a todo
// Caller will block until delivery
broker.send(TOPIC_NEWDATA, todo); 

You can now send arbitrary Java objects or primitives through the event bus.

3.2. Receiving

You can use dependency injection to register and respond to events.

The @EventTopic and @UIEventTopic annotations tag methods and fields that should be notified on event changes. The @UIEventTopic ensures the event notification is performed in the user interface thread.

// Constant for event registration
public static final String TOPIC_NEWDATA = "TOPIC_NEWDATA";

// Register to the topic TOPIC_NEWDATA for 
// objects of type Todo
@Inject @Optional
void closeHandler(@UIEventTopic(TOPIC_NEWDATA) Todo todo) {
    // Do something
}

//Register to the topic TOPIC_NEWDATA for 
//objects of type String
@Inject @Optional
void closeHandler(@UIEventTopic(TOPIC_NEWDATA) String s) {
 // Do something
} 

Alternatively an object can also register an instance of the EventHandler directly with the IEventBroker via the subscribe() method. Using dependency injection for subscribing should be preferred compared to the direct subscription.

3.3. Eclipse Framework Events

It is also possible to register for Eclipse framework events. The UIEvents class from the org.eclipse.e4.ui.workbench contains all framework events. This class also contains in its Javadoc information about the purpose of events.

For example the UIEvents.UILifeCycle.APP_STARTUP_COMPLETE event is triggered once the application has started. This event was introduced with Eclipse 4.3, see https://bugs.eclipse.org/376821.

Or the UIEvents.UILifeCycle.ACTIVATE event is triggered if a part is activated.

@Inject
@Optional
public void partActivation(@UIEventTopic(UIEvents.UILifeCycle.ACTIVATE) 
  Event event) {
  // Do something
  System.out.println("Got Part");
} 

This allows you for example to put a Context variable called myactivePartId on every part change into the application context.

// Set a context variable
@Inject
@Optional
public void partActivation(@UIEventTopic(UIEvents.UILifeCycle.ACTIVATE) 
  Event event,
  MApplication application) {
    
  // Don't inject MPart and IEclipseContext! Need from root context here
  MPart activePart = (MPart) event.
      getProperty(UIEvents.EventTags.ELEMENT);
  IEclipseContext context = application.getContext();
  if (activePart != null) {
    context.set("myactivePartId", activePart.getElementId());
  }
} 

This context variable can be used to define a visible-when clause which can be used to restrict the visibility of menus and toolbars.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

   <extension
         id="product"
         point="org.eclipse.core.runtime.products">
      <product
        application="org.eclipse.e4.ui.workbench.swt.E4Application"
        name="to-do">
         <property
          name="applicationXMI"
          value="com.example.e4.rcp.todo/Application.e4xmi">
         </property>
         <property
               name="appName"
               value="to-do">
         </property>
      </product>
   </extension>
   
   <extension
         point="org.eclipse.core.expressions.definitions">
      <definition
            id="com.example.e4.rcp.todo.todooverviewselected">
         <with
               variable="myactivePartId">
            <equals
                  value="com.example.e4.rcp.ui.parts.todooverview">
            </equals>
         </with>
      </definition>
   </extension>

</plugin> 

Restrict the visibility of a command

The Eclipse platform places several ContextVariables into the context. Several keys are defined in the IServiceConstants interface.

4. Evaluation

4.1. Context Variables

Context variables can be used to share your application state, instead of the IEventBroker service.

If you put Context variables into a context which is available to other objects, for example the application context, these other objects can use @Inject to get these Context variables injected.

The IEventBroker is a global event bus and is unaware of the IEclipseContext hierarchy. Context variables provide an improved way to manage scoped shared application state.

4.2. Conclusion

The advantage of the IEventBroker Service is that it supports sending event information without knowing who is receiving it. Interested classes can register for events without knowing who is going to provide them. This is known as the whiteboard pattern and this pattern supports the creation of very loosely coupled application components.

The disadvantage is that it is a global bus, i.e. there is no scoping of the events. Publishers have to ensure they provide enough information in the event for subscribers to discriminate and decide that the particular event is applicable to them.

5. Thank you

Please help me to support this article:

Flattr this

6. 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.

7. Links and Literature

7.1. Source Code

Source Code of Examples

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

Wiki for the Event Model of Eclipse 4

Eclipse RCP

Eclipse EMF

Dependency Injection