JavaFX Interaction Events Eventhandler Lambda-Ausdrücke Einfache Interaktion (c) schmiedecke 15 Prg-20-Interaktion 2 Interaktion • Jedem Control kann Interaktivität hinzugefügt werden • Die GUI erkennt verschiedenste Interaktions-Ereignisse – – – – – – – Mausklick Mausbewegung, Dragbewegung linke, rechte Maustaste Taste gedrückt, losgelassen Entertaste Selektion ... • Für jedes Ereignis wird ein von der GUI ein Event-Objekt erzeugt, das die erforderlichen Infos enthält (z.B. "worauf geklickt?") • Den Controls können durch "SetOn..."-Methoden Event-Handler hinzugefügt werden. • Wir beginnen mit "ActionEvents", wie z.B. Knopfdruck und Enter • Die anderen Events kommen später... (c) schmiedecke 15 Prg-20-Interaktion 3 Aktion des Login-Knopfes (c) schmiedecke 15 Prg-20-Interaktion 4 EventHandler des Login-Knopfes • LoginHandler ist innere Klasse (in Main05) • Zweck: Controls (btn und userTextField) sollen bekannt sein • Beide dürfen aber nicht lokal in start() sein, sondern müssen Attribute werden: (c) schmiedecke 15 Prg-20-Interaktion 5 Die Theorie dahinter: Events • Ein Event ist ein Objekt vom Typ Event, in der Regel einer Unterklasse von javafx.event.Event • Es wird vom FX-Laufzeitsystem für jede Benutzeraktion erstellt. • Ein Event-Objekt ist ein "Informationspaket" über ein Ereignis, enthält mindestens getType, getSource, getTarget • Es gibt eine Hierarchie von Event-Typen (c) schmiedecke 15 Prg-20-Interaktion 6 EventHandler • Ein EventHandler ist eine Implementierung des Interfaces public interface EventHandler<T extends Event> extends EventListener { void handle(T event); } • Es gibt nur die eine Methode handle, der ein Event als Parameter übergeben wird (das "Infopaket"). • Ein Eventhandler wird bei einem Node "registriert" und dadurch bei Auftreten eines Ereignisses aufgerufen. myButton.addEventHandler(ActionEvent.ACTION, myButtonHandler); adressierter EventType Instanz von Button (c) schmiedecke 15 Instanz von EventHandler<ActionEvent> Prg-20-Interaktion 7 Beispielcode Login Handler muss "innere Klasse" sein, damit Zugriff auf btn userTextField und loginmessage besteht (c) schmiedecke 15 Prg-20-Interaktion 8 Kombination von Events und Handlers Praxistür Gong Haustür Tueroeffner oben Tueroeffner unten Kombination von Events und Handlers public DocsPraxis() { Button hausklingel = new Button("Dr.Java"); Button praxisklingel = new Button("Dr.Java"); EventHandler<ActionEvent> gong = new Gong(); EventHandler<ActionEvent> praxistueroeffner = new Tueroeffner("oben"); EventHandler<ActionEvent> haustuer = new Tueroeffner("unten"); hausklingel.addActionListener(gong); hausklingel.addActionListener(haustueroeffner); praxisklingel.addActionListener(gong); praxisklingel.addActionListener(praxistueroeffner); pane.getChildren().add(praxisklingel); pane.getChildren().add(hausklingel); } Die wichtigsten Eventklassen • javafx.event.ActionEvent häufigstes Event Knopfdruck, Doppelklick, Enter • javafx.scene.input.InputEvent Maus- oder Tastenklick • javafx.scene.input.KeyEvent Tastenereignisse: (extends InputEvent) • javafx.scene.input.MouseEvent Drücken, Lösen, Klicken.... Mausereignisse (extends InputEvent) Bewegen, Drag, Maustasten... • javafx.scene.TouchEvent Toucheingaben • javafx.scene.WindowEvent Änderung des Stage-Zustands Maximieren, Minimieren, Resize... (c) schmiedecke 15 Prg-20-Interaktion 11 Vereinfachte Event-Registrierung • "setOn...." • vereinfachte Registrierung für häufige Event-Typen • Beispiel: Grüner Punkt soll bei Mausklick rot werden (c) schmiedecke 15 Prg-20-Interaktion 12 Übersicht Vereinfachte Registrierung http://docs.oracle.com/javafx/2/events/convenience_methods.htm (c) schmiedecke 15 Prg-20-Interaktion 13 (c) schmiedecke 15 Prg-20-Interaktion 14 Allgemeine Form der Registrierung: setOnEvent-type(eventHandler); statt vereinfacht (c) schmiedecke 15 Prg-20-Interaktion 15 Events auf Nodes • • • • Der Scene Graph enthält Nodes Events können auf Nodes registriert werden Shapes sind Nodes d.h. aus jedem "Shape" kann ein Control werden (c) schmiedecke 15 Quelle Rheinjug / Saxonia Systems / http://youtu.be/hYW4TRoFgXA Prg-19-Panes und Controls 16 Ein Shape als Knopf (c) schmiedecke 15 Prg-20-Interaktion 17 Projekt Scribble – Malen mit der Maus Scribble-Idee: • Group als Root • Rectangle als Untergrund • Darauf Lines: – Starten, wenn Mausknopf gedrückt (kleiner Kreis) – Bei jedem MouseDragged-Event kleines Stück Linie erzeugen (Line-Objekt) und hinzufügen – Wenn Mausknopf gelöst, endet die Linie (kleiner Kreis) (c) schmiedecke 15 Prg-20-Interaktion 18 Project Scribble (c) schmiedecke 15 Prg-20-Interaktion 19 Project Scribble (c) schmiedecke 15 Prg-20-Interaktion 20 Anonyme innere Klasse • Viel unnötiger Code: Der Klassenname wird nur 1x benötigt! • Deshalb üblicherweise anonyme innere Klasse: Deklaration und Instanziierung in einem Schritt Brrrr - hässlich, aber üblich! (c) schmiedecke 15 Prg-20-Interaktion 21 Die elegante Lambda-Lösung • Dies ist ein Überfall Vorgriff - Theorie folgt später • Ein Lambda-Ausdruck ist eine namenlose Methode (also etwas Anonymes), die (als Objekt) weitergegeben werden kann • (Heißt in Skriptsprachen Closure) • Syntax in Java 8: Parameterliste -- Pfeil -- Methodenrumpf (MouseEvent event) -> public void handle(MouseEvent event) { x=event.getX(); y=event.getY(); root.getChildren().add(new Circle(x,y,3,Color.BLUE)); } Als Methode nicht weitergebbar – müsste noch in eine Klasse gekapselt werden. Lambda-Ausdrücke haben so eine (unsichtbare) Kapsel (c) schmiedecke 15 Prg-20-Interaktion 22 Lambda statt anonym (c) schmiedecke 15 Prg-20-Interaktion 23 Guter Stil: private Methode Keine innere Klasse mehr, nur noch eine private Methode (c) schmiedecke 15 Prg-20-Interaktion 24 Lambda für Scribble (c) schmiedecke 15 Prg-20-Interaktion 25 Noch Lust auf eine ComboBox? • in "handle" sichtbar setzen... (c) schmiedecke 15 Prg-20-Interaktion 26 Das gibt Ihnen schon ganz viele Möglichkeiten Was fehlt? Dynamische Werte durch Properties Navigation und Message Panes