2010-07-13 9 views
12

Quando ho imparato a generare eventi in Java, ho acquisito familiarità con EventListenerList. Quando creo i miei ascoltatori, scrivo l'ascoltatore modo che si estende EventListener, li devo conservare in un eventListenerList, e il mio metodo di fuoco sarebbe passare attraverso i listener di eventi come questo: codiceQuando utilizzare EventListenerList anziché una raccolta generale di listener

protected void fireChangeOccurred(Change change) { 
    Object[] listeners = listenerList.getListenerList(); 
    for (int i = listeners.length-2; i>=0; i-=2) { 
     if (listeners[i]==ChangeListener.class) { 
      ((ChangeListener)listeners[i+1]).changeOccurred(change); 
     } 
    } 
} 

Ora sto rivedendo che semplicemente mette gli ascoltatori in un HashMap (potrebbe essere qualsiasi raccolta), l'interfaccia ascoltatore non si estende EventListener, e il metodo di fuoco assomiglia a questo:

protected void fireChangeOccurred(Change change) { 
    for (ChangeListener listener : listeners) { 
     listener.changeOccurred(change); 
    } 
} 

Quali sono i vantaggi di utilizzare eventListenerList invece di mantenere la mia lista di ascoltatori? Interessa solo se gli ascoltatori si trovano in un componente Swing: è importante per il thread di invio eventi?

+5

Giusto per essere sicuri, quei 2 loop non sono uguali: il primo itera l'ultimo al primo e il secondo itera il penultimo. Se un listener è autorizzato a rimuovere se stesso (che di solito sono), allora ti consigliamo di eseguire un'iterazione dell'ultimo per evitare di saltare l'ascoltatore successivo se quello corrente viene rimosso. –

risposta

6

Per me, il vantaggio principale di EventListenerList è se la classe contenente ha (o potrebbe avere) più di uno tipo di listener. Molti componenti Swing fanno; quello che stai recensendo non può. Il secondo esempio è più breve, ma presenta una limitazione implicita del design.

+0

Ma non dovresti semplicemente tenere un elenco separato di listener - List vs. List , ad esempio? –

+0

@David: Sì, e così via per ogni tipo di listener; 'JTable' ha fino a otto, ma ha ancora una sola lista. L'array 'EventListenerList' è legacy; per gli eventi senza swing, una raccolta ha un senso. Conserverei comunque il token di tipo. – trashgod

+0

@David: per riferimento, [tag: jfreechart] è un esempio concreto di una libreria che utilizza 'EventListenerList' per gestire più tipi di eventi. – trashgod

3

Non ci sono grandi vantaggi oggigiorno. Solo piccole ottimizzazioni. Ecco cosa JavaDocs dice:

principali benefici che questa classe fornisce sono che è relativamente a buon mercato nel caso di mancata ascoltatori, e fornisce serializzazione per l'evento-ascoltatore elenca in un unico luogo, come bene come un grado di sicurezza MT (se usato correttamente)

Con JVM e collezioni moderni non importa. Ma quello che potresti fare con la tua implementazione è fornire il modo di attivare i cambiamenti su EDT se usi Swing - sarebbe vantaggioso.

7

EventListenerList ha un method, getListeners(Class<T> t), in particolare per il caso in cui si è interessati a un solo tipo di evento.

Ecco un esempio di come usarlo:

protected void fireChangeOccurred(Change change) { 
    for (ChangeListener listener: 
     listenerList.getListeners(ChangeListener.class)) { 
      listener.stateChanged(new ChangeEvent(this)); 
    } 
} 

Se si sceglie di mantenere la propria collezione di ascoltatori, vi consiglio un CopyOnWriteArrayList.

Problemi correlati