Using Events to Communicate with Other Components

   

Using Events to Communicate with Other Components

The whole idea behind the JavaBeans component model is to provide a way to create reusable components. To do this, Beans must be able to communicate with the other Beans in their environment and with their container. This is accomplished by means of Listener interfaces. You've already seen some of this with the PropertyChangeEvent from the last section. This section goes into more detail about how Listener s work.

Beans use the same event-handling scheme as AWT and Swing. This means that if your Bean needs to hear about events coming from another Bean, it must register itself with that Bean. To do this, it must implement the Listener interface for the event of interest. At the same time, if your Bean is no longer interested in hearing about some other Bean's event, it must unregister itself with that Bean. Any event that a Bean wants to fire must inherit from the java.util.EventObject class. For simple events, the java.util.EventObject class itself could be used; however, as with java.lang.Exception, using child classes provides clarity and is preferred. All Listener interfaces must inherit from the java.util.EventListener interface, and the same subclassing convention applies. The event handling method of a Listener interface should follow the design pattern for introspection as shown here:

 void <EventOccuranceName>( <EventObjectType evt ); 

Note that <EventObjectType> must inherit from java.util.EventObject. Here is an example of an event handler for a DinnerServedListener interface:

 // DinnerServedEvent inherits from // java.util.EventObject. void dinnerServed( DinnerServedEvent evt ); 

There is no restriction preventing an event-handler method from throwing an exception. In addition, any one Listener interface can have any number of related event handlers.

There are two types of events that components can listen for: multicast events and unicast events.

Multicast Events

Multicast events are the most common types of events. The PropertyChangeEvent, which you have already been exposed to, is a multicast event because there can be any number of listeners. In that example, you had addPropertyChangeListener() and removePropertyChangeListener() methods, which allowed other components to register with the Bean as being interested in hearing when a bound property changed. The process is the same for any other type of multicast event, and the registration methods should follow the design pattern for introspection as shown here:

 public synchronized void add<ListenerType>( <ListenerType> listener ); public synchronized void remove<ListenerType>( <ListenerType> listener ); 

The keyword synchronized is not actually part of the design pattern. It is included as a reminder that race conditions can occur, especially with the event model, and precautions must be taken.

Unicast Events

Unicast events don't occur nearly as often as their counterpart , but they're just as useful. Unicast events can have only one listener. If additional components attempt to listen to the unicast event, a java.util.TooManyListenersException will be thrown. The following design pattern should be used when declaring unicast events:

 public synchronized void add<ListenerType>( <ListenerType> listener ) throws    java.util.TooManyListenersException; public synchronized void remove<ListenerType>( <ListenerType> listener ); 

Event Adapters

In some cases, it might be necessary to build an event adapter class that can transfer an event to a component. This comes into play especially for an application builder because the application doesn't know until runtime how the components will be linked together or how they will interact with each other's events.

An event adapter intervenes in the normal event-handling scheme by intercepting the events normally meant for another component. For example, assume that a user places a button and a text box in an application builder. If the user wants the text box to fill with the word "Pressed" when the button is pressed, the application builder can use an event adapter to call a method containing the user -generated code needed to do it. Here's how it will eventually work:

  1. The event adapter registers with the event source. In other words, it calls an addSomeEventListener() method on the event source component.

  2. The event source component fires an event by calling the event adapter's event-handler method, someEvent(). Keep in mind that the event source component doesn't care whether it's calling an event adapter or a true event listener. At this point, with the event fired , it can continue with its business.

  3. The event adapter calls the specific user-designed method on the final target component.

  4. The code in the user-designed method fills in the text box component with the "Pressed" text.

Sometimes it helps to see some code. Listing 29.6 contains some pseudocode you can examine to see how an event adapter is written. The code in the example builds off the procedure listed previously. You won't be able to compile this code (notice the class keywords have been changed to pseudoclass), but it serves as an example you can build off of in your own Beans.

Listing 29.6 AdaptorExample.java ” Pseudocode Showing How to Implement an Adapter Class; This Code Might Be Generated by an Application Builder
 // this pseudoclass example uses a unicast mechanism to keep things simple. public interface SomeEventListener extends java.util.EventListener {    public someEvent( java.util.EventObject e ); } public pseudoclass button extends java.awt.Button {    public void synchronized addSomeEventListener( SomeEventListener l )                                 throws java.util.TooManyListenersException {       if ( listener != null ) {          listener = l;       }  else throw new java.util.TooManyListenersException;    }    private void fireSomeEvent() {       listener.someEvent( new java.util.EventObject( this ) );    }    private SomeEventListener listener = null; } public pseudoclass eventAdaptor implements SomeEventListener {    public eventAdaptor( TargetObject target ) {       this.target = target;    }    someEvent( java.util.EventObject e ) {       // transfer the event to the user generated method.       target.userDefinedMethod();    }    private TargetObject target; } public pseudoclass TargetObject {    public TargetObject() {       adaptor = new eventAdaptor( this );    }    public userDefinedMethod() {      // user generated code goes here.    }    private eventAdaptor adaptor; } 
   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net