Wydarzenia i słuchacze

Jak utworzyć zdarzenie niestandardowe i jak je uruchomić, aby komponent mógł uzyskać zdarzenie?

Przed patrząc na zdarzenia niestandardowego, pozwala spojrzeć na wcześniej istniejące imprezy: the ActionEvent.

Komponenty, takie jak Buttoni JButtonuruchamiają się, ActionEventsaby wskazać jakieś działanie zdefiniowane przez komponent. Na przykład Buttonodpala się, ActionEventgdy użytkownik go naciśnie. Celem zdarzenia jest poinformowanie słuchacza, że ​​coś się stało z komponentem w GUI. Wydarzenie zawiera wszystkie informacje, których słuchacz potrzebuje, aby dowiedzieć się, co się stało i komu to się wydarzyło (co i kto z tego wydarzenia). Wydarzenie musi zawierać wystarczającą ilość informacji, aby w pełni się opisać. W ten sposób słuchacz może dowiedzieć się, co dokładnie się wydarzyło i odpowiedzieć w znaczący sposób.

ActionEventObejmuje metody uczenia ciąg ACTION za poleceń, modyfikatory i ciąg identyfikacyjny. getActionCommand()Metoda zwraca ciąg poleceń, który wskazuje, przeznaczony akcja zdarzenia, takie jak druk lub kopii (what). getSource()Sposób powraca do obiektu, który generuje zdarzeń (WHO).

Aby otrzymać wiadomość ActionEvent, słuchacz musi zaimplementować ActionListenerinterfejs i zarejestrować się w komponencie. Ponadto składnik musi śledzić swoich słuchaczy, aby powiadomić ich o zdarzeniu.

Używając ActionEventprzykładu jako modelu, możemy łatwo zobaczyć elementy potrzebne komponentowi do wygenerowania zdarzenia i słuchaczowi do nasłuchiwania zdarzenia. Na wysokim poziomie są trzy elementy:

  1. Składnik
  2. Klasa eventowa
  3. Interfejs nasłuchujący

Przyjrzyjmy się każdemu z nich osobno.

Składnik

Komponenty generują zdarzenia. Zdarzenie to sposób komponentu na poinformowanie słuchacza, że ​​coś się wydarzyło. Dlatego komponent musi udostępniać mechanizm rejestrowania i wyrejestrowywania detektorów zdarzeń. Komponent musi również śledzić swoich słuchaczy i przekazywać im zdarzenia.

Mechanizm rejestracji / wyrejestrowania i śledzenia pozostawia się poszczególnym komponentom. Jednak składnik zwykle będzie miał przypisane addXXXListeneri removeXXXListenerdla każdego typu zdarzenia, które generuje. Wewnętrznie komponent może przechowywać słuchacza, jak tylko wybierze; zwykle jednak komponenty przechowują słuchacze w formacie java.util.Vectorlub javax.swing.event.EventListenerList. Aby odpalić zdarzenie do swoich detektorów, komponent po prostu przechodzi przez swoją listę detektorów i przekazuje zdarzenie do każdego detektora, wywołując metodę wysyłania zdarzenia detektora.

Czas na przykład:

... EventListenerList xxxListeners = new EventListnerList(); public void addXXXListener(XXXListener listener) { xxxListeners.add(XXXListener.class, listener); } public void removeXXXListener(XXXListener listener) { xxxListeners.remove(XXXListener.class, listener); } protected void fireXXX(XXXEvent xxxEvent) { Object[] listeners = xxxListeners.getListenerList(); // loop through each listener and pass on the event if needed Int numListeners = listeners.length; for (int i = 0; i
    

This example shows how to register, deregister, and fire events of type XXXEvent. Listeners can register and deregister themselves through the addXXXListener() and removeXXXListener() methods. When an event occurs, the component creates an event object and passes it to the fireXXX() method, where it is passed to the listeners.

The example defines a generic recipe that all components can follow. However, in order for the example to work, you must define an XXXEvent and an XXXListener interface.

The event class

The event holds all of the information necessary for a listener to figure out what happened. The information included is really event specific. Just think about the event carefully and design the event class to hold whatever information is necessary to fully describe the event to a listener. Events normally extend the java.awt.AWTEvent event class.

The listener interface

An event listener interface defines the methods used by a component to dispatch events. Each event type will have at least one corresponding dispatch method in a listener interface.

A listener interface takes the following generic format:

public interface XXXListener extends EventListener { // event dispatch methods somethingHappened(XXXEvent e); somethingElseHappened(XXXEvent e); ... } 

To listen for an event, a listener must implement the XXXListener interface and register itself with the component. When an event occurs, the component will call the proper dispatch method. The methods are defined in an interface so that any object can receive the event. As long as the listener implements the interface, the component will know how to dispatch the event to the listener.

Wrap-up

As you can see, there are dependencies between some of the pieces. The listener interface corresponds directly to the event. The event is necessarily the dispatch method's argument.

The component corresponds directly with the event and listener. It needs to know about each so that it can create events, dispatch events, and register listeners.

Unlike the other two pieces, the event object is independent. As a result, many components are free to fire off the event type. Furthermore, multiple interfaces may define methods to dispatch the event.

Tony Sintes is a principal consultant at BroadVision. Tony, a Sun-certified Java 1.1 programmer and Java 2 developer, has worked with Java since 1997.

This story, "Events and listeners" was originally published by JavaWorld .