Michael Elhadad

Software Engineering - Fall 1999

Lecture 10: Event Models



Read The Java Event Model from the Sun Java Tutorial.

More on Java events in SWING.

Read Schmidt's columns on Corba's event system (the examples are translated in Java in the previous lecture notes):

  1. Distributed Callbacks and Decoupled Communication in CORBA, SIGS, Vol 8. No 9. October 1996.

    This column examines distributed callbacks in CORBA and illustrates why they are useful for decoupling relationships between consumers and suppliers in object-oriented communication applications. The source code examples are based on the HP ORB Plus CORBA implementation.

  2. OMG Event Object Service, SIGS, Vol. 9, No 2. February, 1997.

    This column outlines the roles of the key components in the OMG Events Service, examines the IDL interfaces of the Events Service components in detail, shows how to use it to build a flexible implementation of the distributed stock quoter system, and evaluates the strengths and weaknesses of the OMG Event Services model and its specification.

  3. Overcoming Drawbacks with the OMG Events Service,, SIGS, Vol. 9, No 6. June, 1997. (updated April 7th, 1997)

    This column describes techniques for overcoming drawbacks with the OMG Events Service. These techniques range from changing the COS Events Service specification, to changing implementations of the COS Events Service specification, as well as changing applications that use a COS Events Service implementation.


Events are objects or messages used when a software components wants to notify a state change to other components.

An Event model is a software architecture (a set of classes and interfaces) that determine how components can:

  1. On the event source side:
    1. create and describe events
    2. trigger (or fire) events
    3. distribute events to interested components
  2. On the event listener side:
    1. subscribe to event sources
    2. react to events when received
    3. remove the subscription to event sources when desired
Terminology often used refers to:
  1. Event Source or Provider: the sender of events
  2. Event: the object sent
  3. Event Listener or Event Sink or Consumer: the receiver of events.

Properties of Event Services

The most important properties:
  1. Synchronous vs. asynchronous events: does the consumer react immediately to the event? does the producer wait for the consumer to finish reacting?
  2. Connection topology: can producers and consumers be connected in complex topologies (fan-in, fan-out)? does the service require a centralized event registration mechanism or can it be distributed?
  3. Push vs. Pull: do producers inform consumers (push) or reversely do consumers ask producers for events (pull)? Can hybrid models be supported?
  4. Distributed vs. single process events
  5. Quality of Service (QoS): does the service insure that the channel between producer and consumer can reserve bandwidth to allow time-critical events to reach consumers whenever needed?
  6. Directed vs. undirected events: it is desirable that the producer can trigger events without knowing the identity of the consumers and vice-versa, that consumers can subscribe to event sources without knowing the identity of the potential producers.
  7. Typed vs. untyped events: with untyped events, consumers can listen to any type of events. This adds to flexibility but costs in security (no compile-time check).
  8. Persistent: what happens if the event channel process exits? It should keep the event queues in a persistent store and restore them upon restart. Also, if an event channel or a source is used, whenever it is shut down, it should keep the list of registered listeners to restore it upon restart.
  9. Security: does anyone check if consumers are authorized to subscribe to an event notification service?
  10. Filtering: who is in charge of filtering events, consumer or producer? How difficult is it to define filtering constraints?
The conclusion is that the definition of an event model can be difficult, and must be adapted by analyzing the trade-offs of each application.

The Java Event Model: Part 1

Java defines the following basis to help define new event types:
  1. class EventObject: is serializable and remembers the Source object.
  2. interface EventListener: is used only to tag interfaces that extend it so that run-time type information can recognize them.
When defining a new event, the following conventions are followed:
  1. A new class extending EventObject is defined. It is named using the pattern xxxEvent.
  2. A new interface extending EventListener is defined. It is named using the pattern xxxListener
  3. The interface xxxListener defines functions to react to the xxxEvent family. They are named using the pattern onxxx(xxxEvent).
  4. The producer of the xxxEvent implements 3 methods:
    1. void addxxxListener(xxxListener l): adds l to the list of interested listeners.
    2. void removexxxListener(xxxListener l): removes l from the list.
    3. void notifyxxx(): creates an xxxEvent and sends it to all interested listeners.
  5. The consumers of the event define an instance of a class that implements the xxxListener interface and register this class with an xxxEvent producer using the addxxxListener() method.
  6. The producer fires events by calling notifyxxx().
This is the simplest application of the model. It is:
  1. synchronous
  2. simple direct topology (direct link producer/consumer)
  3. push
  4. non distributed (except if the onxxx() method is a remote invocation, but this is not desirable because this is a synchronous model and the remote invocation would block the event notification loop).
  5. No handling of quality of service: there is no priority among listeners - they are simply added to the list of listeners, which could grow. The time it takes to notify a listener is therefore unbounded.
  6. Directed (consumers and producers know about each other)
  7. Typed (the xxxEvent type is used)
  8. The addxxxListener is in charge of checking security
  9. Filtering is performed by the producer in the notifyxxx() method or by the consumer in the onxxx() method. There is no "declarative" setting of event filtering.

The Java Event Model: Example 1

The following code illustrates how to implement the simplest application of the Java event model:
// Define a new event
public class StockPriceChangeEvent extends EventObject {
  private long newPrice;
  public StockPriceChangeEvent(Object source, long np) {
    newPrice = np;
  public long getNewPrice() {
    return newPrice;
  // Type-safe access to source
  public Stock getStock() {
    return (Stock)getSource();

// Define new listener interface
public interface StockListener extends EventListener {
  public abstract void onStockPriceChange(StockPriceChangeEvent e);

// Define a source for the event
public class Stock {
  private long currentPrice;
  private Vector stockListeners = new Vector();
  private String name;

  public Stock(String n) {name = n;}

  public setPrice(long np) {
    currentprice = np;

  public synchronized void addStockListener(StockListener l) {

  public synchronized void removeStockListener(StockListener l) {

  protected void notifyStockPriceChange() {
    StockPriceChangeEvent e = new StockPriceChangeEvent(this, currentPrice);
    for (int i = 0; i < stockListeners.size(); i++ ) {
      StockListener l = (StockListener)stockListeners.elementAt(i);

// Define a listener for the event
public class Trader implements StockListener {
  public Trader() {
    ibm = new Stock("ibm");

  public onStockPriceChange(StockPriceChangeEvent e) {
    if (e.getNewPrice() > 103) {

As shown in the code, event sources must deal with the issue of registration of listeners and distribution of events when they work in push mode. Java provides classes to support this aspect of the problem.

Event Adapters

Adapters are intermediary objects -- objects that come between event sources and their targets. Adapters allow the decoupling of sources and targets. This is desirable in several scenarios:
  1. Demultiplexing adapters: the same adapter can receive events from several sources and trigger a single event on the targets.
  2. Generic adapters: are useful to allow wiring of sources and targets that are not type compatible. The adapter maintains a map to make events of different types correspond to each other.
  3. Distributed adapters: take care of the remote interfaces to send events to remote targets. For example, a CORBA event-adapter allows an event source to connect to targets on any machine related through the ORB.
  4. Queuing adapters: When using a synchronous event-model, a queuing adapter is important to decouple the posting of an event with the execution of the callback on the targets. The queuing adapter just records the event and the source can keep working. The targets can handle the event when they have time.
  5. Filtering adapters: apply rules to determine which targets should be informed, and which should not be informed of each type of event.
The following Swing example illustrates a good usage of event adapters and the technique of using inner classes as event adapters.
Last modified June 13th, 1999 Michael Elhadad