Package org.bushe.swing.event

The main package, provides publish/subscribe services for Swing and non-Swing applications.

See:
          Description

Interface Summary
ContainerEventServiceSupplier A interface implemented by a Swing Container to supply an EventService local to it's child components.
EventService The core interface.
EventServiceEvent Convenience interface for events that get processed by the EventService, its usage is not required in any way.
EventSubscriber<T> Callback interface for class-based subscribers of an EventService.
EventTopicSubscriber<T> Callback interface for topic-based subscribers of an EventService.
Prioritized Subscribers can implement this interface in order to affect the order in which they are called.
PrioritizedEventSubscriber This is a convenience interface, particularly for inner classes, that implements EventSubscriber and Prioritized.
PrioritizedEventTopicSubscriber This is a convenience interface, particularly for inner classes, that implements EventTopicSubscriber and Prioritized.
ProxySubscriber An interface that can be implemented when proxies are used for subscription, not needed in normal usage.
PublicationStatusTracker An optional interface that can be implemented by Events objects or topic Payloads to enable the events' status to be stamped on the event by an event service.
VetoEventListener<T> Interface for classes that can veto class-based event publication from the EventService.
VetoTopicEventListener<T> Interface for classes that can veto publication on topic names from the EventService.
 

Class Summary
AbstractEventServiceEvent Convenience base class for EventServiceEvents in the application.
CleanupEvent Published when the ThreadSafeEventService cleans up stale subscribers.
ContainerEventServiceAction When fired, this action publishes an ActionEvent on a Container EventService.
ContainerEventServiceFinder This class finds a component's container event service, and creates one if necessary and possible.
ContainerEventServiceRegistrar Registers a component with it's Container's EventService while keeping track of the component's container.
EventBus The EventBus provides event publication and subscription services.
EventBusAction When fired, this action publishes events on the EventBus.
EventServiceAction Abstract class that publishes a Swing ActionEvent (or another object) to an EventService.
EventServiceLocator A central registry of EventServices.
Logger Central Logging class.
ObjectEvent A simple event that delivers an untyped object with a source object.
SubscriberTimingEvent This event is published internally to report timing for subscribers on an EventService.
SwingEventService An EventService implementation for Swing.
ThreadSafeEventService A thread-safe EventService implementation.
 

Enum Summary
CleanupEvent.Status The status of the cleanup.
Logger.Level Standardized logging levels.
Logger.LoggerType Allows switching between Java and Commons logging.
PublicationStatus The status of an event as it makes its way from publication through processing by subscribers.
 

Exception Summary
EventServiceExistsException Exception thrown by the EventServiceLocator when an EventService already is registered for a name.
 

Package org.bushe.swing.event Description

The main package, provides publish/subscribe services for Swing and non-Swing applications.

See the overview for an introduction to the EventBus' pub/sub services.

This simple example prints "Hello World" using class-based publication.


class HelloEvent {
   public String getWorld() {
      return "World";
   }
}


class MySubscriber implements EventSubscriber {
   //EventSubscriber implementation
   public void onEvent(Object event) {
      HelloEvent helloEvent = (HelloEvent)event;
      System.out.println("Hello"+helloEvent.getWorld());
   }
}


class HelloEventBus {
   public static void main(String args[]) {
      MySubscriber subscriber = new MySubscriber();
      EventBus.subscribe(HelloEvent.class, subscriber);
      EventBus.publish(new HelloEvent());
   }
}

Though the term "Event Bus" refers to the entire library, the EventBus class used above is a static wrapper around a global instance of an EventService, specifically the SwingEventService implementation by default.  MySubscriber subscribes itself to the HelloEvent.class. When main() publishes an instance of HelloEvent the Event Bus calls MySubscriber's onEvent method, passing the HelloEvent as a parameter, and "Hello World" is printed.

The above subscriber can be simplified by using a generic type.


class MySubscriber implements EventSubscriber {
   //EventSubscriber implementation
   public void onEvent(HelloEvent helloEvent) {
      System.out.println("Hello"+helloEvent.getWorld());
   }
}

Alternatively, this example can be coded using EventBus annotations and the AnnotationProcessor, removing some boilerplate code:


class MySubscriber {
   @EventSubscriber(eventClass=HelloEvent.class)
   public void printOutHelloWorld(HelloEvent event) {
        System.out.println("Hello"+helloEvent.getWorld());
   }
}
class HelloEventBus {
   public static void main(String args[]) {
      MySubscriber subscriber = new MySubscriber();
      AnnotationProcessor.process(subscriber);//makes a proxy subscriber to call subscriber.printOutHelloWorld
      EventBus.publish(new HelloEvent());
   }
}

