Swing Hinter die Kulissen von Events (addActionListener)

martin1989

Aktives Mitglied
Hallo!

Ich wollte mich mal tiefer beschäftigen mit der Handhabe von Events in SWING.
Vorerst mal mein Wissensstand:

Es soll eine Action ausgelöst werden, wenn ich auf einen Button klicke, dazu ist ja folgender Code nötig:

Code:
button.addActionListener(new ControllerCLass);

Hier ruft der button die Methode "addActionListener" auf, diese Methode erbt er von einer Vaterklasse. Diese Methode fügt ein Objekt der Controller Klasse hinzu, oder wie man eigentlich sagt, meldet das Objekt der Controller Klasse beim Button an. Die Controller Klasse ist für die Aktion verantwortlich, die passieren soll wenn das Event auftritt.

Dann zur Klasse ControlelrCLass:

Diese Klasse muss das Interface "ActionListener" implementieren und muss die einzige Methode die in "ActionListener" definiert ist auch verwenden. Dies ist "actionPerformed". Daher:

Code:
public class ControlleClass implements ActionListener

void actionPerformed(Action Event).

So, sobald nun jmd auf den Button klickt, erzeugt der Button automatisch ein Objekt des Typs "Action Event". Dieses wird dann an alle angemeldeten ControllerKlassen weitergeben und in den Controllerklassen wird dann die actionPerformed Methode ausgeführt.

Dies ist mein Stand der Dinge. Mich würde aber interessieren wie das genau funktioniert.

wenn ich nun mir die Methode "addActionListener" genauer anschauen, sehe ich, dass die Controller Klasse direkt einer Liste hinzugefügt wird. Oder wird hier die Klasse als Schnittstellentyp übergeben? Bedeutet dies das hier nur Klassen übergeben werden können, die das Interface ActionListener implementiert haben? Was macht .class?

Code:
 public void addActionListener(ActionListener l) {
        listenerList.add(ActionListener.class, l);
    }



Und dann muss ja auch irgendwo dann diese benachrichtigung, sobald ein "ActionEvent" erzeugt wird, definiert sein (im Konstruktor der Klasse ActionEvent?). Dann müssen ja quasi alle ControllerKlassen die in der Liste stehen benachrichtigt werden und die actionperformed methode aufgerufen werden (mit dem ActionEvent) als Übergabeparameter? Irgendwie mus es ja mid dieser "ActionListener" Schnittstelle zusammenhängen?


Ich würde mich freuen, wenn mir hier jemand dies ein wenig genauer erklären könnte?


Vielen Dank!

P.S.: ich habe schon vieles gesehen bezüglich addActionListener in dem Forum, aber ich würde es gerne noch etwas genauer erklärt bekommen :)
 
Zuletzt bearbeitet:

Tobse

Top Contributor
Was soll denn da noch passieren? Alle Listener-Objekte sind in der Liste (sagen wir mal List<ActionListener>).

Jetzt klickt der Nutzer auf den Button. Das Frame (genaure das ContentPane) bekommt das click-event vom OS. Das schaut dann, welche Komponente geklickt wurde und gibt das event an die entsprechende Komponente. Die macht es ebenso und so weiter, und so weiter, bis irgendwann der Button das Event bekommt. Der Macht dann folgendes:

Java:
ActionEvent e = ...;

Iterator<ActionListener> listenerIterator = list.iterator();
while (listenerIterator.hasNext() && !e.isConsumed())
    listenerIterator.next().actionPerformed(e);

P.S.: Alle möglichen Details kannst du im Sourcecode nachlesen.

P.P.S: Weil es micht selbst interessiert hat, habe ich hier mal den Quellcode nachgelesen. Der Klassen-Parameter (ActionListener.class) in der add-Methode ist dazu da, dass man aus der Listener-Liste später alle Listener einer bestimmten Klassen herausnehmen kann (also Objekte von versch. Klasse in der selben Liste pflegen kann).
 
Zuletzt bearbeitet:

martin1989

Aktives Mitglied
vielen dank für deine Antwort!

1) und wie sieht das aus wenn der Buttond as event bekomtm? da muss es ja auch irgend eine methode dafür geben oder zumindest deinen interator aufrufen oder? Hab mir den Konstruktor von "ActionEvent" angesehen aber nichts gefunden das mir weiterhiltg ....


2)


folgender code

Java:
 public void addActionListener(ActionListener l) {
        listenerList.add(ActionListener.class, l);
    }

bedeutet ja, dass die methode "AddActionListener" ein Interface übergeben bekommen soll (Weil ActionListener ja ein Interface ist). Ich übergebe aber eine Klasse die "nur" dieses Interface implementiert.

