Немного стар и очень поздно, чтобы ответить. Но мой неустойчивый ум действительно заставляет меня суетиться.
Могу ли я рассчитывать на этот заказ или я должен отправить другое
событие?
Я верю, что они поддерживают порядок, документация Компонента нам мало что говорит, но исходный код всегда наш друг. Давайте начнем с addChangeListener(listener)
функции JSlider
:
ШАГ 1: вызов jSlider.addChangeListener(listener)
добавляет listener
к listener list
.
public void addChangeListener(ChangeListener l) {
listenerList.add(ChangeListener.class, l);
}
ШАГ 2: исходный код EvenListenerList
: synchronized add(Class<T> t, T l)
: добавляет слушателей и соответствующий тип, так что новый слушатель добавляется в конце Object[]
и для индекса i
, Object[i]
- это тип слушателя, а Object[i+1]
- это экземпляр слушателя.
public synchronized <T extends EventListener> void add(Class<T> t, T l) {
// There were other checking here
// omitted as irrelevant to the discussion
} else {
// Otherwise copy the array and add the new listener
int i = listenerList.length;
Object[] tmp = new Object[i+2];
System.arraycopy(listenerList, 0, tmp, 0, i);
tmp[i] = t; // add the class type
tmp[i+1] = l; // add the listener instance
listenerList = tmp;
}
}
ШАГ 3: Функция fireStateChanged()
в JSlider
отвечает за отправку события каждому слушателю списка. Исходный код говорит нам, что он вызывает функцию stateChanged()
каждого слушателя, посещая их из конца списка слушателей.
protected void fireStateChanged() {
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i]==ChangeListener.class) {
if (changeEvent == null) {
changeEvent = new ChangeEvent(this);
}
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
}
}
}
Summery: Механизм (синхронизированного) добавления и посещения слушателей в списке слушателей говорит нам, что: он поддерживает порядок LAST ADD FIRST VISIT. То есть сначала будет вызываться добавленный позднее (дочерний) прослушиватель, затем предыдущий (родительский) добавленный прослушиватель и так далее. Код обработки событий Swing работает на EDT. И когда EventQueue
отправляет событие в том же порядке, что и enqueued
, дочернее событие будет отправлено до родительского события.
Так что я верю, что приказ поддерживается.