Foxtrot
Version 2.0

foxtrot.utils
Class EventListenerProxy

java.lang.Object
  extended by foxtrot.utils.EventListenerProxy
All Implemented Interfaces:
InvocationHandler

public class EventListenerProxy
extends Object
implements InvocationHandler

This class wraps an EventListener subclass (and thus any AWT/Swing event listener such as ActionListeners, MouseListeners and so on) making sure that if a wrapped listener is executing, another wrapped listener (even of different type) it is not executed.
For example, if a user clicks very quickly on a button, it may trigger the execution of the associated listener more than once. When the listener contains Foxtrot code, the second click event is dequeued by Foxtrot and processed again, invoking the listener again. Using this class to wrap the listener avoids this problem: the second event will be dequeued and processed by Foxtrot as before, but the wrapped listener will not be called.
Example Usage:

 final JButton apply = new JButton("Apply");
 apply.addActionListener((ActionListener)EventListenerProxy
                .create(ActionListener.class, new ActionListener()
 {
    public void actionPerformed(ActionEvent e)
    {
       apply.setEnabled(false);
       Worker.post(new Job()
       {
          public Object run()
          {
             // Lenghty apply code
          }
       });
    }
 }));

 JButton cancel = new JButton("Cancel");
 cancel.addActionListener((ActionListener)EventListenerProxy
                .create(ActionListener.class, new ActionListener()
 {
    public void actionPerformed(ActionEvent e)
    {
       // For example, dispose a dialog
    }
 }));
 

Without using EventListenerProxy, when a user clicks on the apply button and immediately after on the cancel button, it happens that apply's button listener is executed; in there usage of Foxtrot's Worker will dequeue and execute the event associated to the cancel button click, that will - for example - dispose the dialog before the apply operation is finished.
When using EventListenerProxy instead, the second event - the cancel button click - will not be executed: the event will be processed without invoking the wrapped listener.
The overhead in the code is to change plain listeners:
 button.addActionListener(new ActionListener() {...});
 
to this:
 button.addActionListener((ActionListener)EventListenerProxy
                .create(ActionListener.class, new ActionListener() {...}));
 

Version:
$Revision: 1 $
Author:
Simone Bordet

Constructor Summary
protected EventListenerProxy(EventListener listener)
          Creates an instance that wraps the given listener
 
Method Summary
static EventListener create(Class listenerInterface, EventListener listener)
          Creates a proxy for the given listener.
 Object invoke(Object proxy, Method method, Object[] args)
          
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

EventListenerProxy

protected EventListenerProxy(EventListener listener)
Creates an instance that wraps the given listener

Parameters:
listener - the listener to wrap
Method Detail

create

public static EventListener create(Class listenerInterface,
                                   EventListener listener)
Creates a proxy for the given listener.
The listener must implement the given listener interface

Parameters:
listenerInterface - The interface used to create the proxy
listener - The listener to proxy
Returns:
A proxy for the given listener
Throws:
NullPointerException - When the interface or the listener is null
IllegalArgumentException - When the listener does not implement the interface

invoke

public Object invoke(Object proxy,
                     Method method,
                     Object[] args)
              throws Throwable

Specified by:
invoke in interface InvocationHandler
Throws:
Throwable

Foxtrot
Version 2.0