Wie mache ich ein eigenes Event mit eigenem Listener?

GoldKaetzchen

Grünschnabel
Hallo Leute!
Ich wollte mir ein eigenes Event stricken das genau dann ausgelöst wird, wenn ich
eine bestimmten Zähler in einem Object über Max bekomme, also sozusagen ein Überlauf-Event, und dann soll in einem anderen Objekt dieses Event mitbekommen werden ohne dass, das Objekt ständig abgefragt werden muss.
Also dachte ich mir ich mache mir ein eigenes Event und einen Passenden Listener dazu und registriere dann den Listener bei dem Eventerzeuger...
Soweit so gut aber wie mach ich das?
Ich muss glaube ich EventListener vom AWT erweitern aber was kommt dann?
Hat einer vielleicht einen Tip oder kennt eine Seite wo ich das ganze "leicht" mir aneignen kann?

:D
 
Snapes HowTo für Listener:

1. Listener als Interface anlegen
Code:
public Interface MyListener
{public void reactOnNotification();}

2. Die Klasse, die reagieren soll, als Listener bei der Klasse registrieren, die die Kontrolle hält:
Code:
public class MyClass implements MyListener
{
 // im Konstruktor z.B.:
 myReference.addMyListener(this);
 public void reactOnNotification(){//aktualisiere irgendwas}
}

3. Und in der myReference-Klasse werden die Listener verwaltet, z.B.
Code:
public class DataClass
{
 List alListener = new ArrayList();
 public void addMyListener(MyListener newListener)
 { alListener.add(newListener); }
 private void notifyMyListener()
 { for (int i = 0; i < alListener.size(); i++)
  {
   MyListener listener = (MyListener)alListener.get(i);
   listener.reactOnNotification();
  }
  }
}

Damit muss in der DataClass nur bei Bedarf - also wenn sich das Datenmodell o.ä. geändert hat - die Methode notifyListener() aufgerufen werden.
Wenn weitere Klassen von diesen Daten abhängen, ist lediglich die gleiche Umsetzung wie im o.a. Beispiel für MyClass anzuwenden.
 
Hallo!

Wäre es nicht Sinnvoller, das eigene Event von der Klasse java.util.EventObject bzw. von einer seiner Spezialisierungen abzuleiten? -> Das würde mehr Konsistenz in die API bringen.
Weiterhin gilt: Mit selbst definierten Events immer vorsichtig sein -> so wenige wir möglich! Am besten gar keine eigenen, es gibt fast immer einer passende Entsprechung in der Java API.

Gruß Tom
 
Thomas Darimont hat gesagt.:
Hallo!

Wäre es nicht Sinnvoller, das eigene Event von der Klasse java.util.EventObject bzw. von einer seiner Spezialisierungen abzuleiten? -> Das würde mehr Konsistenz in die API bringen.

Ergibt m.E. nur dann Sinn, wenn das Event auch notwendige Information an den Listener übergibt.

Weiterhin gilt: Mit selbst definierten Events immer vorsichtig sein -> so wenige wir möglich! Am besten gar keine eigenen, es gibt fast immer einer passende Entsprechung in der Java API.

Gruß Tom

Das spricht durchaus für meinen Ansatz ohne Event, s.o. ;)
 
Hallo!

Ich bin mir aber nicht sicher, ob das Ganze in dem Fall noch ein Event ist... bzw. ob das nicht besser über eine Exception erledigt werden sollte... dein Modell sieht mir wie ein einfacher Callback-Mechanismus aus. Die Implementierungen von public void reactOnNotification(){...} sind anscheinend sehr Anwendungsfallspezifisch. Wäre es in solchen Situationen nicht besser auf dieses Callback "Drumherum" zu verzichten und in den geeigenten Situationen die passende Business Methode aufzurufen? -> Da diese Aufgrund der eher Anwendungsspezifischen Natur recht selten Wiederverwendet werden können?! Wie gesagt ein Event Mechanismus so ganz ohne Event...? Ein Event signalisiert doch eine Nachricht und diese Nachricht hat eigentlich auch immer Zusatzinformationen. Im Java Event Modell sollte zumindest mal die Ereignisquelle amd die Behandlungsroutine mitgegeben werden (Wo wir wieder beim EventObject wären *g*).

Gruß Tom
 
Thomas Darimont hat gesagt.:
Hallo!

Ich bin mir aber nicht sicher, ob das Ganze in dem Fall noch ein Event ist... bzw. ob das nicht besser über eine Exception erledigt werden sollte... dein Modell sieht mir wie ein einfacher Callback-Mechanismus aus. Die Implementierungen von public void reactOnNotification(){...} sind anscheinend sehr Anwendungsfallspezifisch.

Das ist ja gerade das Schöne daran. Man nehme eine Klasse Datenkern und zwei Masken. Beide Masken greifen auf den Datenkern zu, zeigen aber unterschiedliche Konstellationen an.

