FXML Markup Inheritance in JavaFX

JavaFX makes it possible to define components either by code or in the FXML markup. Typically, one would like to be able to extend components created in this way. This short tutorial shows how to extend components defined with FXML. For the other case, please refer to the code in e.x. javafx.scene.layout.Pane.

A basic, extensible component, has to define a node where a derived component can be added to. Let's explore how this works in detail with an example Button component:

BasicButton.fxml

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

Corresponding java class BasicButton.java:

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

	public ObservableList<Node> getExtension() {
        return extension.getChildren();
	}
	// ... more component related code
}

The most important part here is the HBox fx:id="extension" which will serve as an extension point in the BasicButton component.

In the BasicButton java class, the extension point has to be introduced with the @DefaultProperty("extension") annotation (fx:id extension corresponds with the value for the annotation) and also the getter for the property has to be defined (ObservableList<Node> getExtension()).

Now the BasicButton can be extended in a regular java manner:

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>

and SpecializedButton.java:

public class SpecializedButton extends BasicButton {
	public SpecializedButton() {
		// load SpecializedButton.fxml
	}
	// ... more component related code
}

Resources: Complete project with sample code on github