How do I properly extend a custom JavaFX component to add or modify its GUI components if it uses FXML for the view?
As an example scenario, suppose I use the following approach of creating a custom JavaFX component:
SpecializedButton.java (Controller)
package test;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
public class SpecializedButton extends HBox
{
@FXML private Button button;
@FXML private Label label;
public SpecializedButton()
{
FXMLLoader loader = new FXMLLoader( getClass().getResource( "SpecializedButton.fxml" ) );
loader.setRoot( this );
loader.setController( this );
try {
loader.load();
} catch ( IOException e ) {
throw new RuntimeException( e );
}
}
// specialized methods for this specialized button
// ...
public void doSomething() {
button.setText( "Did something!" );
}
}
SpecializedButton.fxml (View)
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>
<fx:root type="HBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane HBox.hgrow="ALWAYS">
<children>
<Label fx:id="label" text="Click to do something: " AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane HBox.hgrow="ALWAYS">
<children>
<Button fx:id="button" onAction="#doSomething" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</children>
</fx:root>
MyApp.java
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MyApp extends Application
{
public static void main( String[] args )
{
launch( args );
}
public void start( Stage stage ) throws Exception
{
stage.setScene( new Scene( new SpecializedButton(), 300, 50 ) );
stage.show();
}
}
The SpecializedButton class loads the FXML view (SpecializedButton.fxml) and acts as the controller for it.
The SpecializedButton FXML view just creates an HBox with two AnchorPanes and a Label and Button in the left and right sides, respectively. When the button is clicked, it calls doSomething() in the SpecializedButton controller class.
Problem
With this setup, I am using FXML to separate the view from the application logic.
However, if I want to create a new HighlySpecializedButton class that extends SpecializedButton, I don't know how to go about "extending" the view as well.
If I wanted to use the SpecializedButton view, but modify it for the HighlySpecializedButton, I'd have to copy the view code into a new FXML file, resulting in duplicate code instead of proper inheritance.
If I wasn't using FXML, and was creating the GUI components within a Java class instead, extending that class would give me the ability to properly inherit and add/modify the components from the super class.
I am clearly misunderstanding some very important concepts about JavaFX.
Question
Are FXML views in this case so "dumb" that I'd have to create an entirely new FXML view every time I wanted to inherit from a custom component?
Or, if I am misunderstanding the real issue, what is the proper way of creating extendable custom JavaFX components, with or without FXML?
I'd greatly appreciate any insight. Thanks in advance!