Zielony Smok - logo witryny

Generowanie (własnych) zdarzeń dziedziczących po EventObject – sposób 1

W poprzednich wpisach dotyczących zdarzeń opisaliśmy tworzenie klas zdarzeń i klas listenerów w przypadku, gdy nasza klasa dziedziczyła po klasie JComponent, a zdarzenia po AWTEvent. Nie zawsze jest to wskazane czy możliwe. Dziedziczenie po klasie JComponent obciąża klasę setkami niepotrzebnych metod. Jeżeli klasa nie dziedziczy po klasie JComponent to musimy poradzić sobie inaczej.

Tworzymy klasę zdarzenia dziedziczącą po klasie EventObject. W naszym przypadku jest to klasa SmokEvent.

Klasa SmokEvent
package events3;
import java.util.*;
class SmokEvent extends EventObject {
    private static final long serialVersionUID = 4133048828738474610L;
    public SmokEvent(Smok source) {
        super(source);
    }
}

W klasie tej wskazujemy obiekt, który będzie generował to zdarzenie.

Następnie tworzymy klasę listenera SmokListener.

Klasa SmokListener
package events3;
import java.util.*;
interface SmokListener extends EventListener {
    void smokZasnal(SmokEvent e);
    void smokObudzilSie(SmokEvent e);
}

Jest to klasa interfejsowa dziedzicząca po klasie EventListener. W niej umieszczamy dwie metody z argumentem SmokEvent.

Następnie piszemy klasę Smok.

Klasa Smok
package events3;
import java.util.*;
class Smok {
    private static final long serialVersionUID = 5496971741095724065L;
    private final Vector<SmokListener> listeners = new Vector<>();
    public Smok() {
    }
    @SuppressWarnings("unchecked")
    public void uspijSmoka() {
        Vector<SmokListener> v = (Vector<SmokListener>) listeners.clone();
        SmokEvent event = new SmokEvent(this);
        Enumeration<SmokListener> e = v.elements();
        while (e.hasMoreElements())
            (e.nextElement()).smokZasnal(event);
    }
    @SuppressWarnings("unchecked")
    public void obudzSmoka() {
        Vector<SmokListener> v = (Vector<SmokListener>) listeners.clone();
        SmokEvent event = new SmokEvent(this);
        Enumeration<SmokListener> e = v.elements();
        while (e.hasMoreElements())
            (e.nextElement()).smokObudzilSie(event);
    }
    public synchronized void addSmokListener(SmokListener d) {
        listeners.addElement(d);
    }
    public synchronized void removeSmokListener(SmokListener d) {
        listeners.removeElement(d);
    }
}

Klasa tworzy kolekcję listenerów typu SmokListener. Następnie tworzymy dwie metody generujące zdarzenia. W metodzie uspijSmoka() tworzymy klon kolekcji listenerów, generujemy zdarzenia dla tego (this) smoka i wskazuje, którą metodę listenera należy uruchomić. Podobnie jest w metodzie obudzSmoka().

Następnie dodajemy dwie metody umożliwiające dodawanie i usuwanie listenerów do listy listenerów. zauważmy, że lista listenerów jest wewnętrzna dla obiektu Smok, a nie dziedziczona z innej klasy.

Całość uruchamiamy w klasie Main, która jest praktycznie identyczna jak w poprzednich projektach.

Klasa Main
package events3;
class Main {
    public static void main(String[] args) {
        Smok smok = new Smok();
        smok.addSmokListener(new SmokListener() {
            @Override
            public void smokObudzilSie(SmokEvent event) {
                System.out.println("Smok obudził się");
            }
            @Override
            public void smokZasnal(SmokEvent event) {
                System.out.println("Smok zasnął");
            }
        });
        smok.uspijSmoka();
        smok.obudzSmoka();
    }
}

Po jej uruchomieniu zobaczymy

Smok zasnął
Smok obudził się