Presently all of the state in an AWT component that can be written can
also be read, e.g. there are no write-only properties in the component
API. There's one notable exception to this convention: event
listeners. AWT event listeners are managed according to the JavaBeans
conventions with a pair of methods: addFooListener() and
removeFooListener() for a listener that implements the Foo
EventListener interface. No access is provided to the listener lists
themselves. The fields that contain the listener lists are package
private (although the cunning AWTEventMulticaster class used to
implement them isn't) and no method is provided that returns the
contents of a listener list. This has caused some problems for Swing
and other AWT clients:
- The Swing UI classes have to keep references to every listener they
add, just to enable removing them if the UI is changed. Swing
applications contain 1000's of references like this. A simpler
version of this problem is that you can't clear a listener list unless
you've kept a private copy.
- Archiving systems, e.g. IBMs BML package, have to resort to
implementation dependent snooping to discover the contents of the
- Externalization isn't an option for classes derived from Component,
like the Swing components, because the listeners are inaccessible.
To remedy the problem we propose to add a single method to Component,
getEventListeners() that uses a Class object to specify a particular
listener list. For example to get all of the listeners added with
addFocusListener(), one would write: getListeners(FocusListener.class).
This proposal conciously ignores the problem created by
addListenerMethods that take extra arguments, e.g. the overloading of
addPropertyChangeListener that allows one to specify a single property
name. Although one could accomodate listener lists like this by
having getEventListeners() return an object that contained both the
listener and the add listener arguments, we were uncomfortable with
supporting this (rare) special case now. Support could easily be
added in a future release.
Proposed API change:
The following method will be added to java.awt.Component:
* Return an array of all the listeners that were added to the Component
* with addXXXListener(), where XXX is the name of the <code>cls</code>
* argument. For example, to get all of the MouseListeners for the
* given Component <code>c</code>, one would write:
* MouseListener mls = (MouseListener)(c.getListeners(MouseListener.class))
* If no such listener list exists, then null is returned.
* @returns all of the listeners for the specified Component.
* @since 1.3
public EventListener getEventListeners(Class cls)
Name of engineer who will make the changes: Phil Milne
Name of person who will review the changes: Hans Muller, AWT team
Date at which they will be completed: ASAP
# lines of new or modified code:
Code reviewed (or will be reviewed) by:
Phil Milne, Brent Christian, Robi Khan, Fred Ecks, Dave Mendenhall, others.
Risk assessment (required):
SQE (product testing) impact:
Automatic tests should be straightfoward to write. One can easily
compute the list of listeners for a class with the beans
Introspector. Verifying that the lists are returned by
getListeners() correctly would be trivial.
JCK (compatibility testing) impact:
SQE and JCK tests don't need to be different.
Doc impact (contact Alan Sommerer if you don't know your contact):
Javadoc will be provided as part of the implementation.
Localization impact: No
Internationalization impact: No
Security impact: No
Legal impact: No