Damit (nach meinen Nachforschungen), kann (soll) ich hier nur Klassen übergeben die auch das Interface "ActionListener" implementiert haben. Nennt man dies "zum Interface implementieren"?

Ist auf den ersten Blick etwas verwirrend wenn ein Interface übergeben werden soll, aber dann eine Klasse übergeben wird die dieses Interface implementiert. Auf der anderen Seite kann man ja gar kein Objekt von einem Interface erzeugen, darum kann hier nur ein Objekt einer Klasse übergeben werden.

Lt. meinem Wissen kann man in einem Array ja nur Objekte der selben Klasse hinzufügen. Durch diese Schreibweise (Interace als Datentyp) sind somit alle übergebenen "Listener Klassen" vom gleichen Datentyp. Dies müsste der Sinn sein warum man hier das Interfac als Datentyp übergibt?

Damit stellt sich mir aber die Frage, warum die methode "listenerList.add" dann noch das .class übergeben bekommt?
Lt. meiner Meinung wird dein oben genannter Grund ja schon durch das Übergaben des Interface Datentypes erfüllt.
 

Tobse

Top Contributor
zu 1)

Das ActionEvent hat damit nichts zu tun; das erfährt nie, an wen es übergeben wird (ausser evtl. durch analyse des Stacktrace, aber das tut es nicht).

Der JButton hat eine Methode fireActionPerformed(ActionEvent e) (bzw. actionPerformed(ActionEvent e)).

zu 2):



folgender code [...] bedeutet ja, dass die methode "AddActionListener" ein Interface übergeben bekommen soll (Weil ActionListener ja ein Interface ist).
Falsch. Es bedeutet, dass der Parameter l ein Objekt sein muss, welches das Interface ActionListener implementiert.

Ich übergebe aber eine Klasse die "nur" dieses Interface implementiert.
Wie gesagt übergibst du ein Objekt.


"zum Interface implementieren"?
Man nennt es "das Interface implementieren".

Durch diese Schreibweise (Interace als Datentyp) sind somit alle übergebenen "Listener Klassen" vom gleichen Datentyp. Dies müsste der Sinn sein warum man hier das Interfac als Datentyp übergibt?
Nein, das ist er nicht. Wenn man einen Blick in den Quellcode von EventListenerList (die Klasse der Variable listenerList) wirft, sieht man, dass das interne Array der Klasse vom Typ "Object" ist und damit alles aufnehmen kann:

Java:
protected Object[] listenerList = NULL_ARRAY;


Damit stellt sich mir aber die Frage, warum die methode "listenerList.add" dann noch das .class übergeben bekommt?

Auch hier ist ein Blick in den Quellcode EventListenerList aufschlussreich:

Java:
// Quelle: [url=http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/javax/swing/event/EventListenerList.java#EventListenerList.add%28java.lang.Class%2Cjava.util.EventListener%29]GC: EventListenerList - javax.swing.event.EventListenerList (.java) - GrepCode Class Source[/url]

public synchronized <T extends EventListener> void add(Class<T> t, T l) {
    // ...
    listenerList[i] = t; // sinngemäß
    listenerList[i + 1] = l; // sinngemäß
    // ...
}

Ja, das bedeutet, dass l vom übergebenen Typ t sein muss. Das ist aber völlig egal wenn es dann im Array ist. DENN folgender Methodenkopf drängt es förmlich auf, dass nach der ebenfalls gespeicherten Klasse wieder gefiltert werden kann:

Java:
// Quelle: [url=http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/javax/swing/event/EventListenerList.java#EventListenerList.getListeners%28java.lang.Class%29]GC: EventListenerList - javax.swing.event.EventListenerList (.java) - GrepCode Class Source[/url]

public <T extends EventListener> T[] getListeners(Class<T> t)
 
Zuletzt bearbeitet:

martin1989

Aktives Mitglied
zu 1)

Das ActionEvent hat damit nichts zu tun; das erfährt nie, an wen es übergeben wird (ausser evtl. durch analyse des Stacktrace, aber das tut es nicht).

Ok danke!

weisst du zufällig welche methode des Buttn dieses ActionEvent dann aufnimmt bzw. übergeben bekommt?
bzw. wer ruft die methode fireActionPerformed auf?



Falsch. Es bedeutet, dass der Parameter l ein Objekt sein muss, welches das Interface ActionListener implementiert.
Ok danke verstehe!

Man nennt es "das Interface implementieren".


Ich habe das hier gelesen, dass man es so nennt?:

http://www.java-forum.org/allgemein...nterface-parameter-uebergeben.html#post220739

