Den Szene-Graph über Java Programmcode aufzubauen ist eine Möglichkeit, doch JavaFX erlaubt es auch, die Objekte über XML zu konfigurieren. Das erlaubt es viel einfacher, grafische Oberflächen über Gui-Builder aufzubauen und sauber das Layout (was) vom Code (wie) zu trennen.
Die hierarchische Struktur von XML passt natürlich prima zu der Hierarchie, die es bei grafischen Oberflächen gibt: Ein Fenster enthält Container, die wiederum Elemente enthalten, usw. Für unser kleines Beispiel soll eine Oberfläche drei Elemente bieten: Eine Beschriftung, ein Textfeld und eine Schaltfläche. Drückt der Anwender die Schaltfläche, soll der Text im Textfeld in Großbuchstaben konvertiert werden.
Die XML-Datei covert2UpperCase.fxml sieht so aus:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.*?> <?import javafx.scene.control.*?> <HBox xmlns:fx="http://javafx.com/fxml" fx:controller="com.tutego.insel.javafx.ButtonController"> <children> <Label text="Eingabe: " /> <TextField fx:id="input" /> <Button text="Konvertiere" onAction="#convertAction" /> </children> </HBox>
Die Hierarchie ist gut zu erkennen. Die interessanten Dinge sind andere:
- Zu Beginn gibt es eine Art import-Anweisung um Typnamen nicht voll qualifizieren zu müssen. Für den Rückgriff auf Grafiken muss <?import javafx.scene.image.*?> eingebunden werden und <?import javafx.scene.*?> für Group, Node oder ähnliches, was wir im Programm aber alles nicht nutzen.
- HBox hat zwei Attribute: Ein Attribut deklariert den Namensraum fx, ein anderes eine Klasse, den sogenannten Controller, der später die Ereignisbehandlung für den Klick übernimmt. Die Typen in FXML heißen genauso wie die Klassennamen. Natürlich könne auch eigene Klassen eingebaut werden, sofern sie mit <?import> bekannt gemacht wurden.
- Das TextField bekommt mit dem Attribut fx:id eine ID zugewiesen, unter der das Textfeld später erfragt werden kann. JavaFX geht noch einen Schritt weiter, und bildet das Objekt mit der ID automatisch auf ein Attribut der Controller-Klasse ab. Label und Schaltfläche brauchen keine IDs, da sie nicht erfragt werden müssen.
- Das Attribut onAction der Schaltfläche referenziert Programmcode, der immer aufgerufen wird, wenn die Schaltfläche gedrückt wird. Hier kann direkt Java-Quellcode stehen, oder, wie in unserem Fall, ein # und der Name einer Methode, die in einem Controller deklariert werden muss. Den Klassenamen vom Controller haben wir am Wurzelelement deklariert.
Die Ereignisbehandlung ist komplett aus der FXML-Datei rausgezogen und wandert in Controller-Klassen. Die eigene Klasse ButtonController, die voll qualifiziert bei fx:controller genannt wurde, enthält:
com/tutego/insel/javafx/ButtonController.java
package com.tutego.insel.javafx; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.TextField; public class ButtonController { @FXML private TextField input; @FXML protected void convertAction( ActionEvent event ) { input.setText( input.getText().trim().toUpperCase() ); } }
Drei Dinge fallen ins Auge:
- Die Controller-Klasse erweitert keine Schnittstelle.
- Die Annotation @FXML sagt, dass der Verweis auf das TextField-Objekt aus dem Szene-Graphen in die Variable input injiziert werden soll.
- Da in der FXML-Datei an der Schaltfläche ein onAction="#convertAction" steht, muss das zu einer Methode zugeordnet werden. Die Annotation @FXML an der Methode unter dem Namen convertAction stellt diese Beziehung her.
Das Hauptprogramm ist nun relativ einfach:
com/tutego/insel/javafx/FXMLDemo.java, start()
@Override public void start( Stage stage ) throws Exception { Parent p = FXMLLoader.load( getClass().getResource( "covert2UpperCase.fxml" ) ); stage.setScene( new Scene( new Group( p ), 500, 400 ) ); stage.setVisible( true ); }
Was noch alles mit FXML möglich ist, beschreibt ein Dokument von Oracle: http://fxexperience.com/wp-content/uploads/2011/08/Introducing-FXML.pdf.
Sehr interessant sieht ja schon fast so aus wie XAML von Microsoft 😉
Ein bisschen spät aber danke für den Schnelleinstieg.
Ich habe mir NB 7.1 installiert nebst neuem JDK und JAVAFX DK und bin überhaupt nicht überzeugt:
– statt schöner deklarativer Sprache (f3, V 1.0) dieses furchtbare XML
– immer noch kein grafischer Designer – nach fast 5 Jahren!
So wird das nie was. Also Oracle: nochmal von vorne anfangen und es kommt 2013 das völlig neue und zu allen Vorgängern inkompatible Java FX 3.0