Ereignisse werden mit Listenern überwacht und ausgeführt. Unnötig zu sagen, dass das Thema wichtig ist. In AS3 kann man eine Aktion nicht mehr direkt einer Schaltfläche oder einem MC zuweisen, indem man ihn anklickt und dann im Aktionenfenster die Aktion einträgt. Auch die alten Events wurden durch Event.Listener ersetzt. Dieses Thema in den
Im folgenden SWF Beispiel werden die wichtigsten Eigenschaften und Funktionen des Event Handlings erklärt. Hier kann man direkt einige Parameter ausprobieren
Ein einfaches Beispiel mit einem MouseEvent, wie es im vorigen SWF Beispiel erläutert wurde.
Mit der Eigenschaft currentTarget
wird das Ojekt angesprochen auf den der EventListener registriert ist. So hat man die Möglichkeit eine Funktion für mehrere Objekte gezielt zu nutzen.
Man kann Movieclips eine interne Variable zuweisen. So kann man innerhalb der Event Funktion gezielt darauf zugreifen. Das Prinzip kann man auf viele Arten einsetzen. Menüpunkte, die jeweils einen bestimmten Frame aufrufen. Oder Menüpunkte die eine zugewiesene swf Datei laden etc.
MouseEvents bieten die Möglichkeit abzufragen welche Taste gedrückt wurde. Innerhalb der Event Funktion, kann man dann gezielt darauf reagieren.
Wenn man Movieclips oder DisplayObjekte ineinander verschachtelt, entsteht eine Hierachie.
Mittels evt.target greift man auf das Objekt in der Hierachie zu, welches direkt unter der Maus liegt
Auf der Bühne liegt ein Movieclip. Der Instanzname ist haende_mc. Darauf ist der Event Listener registriert.
haende_mc.addEventListener(MouseEvent.CLICK, onMouseClick);
In dem Movieclip liegen 3 Movieclipinstanzen, jeweils von einer Hand
Diese Instanzen werden über target. angesprochen.
In der linken Hand liegen weitere Movieclips, nämlich die einzelnen Finger
Wenn man auf einen Finger klickt wird er gedreht,
wenn man auf die Handfläche klickt, wird sie gedreht.
Einen Event Listener kann man entfernen. Vergleiche beide Zeilen.
hand.addEventListener(Event.ENTER_FRAME, bewege);
hand.removeEventListener(Event.ENTER_FRAME, bewege);
siehe auch added to Stage / removed from Stage
Will man eine Event Funktion auch ohne den eigentlichen Event aufrufen,
wie hier die Funktion startMove(), so weist man dem event Parameter
den Wert null zu.
function startMove(evt:MouseEvent=null){.....}
Die Funktion startMove() wird einmal mittels Event Listener aufgerufen
hand.addEventListener(MouseEvent.CLICK, startMove);
und weiter unten ohne EventListener
startMove();
Ich benutze in diesem Tipp die Bezeichnungen Abkömmling oder Nachfahre, sowie den Begriff Vorfahre. Damit sind Objekte in der Displaylistenhierachie gemeint. Ein Abkömmling ist ein child Objekt und ein Vorfahre bezieht sich auf parent Objekte. In beiden Fällen müssen das nicht die direkten Kinder oder Eltern sein.
Man hat in AS3 auch ein Doppelklick Ereignis: MouseEvent.DOUBLE_CLICK
Das funktioniert nur wenn man die Eigentschaft doubleClickEnabled auf true setzt.
my_mc.doubleClickEnabled=true;
my_mc.addEventListener(MouseEvent.DOUBLE_CLICK, doppelklick);
function doppelklick(evt:MouseEvent):void
{
trace("hallo");
}
Ereignisse mit Tastatursteuerung in meinem Tipp "programmierte Bewegung"
In Event Handlern haben wir keine Funktionsaufrufe, sondern Referenzen auf Funktionen. Ein Funktionsaufruf hat immer die beiden Klammern hinter dem Bezeichner. myFunction() Bei einer Referenz wird nur der Bezeichner der Funktion angegeben. Dadurch hat man auch nicht die Mögichkeit irgendwelche Parameterwerte einzufügen.
Es gibt jedoch auch die Möglichkeit anstatt einer Referenz eine anonyme Funktion zu definieren. Eine anonyme Funktion hat keinen Bezeichner.
function (){Anweisung;}
Beachte dass hier anstatt der Funktionsreferenz eine anonyme Funktion notiert ist.
b1.addEventListener(MouseEvent.CLICK, function(){trace("Hallo")});
Im EventListener des ersten Buttons ist so eine anonyme Funktion notiert.
b1_btn.addEventListener(MouseEvent.CLICK, function () { info.text = "Dieses ist der erste Button"; })
Der zweite Button ruft in der anonymen Funktion eine Funktion auf welche einen Parameter hat.
b2_btn.addEventListener(MouseEvent.CLICK, function () { infoText("Ich bin der zweite Button."); }) function infoText(a: String): void { info.text = a; }
Im dritten Button haben wir einen Funktionsaufruf mit Klammern. Wie geht das denn?
Das geht nur deswegen, weil es eine callback Funktion ist.
In der Callback Funktion getFunction() ist der Rückgabewert eine Funktion. So eine
Funktion kann man auch in einem EventListener aufrufen. So etwas nennt man eine Callback Funktion
b3_btn.addEventListener(MouseEvent.CLICK, getFunction("Hier kommt Button 3.")); function infoText(a: String): void { info.text = a; } function getFunction(b: String) { return function () { infoText(b); } }
Event Dispatcher (dispatcher: Sender /Depeche). Ein Event Dispatcher braucht man, wenn man in einer eigens erstellten Klasse einen eigens erstellten Event braucht, den man der Instanz der Klasse anhängen kann. Schauen wir uns dazu mal eine der UI Komponenten an. Wenn ich beispielsweise eine Funktion definiere, die auf dem onChange Ereignis einer Combobox ausgeführt wird, benutze ich dazu, das zur Verfügung gestellte onChange Ereignis der Combobox.
Versuche mal selber so etwas mit einer erweiterten Movieclipklasse in der dazugehörigen Klassendatei nachzubauen, dann kommst du an den Punkt, wo du einen Event Dispatcher brauchst. Innerhalb der Klasse möchtest du Ereignisse definieren, denen du von außen eine Funktion zu weisen willst. Von außen heißt in diesem Falle in der Umgebung, wo die Instanz der Klasse eingefügt wurde. Dazu nun 2 Beispiele zuerst ein ganz einfaches Beispiel und weiter unten das Beispiel genannt TextfeldMessage:
Im folgenden ein ganz einfaches Beispiel. Hier ist alles auf das Wesentliche beschränkt.
dispatchEvent(new Event(EXP_CLICK));
In dem Parameter newEvent()
wird die anfangs erstellte Konstante übergeben.kreis.addEventListener(EvtDispExpl.EXP_CLICK, showMessage);
Die Actions der Klasse
package { import flash.display.Sprite; import flash.events.*; public class EvtDispExpl extends Sprite { //Konstante public static const EXP_CLICK:String = "EvtDispExplEvent_EXP_CLICK"; public var someVar:String; public function EvtDispExpl(_someVar:String) { someVar = _someVar; this.graphics.beginFill(0x5500ff); this.graphics.drawCircle(0,0, 50); addEventListener(MouseEvent.CLICK, someClick); } public function someClick(evt:MouseEvent):void { //EventDispatch dispatchEvent(new Event(EXP_CLICK)); } } }
Die Actions in der fla
var kreis:EvtDispExpl = new EvtDispExpl("the message"); addChild(kreis); kreis.addEventListener(EvtDispExpl.EXP_CLICK, showMessage); function showMessage(evt:Event):void { trace(kreis.someVar); }
package { import flash.display.MovieClip; import flash.display.DisplayObject; import flash.events.*; import flash.text.Font; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFieldAutoSize; import flash.text.AntiAliasType; import flash.text.TextFormatAlign; public class TextfeldMessage extends MovieClip { //----------------------------------------------------------- // TextfeldMessage-Ereigniss // public static const LISTITEM_CLICK:String="TextfeldMessageEvent_LISTITEM_CLICK"; //------------------------------------------------------------------------ //Variablen //Der ausgewählte TextString protected var selectedTextfieldText:String; //-------------------------------------------------------------------------- //Konstruktor public function TextfeldMessage() { //Textfeld mit Text wird erzeugt und der Displayliste dieses Objekts hinzugefügt var lblText:TextField = new TextField(); lblText.text="die Message"; lblText.mouseEnabled=true; lblText.width=225; lblText.height=26; lblText.selectable=false; lblText.addEventListener(MouseEvent.CLICK, ListItemClick); addChild(lblText); } //Konstruktor Ende //----------------------------------------------------------- //getter Funktion ausgewählten Textstring zurückgeben public function get TextString():String { return selectedTextfieldText; } // Klick auf das Listen-Ereignis public function ListItemClick(evt:MouseEvent):void { selectedTextfieldText=evt.currentTarget.text; dispatchEvent(new Event(LISTITEM_CLICK)); } } }
Es folgt die Dokumentenklasse der fla in der das TextfeldMessage Objekt instanziiert ist.
package { import flash.display.MovieClip; import flash.events.Event; public class dispatchEventExample extends flash.display.MovieClip { //Konstruktor public function dispatchEventExample():void { //TextfeldMessage Instanz wird erzeugt und auf die Bühne gebracht var textMessageInstanz:TextfeldMessage = new TextfeldMessage(); addChild(textMessageInstanz); textMessageInstanz.x=20; textMessageInstanz.y=10; //der Instanz wird ein Event Listener hinzugefügt textMessageInstanz.addEventListener(TextfeldMessage.LISTITEM_CLICK, showText); function showText(evt:Event):void { trace(textMessageInstanz.TextString); anzeige.text=textMessageInstanz.TextString; } } //Ende Konstruktor } }
Events die man auf Display Objekte registrieren kann, können Event Phasen haben. Das bezeichnet man als Event Flow.
Die folgenden 4 Event Typen haben nur eine target-Phase
Alle anderen Event Dispatches, die an ein Objekt in der Displaylistenhierachie gehängt sind, haben eine capture Phase und eine target Phase. Einige haben auch eine bubbling Phase. In den Referencen kann man nachschauen, ob der Event eine bubbling Phase hat oder man überprüft die Eigenschaft bubbles per Actionscript.
...
if(evt.bubbles)trace("der Event besitzt die Bubbling Phase");
...
Hier ein weiteres Beispiel in dem Phasen überprüft werden.
Die Reihenfolge der Phasen läuft folgendermaßen. Es beginnt oben auf der stage Ebene, durchläuft dann die Displaylistenhierachie bis zum Target und dann den Weg wieder zurück bis zur stage Ebene.
In folgendem Beispiel haben wir ein Sprite auf der Bühne. Im Sprite befindet sich ein Texteingabefeld.
Es werden also alle Vorfahren des Ziels benachrichtigt, dann in der Target Phase das Ziel und dann werden, in der Hierachieebene zurück, alle Vorfahren davon benachrichtigt, dass die Funktion ausgeführt wurde.
Im folgenden Beispiel, welches der vorigen Beispielgrafik entspricht, erfolgt der Trace Befehl nachdem eine Texteingabe gemacht wird, also in der Bubbling Phase
import flash.display.Sprite; import flash.text.TextField; import flash.events.TextEvent; var tS:Sprite = new Sprite(); var tT:TextField = new TextField(); tT.text ="Eingabe hier"; tT.autoSize = TextFieldAutoSize.LEFT; tT.type = TextFieldType.INPUT; tS.addChild(tT); addChild(tS); function textInputListener(e:TextEvent):void{ trace("Texteingabe durch User"); } tS.addEventListener(TextEvent.TEXT_INPUT, textInputListener);
Möchte man, dass der Vorfahre schon während der Capture Phase registriert wird, muss man den dritten Parameter (useCapture) von addEventListener auf true setzen. Standardmäßig ist der Wert false.
tS.addEventListener(TextEvent.TEXT_INPUT, textInputListener, true);
Da die Funktion ausgeführt wird, bevor der Bildschirm aktualisiert wird, zeichnet sich hier schon eine Einsatzmöglichkeit ab. So könnte man beispielsweise ein Eingabefeld auf aktiviert oder deaktiviert überprüfen und eine Eingabe verhindern.
Wenn man einen Event Listener entfernt, müssen alle Parameter bei add und remove übereinstimmen.
tS.addEventListener(TextEvent.TEXT_INPUT, textInputListener, true);
tS.removeEventListener(TextEvent.TEXT_INPUT, textInputListener, true);
Will man einen Vorfahre auf Capture und Bubbling Phase registrieren muss man ihn 2 mal registrieren. Einmal mit useCaputre= true und einmal mit useCapture = false. Im letzteren Fall kann man sich das Setzen des Parameters sparen, da der Standardwert auf false voreingestellt ist.
tS.addEventListener(TextEvent.TEXT_INPUT, textInputListener, true);
tS.addEventListener(TextEvent.TEXT_INPUT, textInputListener);