This second example prints "Hello World" using topic-based publication.


class MyTopicSubscriber implements EventTopicSubscriber {
   //EventTopicSubscriber implementation
   public void onEvent(String topic, Object event) {
        System.out.println(topic+" "+event);
   }
}

class HelloEventBus {
   public static void main(String args[]) {
      MyTopicSubscriber subscriber = new MyTopicSubscriber();
      EventBus.subscribe("Hello", subscriber);
      EventBus.publish("Hello", "World");
   }
}

MyTopicSubscriber subscribes itself to the topic named "Hello".  When main() publishes the String "World" (the "payload") on the event topic "Hello", the EventBus calls MyTopicSubscriber on the Swing EDT and "Hello World" is printed.

Alternatively, this example can also be coded using EventBus annotations and the AnnotationProcessor:


class MyTopicSubscriber {
   @EventTopicSubscriber(topic="Hello");
   public void printOutHelloWorld(String topic, Object event) {
        System.out.println(topic+" "+event);
   }
}

class HelloEventBus {
   public static void main(String args[]) {
      MySubscriber subscriber = new MySubscriber();
      AnnotationProcessor.process(subscriber);//makes a subscriber to call subscriber.printOutHelloWorld
      EventBus.publish("Hello", "World");
   }
}

Important: The EventBus uses WeakReferences by default, so this WILL NOT WORK since it uses an anonymous inner class:


   public static void main(String args[]) {
      EventBus.subscribe("Hello", new MySubscriber());
      //subscriber will likely get garbage collected - no Hello World!!!
      EventBus.publish("Hello", "World");
   }

In the above example, the subscriber will likely be garbage collected before the publication occurs. However you can subscribe strongly instead:

     
     public static void main(String args[]) {
         EventBus.subscribeStrongly("Hello", new MySubscriber());
         //subscriber will not get garbage collected
         EventBus.publish(new HelloEvent());
         //In real apps use unsubscribe to make sure you don't leave a subscriber hanging
         //around in the EventBus forever (a memory leak), unless you really want to
         EventBus.unsubscribe(subscriber);
     }
     
   

This last example shows support for generic types. In the application for this example, there are many List's that are published. This subscriber only want to be notified of List's of Trades, or List<Trade>. Due to type erasure, this feature requires an addition step - the use of a TypeReference object:

     
     public class TradeSubscriber implements EventSubscriber {
        public TradeSubscriber() {
           TypeReference<List<Trade>> subscribingTypeReference = new TypeReference<List<Trade>>(){};
           EventBus.subscribe(subscribingTypeReference.getType(), this);
        }
        public void onEvent(Object object) {
        }
     }

     //Publisher
     List<Trade> trades = new ArrayList<Trade>();
     trades.add(trade);
     TypeReference<List<Trade>> publishingTypeReference = new TypeReference<List<Trade>>(){};
     EventBus.publish(publishingTypeReference.getType(), trades);
     
   

There are two EventService implementations provided by the EventBus library. One is the ThreadSafeEventService. As the name implies the ThreadSafeEventService can be used in multithreaded environments. There are no extra threads created by the EventBus, as notification generally happens on the publishing thread. The exception to this rule is the SwingEventService, which extends the ThreadSafeEventService and ensures that notifications of subscribers are later posted on the Swing/AWT EventDispatchThread if the publishing thread is not already the EventDispatchThread.

The key class in the EventBus library is the EventBus. The EventBus is a wrapper around an EventService, by default a SwingEventService. Non-Swing applications can change the default implementation, by using the EventServiceLocator.

An application may use multiple event services. The EventServiceLocator is a central registry of EventServices where any number of EventServices can be registered by name, but there is only one EventService instance created by the EventBus library and it registered by default under both the names EventServiceLocator.SERVICE_NAME_EVENT_BUS ("EventBus") and EventServiceLocator.SERVICE_NAME_SWING_EVENT_SERVICE ("SwingEventService"). The EventBus class wraps the EventService registered under the name "EventBus". By default, the EventServiceLocator's "EventBus" defaults to the EventService registered under the name "SwingEventService", which is an instance of a SwingEventService. So out-of-the-box there is one global event service that should only be used for Swing apps, but this can either be changed programmatically or via Java properties before the first time the EventServices are requested from the EventServiceLocator or the first time the EventBus us used, whichever comes first.



Copyright © 2011 Bushe Enterprises, Inc.. All Rights Reserved.