FXML Markup Vererbung in JavaFX

Kurze Einführung in Vererbung von in FXML definierten Komponenten

JavaFX erlaubt, Komponenten entweder per Code oder in FXML zu definieren. Typischerweise möchte man auf diese Weise erstellte Komponenten mittels Java-Vererbung erweitern. Dieses Tutorial zeigt, wie das für die in FXML definierten Komponenten geht.

Die Komponente, die als Basis für die Vererbung dient, muss einen Knoten definieren, in welchen eine abgeleitete Komponente hinzugefügt werden kann. Zur Veranschaulichung definieren wir eine einfache Button-Komponente:

BasicButton.fxml

<fx:root type="javafx.scene.layout.HBox" 
	xmlns:fx="http://javafx.com/fxml/1"
	alignment="CENTER_LEFT">
	<children>
		<Button text="Button" onAction="#actionHandler" />
		<Label fx:id="label" text="Basic Button" />
		<HBox fx:id="extension" alignment="CENTER_LEFT"/>
	</children>
</fx:root>

Mit zugehöriger Java-Klasse BasicButton.java

@DefaultProperty("extension")
public class BasicButton extends HBox {
	
    private @FXML Label label;
    private @FXML HBox extension;
	
    public BasicButton() {
	    // lade BasicButton.fxml
    }

    public ObservableList<Node> getExtension() {
        return extension.getChildren();
    }

    // ...
}

Der Knoten, der in abgeleiteten Klassen als "Erweiterungspunkt" dienen soll, ist in dem FXML als als HBox mit der fx:id = "extension" eingefügt worden.

In der BasicButton-Klasse muss dieser Knoten mit der Annotation @DefaultProperty ("extension") markiert werden ("value" der Annotation ist gleich dem "fx:id"-Wert der HBox). Zusätzlich müssen getter und setter für die "extension" definiert werden ((ObservableList<Node> getExtension() { ... } , setter analog).

Jetzt kann die BasicButton-Klasse in üblicher Java-Manier erweitert werden:

SpecializedButton.fxml

<fx:root type="mrak.jfx.extendfxml.BasicButton"
	xmlns="http://javafx.com/javafx/8" 
	xmlns:fx="http://javafx.com/fxml/1">
	<Label fx:id="anotherLabel" text="Specialized Button"/>
</fx:root>

mit zugehöriger Java-Klasse: SpecializedButton.java

public class SpecializedButton extends BasicButton {
	public SpecializedButton() {
		// lade SpecializedButton.fxml
	}
}

Ressourcen

Beispiel-Projekt GitHub (https://github.com/matrak/javafx-extend-fxml)