# Eigene Events feuern



## Saberrider (6. Jun 2009)

Moin.
Bisher habe ich UI's meistens mittels dem Observer Pattern aktualisiert.
Ich wollte mir aber letzt auch mal das feuern eigene Events anschauen - allerdings steige ich da leider nicht durch.
Also Beispiel hab ich n Beispiel aus dem Buch Swing Hacks (Abschnitt 94) genommen: Hack*94.*Fire Events and Stay Bug Free - Swing Hacks - Í¼Êé - JAVA ±à³Ì×ÊÁÏÅ£±ÇÕ¾

Was ich hier nicht verstehe:
1. Wieso wird hier für den Test ne abstrakte Klasse genommen - kein Interface???
2. Was ist hier 'Observer' und was 'Observable' (ich hoff die Formulierung macht Sinn)

Ich hab jetzt schon zig Mal versucht, das Beispiel für mich umzumünzen - einfach n TextFeld einer UI von irgend wo her mittels Event abzudaten - immer ohne Erfolg...
Wie macht ihr das???

Der besagte code aus dem Beispiel: 

Testklasse:

```
public abstract class TestEventSource {
	public abstract void addListener (TestEventListener l); 
	public abstract void removeListener (TestEventListener l);
	public abstract void fireEvent (java.util.EventObject o);    
	public void test() {
		addListener (new TestEventListener ("A"));
		addListener (new TestEventListener ("B"));
		addListener (new TestEventListener ("C"));
		addListener (new TestEventListener ("D"));
		addListener (new TestEventListener ("E"));
		fireEvent(new java.util.EventObject(this));
	}
}
```

Listener:

```
import java.util.*;
	public class TestEventListener extends Object 
		implements EventListener { 
		String id; 
		public TestEventListener (String id) {
			this.id = id;
		}
		public void handleEvent (EventObject o) {

			System.out.println (id + " called"); 
			if (id.equals ("C")) {   
				((TestEventSource) o.getSource()).removeListener (this); 
			}
		}
	}
```

EventfeuerKlasse/ Liste der Events

```
import java.util.*;
	import javax.swing.event.*;
	public class EventListenerListEventSource
		extends TestEventSource {
		EventListenerList listenerList = new EventListenerList();
		public void addListener (TestEventListener l) {
			listenerList.add (TestEventListener.class, l);
		}

		public void removeListener (TestEventListener l) {
			listenerList.remove (TestEventListener.class, l);
		}

		public void fireEvent (EventObject o) {
			Object[] listeners = listenerList.getListenerList();
			for (int i = listeners.length-2; i>=0; i-=2) {
				if (listeners[i] == TestEventListener.class) {
				((TestEventListener) listeners[i+1]).handleEvent(o);
				}
			}
		}

		public static void main (String[] args) {
			EventListenerListEventSource bfles =        
				new EventListenerListEventSource();     
			bfles.test(); 
		}
	}
```


----------



## SlaterB (6. Jun 2009)

> 1. Wieso wird hier für den Test ne abstrakte Klasse genommen - kein Interface???

abstrakte Klassen haben gegenüber Interfacen den Vorteil, dass bestimmte Methoden schon komplett implementiert werden können,
so auch hier -> die Methode  test()

> 2. Was ist hier 'Observer' und was 'Observable' (ich hoff die Formulierung macht Sinn)

Observer sind die Listener, Observable das Objekt, welches die Listener kennt und die Events abfeuert,
wenn man die Begriffe nur ein bisschen verstanden hat, dann ist doch die Lage hier klar?

-------

das ganze Beispiel hat nichts mit Swing oder UI zu tun,
es definiert einen eigenen Kreis aus Objekten und zeigt darin einige Probleme der Event-Verarbeitung,
im Grunde nur ein Problem: removeListener() während ein Event abgearbeitet wird

was meinst du mit TextFeld? Swing JTextField?
willst du auf Tastatur/ Maus-Eingaben aus diesem Standard-Framework reagieren?
benutzte ActionListener, DocumentListener, MouseListener, KeyListener usw., kennst du diese Grundlagen?

ob du dann direkt irgendwas verarbeitest oder eigene andere Listener informierst, ist danach zu entscheiden


----------



## Saberrider (6. Jun 2009)

Sorry, ich hätte meinen Versuch des 'ummünzes' etwas genauer beschreiben sollen.
Also wie gesagt hatte ich das obige Beispiel als Grundbauplan.

Meine Applikation sieht so aus, das ich von mein Model aus meine UI updaten möchte (beispielsweise möchte ich eine Statusinfo in ein TextFeld schreiben).
Bisher hab ich sowas immer über Observer gemacht - jetzt möchte ich aber mal eigene Events probieren. Die UI Geschichte dient dabei nur als Beispiel.

Wenn ich mir Java Standart Events anschaue (ActionListener) als Beispiel: bei nem button mach ich ein AddActionListener - danach muß ich das Interface vom Eventlistener in der Klasse implementieren (wenn alles in einer Klasse gemacht wird).
Wenn ich nun aber nicht ein 'normalen' Listener implementieren möchte sondern den aus obigem Beispiel: auf die gleiche Weise geht das ja nicht, weil ich kein Interface habe (sondern die abstrakte Klasse).
Wie mache ich das... Ich müßte doch dann doch... Ich steh hier voll aufm Schlauch*nerv*
Ich kanns nicht mal richtig formulieren...


----------



## SlaterB (6. Jun 2009)

TestEventSource bietet ja nur die test()-Methode, die brauchst du gar nicht für dein Programm, also raus damit,
schon kannst du den Rest zum Interface machen

das TextFeld wäre dann eine TestEventSource, 
da du TextFeld eh als normale Klasse implementieren musst, könntest du ganz auf ein Interface verzichten,
so wie JTextField addActionListener() hat, braucht dein TextFeld auch eine addListener() Methode, eine Liste zur Verwaltung usw.

ich frage mich nur, wann du welche Events feuern möchtest,
auf Usereingaben wie Tastatur/ Maus kann man nämlich nicht einfach so reagieren, da steckt im Falle von Swing ein Riesen-Framework bestimmt auch mit nativen Methoden hinter,
daher mein Hinweis, dass du wahrscheinlich an einem normalen JTextField einen Swing-Listener registerien musst, der die Events liefert, aus denen du dann neue eigene Events an eigene Listener weiterleiten kannst


----------

