Event Bus

Overview
A simple Event Bus implementation.

Any complex Java standalone application requires communication between its modules. The trivial approach is using direct calls. Each module calls other modules with updates. The result is a spaghetti code. This type of design and implementation is error-prone and non-managable.

The solution is using Event Bus. Some module could fire event and other modules interested in this event should register to receive it. Event Bus delivers fired event from the originator module to one or many registered destination modules.

Direct Calls Event Bus

Similar products
You may find many articles on the web about Event Bus implementations. There are also many tutorials available. Many of Event Bus implementations are complex mature products published on GitHub like Google Guava and Green Robot. Another Event Bus is part of Google GWT.

Using any of this heavyweight products requires learning curve, Java code and associated debugging.

Our simple Event Bus implementation has less than 200 lines of code in 5 classes.

Quick start
Follow below steps to start using EventBus. These steps are by example used in a demo Swing application.

Step 1. Create BlueEvent class which implements interface Event. This event class might have constructor with arguments, member variables, and any methods. None of them are required for the simple notification.

  import com.jdotsoft.eventbus.Event;

  public class BlueEvent implements Event {
  }

Step 2. Create BlueEventListener interface which extends base interface EventListener with method onBlue(BlueEvent e). This interface might have any other method declarations, however only methods which returns void with single argument BlueEvent will be invoked on fired event. Generally speaking only this single method makes sense. The name of this method could be any, it is found by reflection based on its signature.
  import com.jdotsoft.eventbus.EventListener;

  public interface BlueEventListener extends EventListener {
     void onBlue(BlueEvent event);
  }

Step 3. Implement BlueEventListener in some class BluePanel to receive BlueEvent event and register all listeners in this class:
  public class BluePanel extends JPanel implements BlueEventListener {
    public BluePanel() {
      EventBus.getInstance().registerListeners(this);
    }
    @Override
    public void onBlue(BlueEvent event) {
      . . .
    }
  }

Step 4. Fire event
  eventBus.fire(new BlueEvent());
  - or -
  EventBus.getInstance().fire(new BlueEvent());
Object BluePanel will receive event in listener BlueEventListener implementation onBlue(BlueEvent e).

Note. The object EventBus could be instantiated as EventBus eventBus = new EventBus() somewhere in a main class and passed to all listeners. Use static EventBus.getInstance() as an alternative.

Demo
The Swing demo application EventBusDemo is included as com.jdotsoft.eventbus.demo.EventBusDemo in test of the GitHub Maven project, see Download section.

Initally all panels in the demo application are grey. Panels which implements RedEventListener update the background to red after the Red button click and the event RedEvent is fired in the ActionListener for this button.

Panels which implements BlueEventListener update the background to blue after the Blue button click and the event BlueEvent is fired in the ActionListener for this button.

All panels implements ResetEventListener in the base class for all panels. All panels reset the background to default color after the Reset button click and the event ResetEvent is fired in the ActionListener for this button.

Download
The project EventBus is available to download from GitHub. It contains also the demo Swing application.

Maven
Add the following dependency to your pom.xml:

  <dependency>
    <groupId>com.jdotsoft</groupId>
    <artifactId>jdotsoft-eventbus</artifactId>
    <version>2.1</version>
  </dependency>

Other features

Enumerate all event listeners
This feature could be useful for debugging purpose to log all registered listeners. This functionality is implemented in EventBus.toString() method. Note, this method should be called after all listeners are registered. Example below is for the demo application.

EventBus: com.jdotsoft.eventbus.EventBus@205797316
  EVENT: com.jdotsoft.eventbus.demo.events.BlueEvent
    LISTENER: com.jdotsoft.eventbus.demo.panels.BluePanel@1296064247
    LISTENER: com.jdotsoft.eventbus.demo.panels.BlueRedPanel@780237624
  EVENT: com.jdotsoft.eventbus.demo.events.RedEvent
    LISTENER: com.jdotsoft.eventbus.demo.panels.RedPanel@2128227771
    LISTENER: com.jdotsoft.eventbus.demo.panels.BlueRedPanel@780237624
  EVENT: com.jdotsoft.eventbus.demo.events.ResetEvent
    LISTENER: com.jdotsoft.eventbus.demo.panels.RedPanel@2128227771
    LISTENER: com.jdotsoft.eventbus.demo.panels.BluePanel@1296064247
    LISTENER: com.jdotsoft.eventbus.demo.panels.BlueRedPanel@780237624

Events logging
This is an optional feature. By default it is turned off. Use default EventLogListener implementation to log to System.out or override this class with application specific logging system.
  EventBus.getInstance().setEventLogListener(new EventLogListener());

Log example:
EventBus: fired 'BlueEvent'
EventBus: dispatched 'BlueEvent' to BluePanel@1296064247->onBlue()
EventBus: dispatched 'BlueEvent' to BlueRedPanel@780237624->onBlue()

License
Java classes in this project are licensed under Apache license.

Leave a comment


  CAPTCHA Image
  Allowed tags: <b> <i> <code>
We record your IP address 18.226.17.210 (located here) and will report abuse of this form to authorities.

Submit Comment