View on GitHub

SuperEventBus

High-octane event bus for GWT

Download this project as a .zip file Download this project as a tar.gz file

What is SuperEventBus?

SuperEventBus is a high-powered event bus for GWT. It is a replacement for the built-in com.google.web.bindery.event.shared.EventBus.

SuperEventBus is currently an experimental API that is subject to change. Please leave feedback and feature requests in the issue tracker!

Why do I need a new event bus?

GWT's event bus is a great way to make your application more maintainable by decoupling components from one another, allowing you to work on one without affecting the others. However, the built-in event bus has several limitations. Specifically,

SuperEventBus addresses all of these problems and more, providing a more powerful event bus that is easier to use.

How do I use SuperEventBus?

SuperEventBus uses a simple annotation-based interface inspired by Guava's event bus. To define a handler method, just annotate a non-private method that takes a single argument with the @Subscribe annotation like this:

@Subscribe
void handleString(String event) {
  Window.alert("The string " + event + " was posted on the event bus.");
}

A class may contain any number of methods annotated with @Subscribe. In order to active them, the class must first declare an event registration interface for the class:

interface MyRegistration extends EventRegistration<MyClass> {}

Then, the class just needs to register itself with an instance of the event bus (this is usually done in the constructor of the class):

eventBus.register(this, (MyRegistration) GWT.create(MyRegistration.class));

Once registered, handleString will be invoked whenever a String is posted on the event bus, which is done like this:

eventBus.post("some string");

Of course, you aren't restricted to posting strings: handler methods can be defined for any type and any type can be passed to post. In practice, most users will define their own event types rather than posting existing types directly.

What else can it do?

SuperEventBus contains several advanced features that have no analogue in GWT's built-in event bus. It's easy to get started with SuperEventBus without these features, and explore them later as needed.

Priorities

In addition to @Subscribe, handler methods can also be annotated with the @WithPriority annotation, which takes a single integer. Handlers with higher priorities are always invoked before handlers with lower priorities. Handlers without the @WithPriority annotation are given priority 0, and negative priorities are allowed. See the javadoc for more details.

Filters

Handler methods can also be annotated with the @When annotation, which takes a filter class and causes that handler to be ignored when the filter returns false. Filter classes extend EventFilter and look like this:

class IsVisible implements EventFilter<HasVisibility, Object> {
  @Override
  public boolean accepts(HasVisibility handler, Object event) {
    return handler.isVisible();
  }
}

A handler annotated with @When(IsVisible.class) would be invoked only if its containing class was visible at the time the event was posted. Note that the filter accepts both the handler class as well as the event, so it is possible to filter based on the properties of either. See the javadoc for more details.

MultiEvents

Since EventBus is polymorphic, it is usually possible to handle many types of events by defining a handler for a common base class of those events. However, sometimes it is necessary to handle multiple events of unrelated types. This can be accomplished by declaring a handler with a paramter of type MultiEvent and annotating it with EventTypes as follows:

@Subscribe
void handleMultipleTypes(@EventTypes({String.class, Double.class}) MultiEvent event) {
  if (event instanceof String) {
    Window.alert("Got a string: " + event.getEvent());
  } else if (event instanceof Double) {
    Window.alert("Got a double: " + event.getEvent());
  }
}

The given handler would be invoked whenever a String or Double was posted on the event bus, and the actual event would be accessible via the getEvent method on MultiEvent. See the javadoc for more details.

Dead events

If an event is fired that has no registered handlers, SuperEventBus will wrap that event in a DeadEvent and re-fire it. This makes it possible to register a handler for DeadEvent that can do something like log a warning when an event without a handler is fired, which can help detect misconfiguration issues. Note that DeadEvent will never be fired if a handler for Object is registered, since that handler will receive every event posted on the event bus. See the javadoc for more details.

How do I install it?

If you're using Maven, you can add the following to your <dependencies> section:

<dependency>
  <groupId>com.ekuefler.supereventbus</groupId>
  <artifactId>supereventbus</artifactId>
  <version>0.1.0</version>
</dependency>

You can also download the jar directly or check out the source using git from https://github.com/ekuefler/gwt-supereventbus.git.