Wäre es in solchen Situationen nicht besser auf dieses Callback "Drumherum" zu verzichten und in den geeigenten Situationen die passende Business Methode aufzurufen? -> Da diese Aufgrund der eher Anwendungsspezifischen Natur recht selten Wiederverwendet werden können?!

Ich kann Dir grad nicht folgen, worauf Du hinaus willst.

Wie gesagt ein Event Mechanismus so ganz ohne Event...? Ein Event signalisiert doch eine Nachricht und diese Nachricht hat eigentlich auch immer Zusatzinformationen. Im Java Event Modell sollte zumindest mal die Ereignisquelle amd die Behandlungsroutine mitgegeben werden (Wo wir wieder beim EventObject wären *g*).

Gruß Tom

Im o.a. Beispiel könnte ja einfach eine Referenz auf den Datenkern übergegeben werden. Oder nicht? :-?
 
Hallo Snape,
hallo Thomas!

vielen Dank für die Ideen, ich hab in der Zwischenzeit auch was ausgebuddelt.
Was haltet Ihr von diesem Ansatz?

zuerst eine Klasse von EventObject ableiten, die macht nichts ausser das sie das Objekt das das Event ausgelöst hat im EventObject kapselt über den Aufruf super(Objekt).

import java.util.EventObject;


public class UeberlaufEvent extends EventObject {

public UeberlaufEvent(Object source) {
super(source);
}

public static void main(String[] args) {
}
}

Dann hab ich noch ein Interface von EventListeners abgeleitet und das nenne ich dann so
wie ich das Event brauche also in dem Fall UeberlaufEvent, in dem Interface hab ich dann die
Funktion die ausgelöst werden soll von denen die das Event mithören, ich hab das jetzt vorläufig auch public void ueberlauf() genannt.

import java.util.EventListener;

public interface UeberlaufEventListener extends EventListener {
public void ueberlauf (UeberlaufEvent e) ;

}

Dann hab ich noch in der Klass in der die Events gefeuert werden koennen fireUeberlauf()
implementiert in der allen registrierten Listenern ein neues UeberlaufEvent verpasst wird.
und addListener(Listener l) und removeListener(Listener l)

@Snape
Welches Object meinst Du mit myReference? (myReference.addMyListener(this);)
Hat jede Klasse die listener hat und auch alle Klassen die Listener sind einen Verweis auf das DataClass Object? Willst Du das als Singleton implementieren?
Also so eine Art Kettenglied das alle Klassen zusammenpackt und denen sagt das sich was verändert hat aber keine neuen Objekte erzeugen, wie beim Event feuern?

@Thomas
Leider kann ich keine Events benutzen, die es schon gibt, da ich mir die Logik von dem ganzen Ding selber stricken muss.
Die Events wollte ich benutzen damit ich Logik von Darstellung trennen kann, eigentlich laufen die Überläufe in einem Feld ab, also man setzt einen Stein und dann ist irgendwann dass Feld voll und läuft über, aber da gibt es halt nichts was man so schon benutzen könnte (denke ich jedenfalls...).

Nochmal vielen Dank für die Anregung!
Ich denke den Ansatz von Snape kann ich auch gebrauchen, habe diesen aber offen gestanden noch nicht so richtig verstanden, glaube ich zumindest.
1.)Alle bekommen das Object der Kontroll-Klasse als Referenz beim erzeugen mit?
2) Wenn das Event auftritt ruft man die Funktion notifyall() vom dem Kontroll-Klassen Objekt auf. Wo wird die Referenz auf den Auslöser mitgegeben?
Ich muss ja den Überlauf zurückverfolgen können.

Schönes Wochenende! :D
 
>@Snape
>Welches Object meinst Du mit myReference? (myReference.addMyListener(this);)

myReference ist eine Referenz auf ein Objekt der DataClass.

>Hat jede Klasse die listener hat und auch alle Klassen die Listener sind einen Verweis auf das DataClass Object? Willst Du das als Singleton implementieren?

Singleton ist vermutlich datenkonsistenter.

>Also so eine Art Kettenglied das alle Klassen zusammenpackt und denen sagt das sich was verändert hat aber keine neuen Objekte erzeugen, wie beim Event feuern?

Genau. Die Listener werden ja in der DataClass in einer Liste gespeichert.

>Nochmal vielen Dank für die Anregung!
>Ich denke den Ansatz von Snape kann ich auch gebrauchen, habe diesen aber offen gestanden noch nicht so richtig verstanden, glaube ich zumindest.
>1.)Alle bekommen das Object der Kontroll-Klasse als Referenz beim erzeugen mit?

Wäre eine Möglichkeit.

>2) Wenn das Event auftritt ruft man die Funktion notifyall() vom dem Kontroll-Klassen Objekt auf. Wo wird die Referenz auf den Auslöser mitgegeben?
>Ich muss ja den Überlauf zurückverfolgen können.

In der Interface-Methode. Also in meinem Beispiel als Übergabeparameter in der Funktion reactOnNotification(EventObject o).
 
Zurück