# EventListenerList vs. ArrayList



## KrokoDiehl (1. Dez 2009)

Morgen zusammen.

Ich habe nun schon ein paar GUI-Komponenten hinter mir, bei denen ich die Verwaltung von Event-Listener machen musste. Z.B. wenn man das _TableModel _implementiert, hat man auch die Methoden 
	
	
	
	





```
add
```
- und 
	
	
	
	





```
removeTableModelListener()
```
.
Bisher dachte ich mir, dass ich dazu die bereits bestehende Klasse EventListenerList benutze, um die hinzugefügten Listener zu hinterlegen. Allerdings bin ich nun schon an einigen Stellen über die Reihenfolge der Listener gestolpert und habe es daher über eine _ArrayList _gemacht.

Nun stellt sich mir allgemein die Frage, welchen Sinn es macht, die _EventListenerList _zu benutzen, so wie sie allgemein in Swing benutzt wird.
Hier mal eine Gegenüberstellung:

```
protected EventListenerList eventListeners;

public void addBlaListener(BlaListener listener)
{
    eventListeners.add(BlaListener.class, listener);
}

// Variante 1: So machte ich es bisher, führte aber teilweise zu 
// unerwünschtem Verhalten, weil ich die Liste von vorn nach hinten durchging,
// Swing macht es idR andersherum.
public void fireBlaEvent()
{
    BlaListener[] listener = eventListeners.getListeners(BlaListener.class);
    for (BlaListener l : listener)
        l.blaHappend(new BlaEvent(this));
}

// Variante 2: So ist es quasi überall in Swing implementiert, aber es scheint
// mir umständlich und ich finde es nicht sonderlich leserlich
public void fireBlaEvent()
{
    Object[] listener = eventListeners.getListenerList();
    for (int i = listener.length-2; i >= 0; i -= 2)
    {
        if (listener[i] == BlaListener.class)
        {
            ((BlaListener)listener[i+1]).blaHappend(new BlaEvent(this));
        }
    } //for
}
```

Ich bin nun teilweise dazu übergegangen eine _ArrayList _zu verwenden. In den Meisten Implementierungen hatte ich es bisher nur mit einer Art Listener zutun (Bsp. _TableModel_):

```
protected ArrayList<BlaListener> eventListener;

// addBlaListener düfte klar sein...

public void fireBlaEvent()
{
    for (BlaListener listener : eventListener)
    {
        listener.blaHappend(new BlaEvent(this));
    }
}
```

Nun sind meine Fragen: 
Spricht etwas gegen ArrayList und für EventListenerList?
Sollte ich die Reihenfolge der Listener irgendwie anders beachten?

Meine Beobachtung ist eher gewesen, dass meine Variante 1 zu teilsweise seltsamen Verhalten führte, z.B. dass Zellen in JTables nicht direkt selektiert wurden, oder erst der CellEditor ansprang, dann wurde die Zelle aber selektiert und der Editor gleich wieder verworfen.
Also ich wäre um ein paar Erfahrungswerte dankbar. Derzeit tendiere ich mehr zu den _ArrayList_s, da ich diese Variante lesbarer finde.


----------



## SlaterB (1. Dez 2009)

viel macht die Klasse nicht, hat auch nur 200 Zeilen Code, getListeners(BlaListener.class) ist interessant,
und dann ist da noch Code zur Serialisierung, wahrscheinlich nicht so wichtig



> * The main benefits that this class provides are that it is relatively
> * cheap in the case of no listeners, and it provides serialization for
> * event-listener lists in a single place, as well as a degree of MT safety
> * (when used correctly).


API


----------



## Marco13 (1. Dez 2009)

Die EventListenerList kann afaik Listener beliebigen Typs speichern - sie enthält abwechselnd die Klasse (also das Class-Objekt) für den Typ, und danach das Objekt selbst. 
Wie sich das "unerwünschte Verhalten" geäußert hat, hast du nicht gesagt.


Deine Letzte Lösung ist an sich OK, aber nicht Threadsafe, und kann zu einem Problem führen - wenn die (absurde???) Situation eintritt, dass einer der Listener einen neuen Listener zu der Liste hinzufügt (dann haut's ihn beim Iterieren über die Liste mit einer ConcurrentModificationException raus). Verhindern könnte man das in diesem Fall mit einer CopyOnWriteArrayList.


----------



## KrokoDiehl (3. Dez 2009)

Ok, das mit der Threadsicherheit habe ich bisher noch nicht bedacht. Aber da sonst offenbar wenig gegen eine "eigene _EventListenerList_" spricht, spreche ich das mit den Kollegen ab, was wir konsequenterweise benutzen sollten.
Also danke euch.


----------

