In a Swing application, I have a number of sub-panels, each listening to a single JSlider
. The surrounding parent panel also listens to all the sub-panels. To get consistent results in the example below, I had to add the parent first and then the local listener. This makes sense, given the order prescribed in EventListenerList
and explained in this article. Can I rely on that order or should I arrange to send a different event?
class SubPanel extends JPanel implements ChangeListener {
private final JSlider slider = new JSlider();
private final JLabel label = new JLabel();
private final String name;
private float value;
public SubPanel(String name, float value, ChangeListener parent) {
this.name = name;
this.value = value;
...
slider.addChangeListener(parent);
slider.addChangeListener(this);
}
...
}
Addendum: the discussion in EventListenerList
appears to be implementation advice rather than a guarantee. The chaining approach suggested by pstanton enforces the correct order more reliably. For example, the SubPanel
's ChangeListener
can simply forward the event to the parent.
@Override
public void stateChanged(ChangeEvent e) {
...
parent.stateChanged(e);
}
Since the documentation for JSlider and JComponent etc don't mention the order of listener notification, I would hesitate to rely on it, at least without thorough testing on each subsequent version of the JRE.
If you really need to rely on the order, consider setting up a chain of listeners, ie Listener one will notify listener two etc.
A bit old and very late to answer. But My unstable mind is really forcing me to snick into.
I do believe that they maintain the order, the Component's documentation doesn't tell us much, but source code is always our friend. Let us start from
addChangeListener(listener)
function ofJSlider
:STEP 1: calling
jSlider.addChangeListener(listener)
adds thelistener
to alistener list
.STEP 2: source code of
EvenListenerList
:synchronized add(Class<T> t, T l)
: adds the listeners and corresponding type such that new listener is added at the end of theObject[]
and for an indexi
,Object[i]
is type of the listener andObject[i+1]
is the listener instance.STEP 3: The
fireStateChanged()
function ofJSlider
is responsible for sending event to every listener of the list. The source code tells us that it call each listener'sstateChanged()
function by visiting them from the end of the listener list.Summery: The mechanism of (synchronized)adding and visiting of listeners in listeners list tells us that: it maintain the LAST ADD FIRST VISIT order. That is, the later(child) added listener is going to be called first, then the previous(parent) added listener and so on. Swing event handling code runs on EDT. And as
EventQueue
dispatches the event In the same order as they areenqueued
, the child event will be dispatched prior to parent event.So I do believe the order is being maintained.