oder verwechsle ich das mit einer anderen anwendung von interfaces wie hier beschrieben?
Interface als Datentyp



Java:
public synchronized <T extends EventListener> void add(Class<T> t, T l) {
 
}


hm das Class<T> bedeutet ja Generics oder, dass heisst ich lege hier nicht fest welchen Typ ich übergebe oder? T steht für irgendeinen Typ?


<T extends EventListener> bedeutet das der übergebene Typ eine Subklasse von EventListener sein muss oder?

{
Ja, das bedeutet, dass l vom übergebenen Typ t sein muss. Das ist aber völlig egal wenn es dann im Array ist.


da T I steht müsste es dann nicht vom Typ T sein?

Java:
public <T extends EventListener> T[] getListeners(Class<T> t)

oh mann hier ist dann noch ein T[] in der "Mitte", für was steht denn das?



Sorry diese Schreibweisen find ich noch ein wenig verwirrend mit den <> :(
 
Zuletzt bearbeitet:

Tobse

Top Contributor
weisst du zufällig welche methode des Buttn dieses ActionEvent dann aufnimmt bzw. übergeben bekommt?
bzw. wer ruft die methode fireActionPerformed auf?

Alle Möglichen Events werden da durchgegeben. U.a. auch mouseDown und mouseUp. Ein mouseUp mit vorherigem mouseDown ist ein clicked. Und auf dem JButton löst das clicked auch das actionPerformed aus.

Ich habe das hier gelesen, dass man es so nennt?:

http://www.java-forum.org/allgemein...nterface-parameter-uebergeben.html#post220739

oder verwechsle ich das mit einer anderen anwendung von interfaces wie hier beschrieben?
Interface als Datentyp

Du verwechselt das grammatikalische Konstrukt "Etwas zum Anderen haben" (also z.B. einen Trottel zum Freund haben).


Bzgl. Generics: Ja richtig, das sind Generics und auch nicht direkt einfach (wenn auch noch bei weitem nicht das schwierigste, was geht). Lies dazu einfach das Kapitel zu Generics in deinem Java-Kurs oder Buch.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
BreakdownBob Swing JLabel verschwindet hinter Image AWT, Swing, JavaFX & SWT 2
H 2D-Grafik BufferStrategy zieht spur hinter sich her AWT, Swing, JavaFX & SWT 3
D JavaFX Mysteriöser Dropshadow hinter Tablabelschrift - Schatten kann nicht entfernt werden (FXML + CSS) AWT, Swing, JavaFX & SWT 6
D JTabbedPane - Farbe ändern im Bereich hinter den Reitern AWT, Swing, JavaFX & SWT 2
O ComboBox hinter TextField? AWT, Swing, JavaFX & SWT 8
G JDialog hinter Glasspane von JFrame. Geht das? AWT, Swing, JavaFX & SWT 3
U Streifen hinter bewegtem BufferedImage AWT, Swing, JavaFX & SWT 13
B DateComboBox öffnet sich hinter JTextarea. AWT, Swing, JavaFX & SWT 10
C Menue verschwindet hinter AWT-List Box.wie beheben? AWT, Swing, JavaFX & SWT 3
F n Fenster hinter einander AWT, Swing, JavaFX & SWT 3
D DropDownSelection Box verschwindet hinter JTextArea AWT, Swing, JavaFX & SWT 2
G mouse events AWT, Swing, JavaFX & SWT 6
Heldderschatten Java Events und Interfaces AWT, Swing, JavaFX & SWT 18
T Swing Änderung des ActionListener Events nach Klick auf JButton AWT, Swing, JavaFX & SWT 2
D Swing Events vom JLayer abfangen AWT, Swing, JavaFX & SWT 2
D Transparentes Hauptfenster Events AWT, Swing, JavaFX & SWT 1
N JTextArea Events weiterleiten AWT, Swing, JavaFX & SWT 3
R SWT Eigene Events erstellen und werfen AWT, Swing, JavaFX & SWT 59
S Mouse Events in einer sortierten JTable unterscheiden AWT, Swing, JavaFX & SWT 18
C Swing Simulation von Drag and Drop Events AWT, Swing, JavaFX & SWT 3
J Events und Sleep? AWT, Swing, JavaFX & SWT 4
C MouseMotionListener fired keine Events mehr wenn in Button AWT, Swing, JavaFX & SWT 2
E JFace ListSelectionDialog & Mouse-Events? AWT, Swing, JavaFX & SWT 2
N Variablen in Events AWT, Swing, JavaFX & SWT 4
P AWT MouseListener unklare abhandlung von Events AWT, Swing, JavaFX & SWT 3
L Swing Auslöser eines Events finden? AWT, Swing, JavaFX & SWT 6
R JTable - eigener Editor - Mouse events AWT, Swing, JavaFX & SWT 2
C keine weiteren Events während Drag&Drop Operation möglich? AWT, Swing, JavaFX & SWT 5
Weltall 7 AWT Maus-Events werden doppelt ausgeführt AWT, Swing, JavaFX & SWT 12
0 Events werden nicht ausgelöst AWT, Swing, JavaFX & SWT 2
V Swing Auslösen von zwei Events hintereinander AWT, Swing, JavaFX & SWT 4
T Swing Control und Events AWT, Swing, JavaFX & SWT 8
MrMilti Gezeichnete Java2D Elemente mit Events versehen AWT, Swing, JavaFX & SWT 3
R Events - Nur auf eines reagieren AWT, Swing, JavaFX & SWT 3
T JComboBox: ActionListener/ItemListener wie nur auf bestimmte Events reagieren? AWT, Swing, JavaFX & SWT 7
B Swing setDefaultButton geht nicht - Komponente fängt Events ab AWT, Swing, JavaFX & SWT 5
R Key und Mouse Events AWT, Swing, JavaFX & SWT 2
K Alle Events abfangen mit GlassPane AWT, Swing, JavaFX & SWT 7
T SWT - Table Events AWT, Swing, JavaFX & SWT 3
hdi Events nicht plattform-unabhängig? AWT, Swing, JavaFX & SWT 14
M SWT: eigene Events AWT, Swing, JavaFX & SWT 9
G Reihenfolge von Events AWT, Swing, JavaFX & SWT 4
D Events bei Tabs in einem Editor AWT, Swing, JavaFX & SWT 2
F Probleme mit MouseWheel events in SWT AWT, Swing, JavaFX & SWT 13
M Globale Events in Windows abfangen AWT, Swing, JavaFX & SWT 2
T Hilfe zu Events? AWT, Swing, JavaFX & SWT 6
S Events abfangen, nicht durchlassen AWT, Swing, JavaFX & SWT 2
T Events unterdrücken AWT, Swing, JavaFX & SWT 8
G An die Quelle einen events kommen AWT, Swing, JavaFX & SWT 2
M Problem mit verschachtelten Events und kein ausweg in sicht AWT, Swing, JavaFX & SWT 3
W Vom JPanel bekomme ich keine Events AWT, Swing, JavaFX & SWT 5
V Events an untere Layers weitergeben AWT, Swing, JavaFX & SWT 2
V events skippen AWT, Swing, JavaFX & SWT 14
M Events auslagern? AWT, Swing, JavaFX & SWT 6
F Events AWT, Swing, JavaFX & SWT 8
N SWT: GUI Windows Events AWT, Swing, JavaFX & SWT 8
I Globale Tastatur-Events abfragen AWT, Swing, JavaFX & SWT 3
D Events werden zu oft aufgerufen AWT, Swing, JavaFX & SWT 4
G Events AWT, Swing, JavaFX & SWT 2
K Mouse Events der Scrollbar/pane AWT, Swing, JavaFX & SWT 2
S Events fremdauslösen AWT, Swing, JavaFX & SWT 17
K Doppelte Events AWT, Swing, JavaFX & SWT 4
A Combobox Focus-Events, Tab in Tabelle AWT, Swing, JavaFX & SWT 7
D Events, Listener, GUI . Größeres Projekt AWT, Swing, JavaFX & SWT 4
A Vielschichtige GUI und Events? AWT, Swing, JavaFX & SWT 4
V JList mit Events Steuern ? AWT, Swing, JavaFX & SWT 15
S Rechner zu schnell für Events? AWT, Swing, JavaFX & SWT 14
G JTable und Events AWT, Swing, JavaFX & SWT 4
S Events bei 2 gleichen Jtree abfangen AWT, Swing, JavaFX & SWT 3
ShapeShifter JButton erzeugt zwei Events AWT, Swing, JavaFX & SWT 4
B Eigenes Events AWT, Swing, JavaFX & SWT 3
T JScrollPane-Events AWT, Swing, JavaFX & SWT 2
M JTable und Events AWT, Swing, JavaFX & SWT 4
K JComboBox: Endlosschleife durch Events AWT, Swing, JavaFX & SWT 4
K [JComboBox] ENTER löst zwei events aus? AWT, Swing, JavaFX & SWT 2
M Glasspane und dispatchen von Events AWT, Swing, JavaFX & SWT 6
H Events manuell aufrufen AWT, Swing, JavaFX & SWT 4
F JComboBox setEditable( true ) auf Tastatur Events reagieren AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben