Documentation



JavaFX: Mastering FXML

4 Creating a Custom Control with FXML

In this tutorial, you create an application with a custom control that consists of a text field and a button, as shown in Figure 4-1.

Before you start, ensure that the version of NetBeans IDE that you are using supports JavaFX 8. (NetBeans IDE 7.4 with patch 2 is the earliest version that meets that criteria.) It is assumed that you are familiar with the basic structure of an FXML project (.java, .fxml, and controller files). If you are not familiar with it, then first complete the FXML tutorial in the Getting Started series and then continue with this tutorial.

Figure 4-1 Custom Control Application

Description of Figure 4-1 follows
Description of "Figure 4-1 Custom Control Application"

Set Up a Project

Open your NetBeans IDE and perform the following steps to set up a JavaFX FXML project:

  1. From the File menu, choose New Project.

  2. In the JavaFX category, choose JavaFX FXML Application. Click Next.

  3. Name the project CustomControlExample and click Finish.

  4. Rename FXMLDocumentController.java to CustomControl.java so that the name is more meaningful for this application.

    1. In the Projects window, right-click SampleController.java and choose Refactor then Rename.

    2. Enter CustomControl, and then click Refactor.

  5. Rename FXMLDocument.fxml to custom_control.fxml

    1. Right-click FXMLDocument.fxml and choose Rename.

    2. Enter custom_control and click OK.

Create the Basic User Interface

Define the structure of a simple custom control containing a TextField and a Button instance. The root container is defined as an instance of the javafx.scene.layout.VBox class.

  1. Edit the custom_control.fxml file.

  2. Delete the <AnchorPane> markup that NetBeans IDE automatically generated.

  3. Add code for the root container as shown in Example 4-1.

    Example 4-1 Defining the Root Container

    <fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml">
        <TextField fx:id="textField"/>
        <Button text="Click Me" onAction="#doSomething"/>
    </fx:root>
    
  4. Remove unused import statements, as shown in Example 4-2.

    Example 4-2 Unused Import Statements

    <?import java.lang.*?>
    <?import java.util.*?>
    

Create a Controller

In this example, the CustomControl class extends the VBox class (the type declared by the <fx:root> element), and sets itself as both the root and controller of the FXML document in its constructor. When the document is loaded, the contents of the CustomControl instance will be populated with the contents of the document.

  1. Open the CustomControl.java file and remove the code that NetBeans IDE automatically generated.

  2. Add code as shown in Example 4-3.

    Example 4-3 The CustomControl Class as Both the Root and Controller of the FXML Document

    package customcontrolexample;
    
    import java.io.IOException;
    
    import javafx.beans.property.StringProperty;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.VBox;
    
    public class CustomControl extends VBox {
        @FXML private TextField textField;
    
        public CustomControl() {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
    "custom_control.fxml"));
            fxmlLoader.setRoot(this);
            fxmlLoader.setController(this);
    
            try {
                fxmlLoader.load();
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }
        }
    
        public String getText() {
            return textProperty().get();
        }
    
        public void setText(String value) {
            textProperty().set(value);
        }
    
        public StringProperty textProperty() {
            return textField.textProperty();
        }
    
        @FXML
        protected void doSomething() {
            System.out.println("The button was clicked!");
        }
    }
    

Load the FXML Source File and Define Stage and Scene

The CustomControlExample.java file contains code for setting up the main application class. It defines the stage and scene, and loads the FXML source file. More specific to FXML, this class loads the FXML source file using the CustomControl class.

  1. Open the CustomControlExample.java file.

  2. Remove the line of code that contains a call to the FXMLLoader class as shown in Example 4-4.

    Example 4-4 Removing the Call to the FXMLLoader Class

    Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
    
  3. Create an instance of the CustomControl class and specify the text for the custom control as shown in Example 4-5.

    Example 4-5 Instantiating the CustomControl Class

    CustomControl customControl = new CustomControl();
    customControl.setText("Hello!");
    
  4. Remove the lines of code that set the stage and scene, and define the stage and scene as shown in Example 4-6.

    Example 4-6 Defining the Stage and Scene

    stage.setScene(new Scene(customControl));
    stage.setTitle("Custom Control");
    stage.setWidth(300);
    stage.setHeight(200);
    stage.show();
    
  5. Press Ctrl (or Cmd) + Shift + I to correct the import statements.

After you create a custom control, you can use instances of this control in code or in markup, just like any other control as shown in Example 4-7 and Example 4-8.

Example 4-7 Using an Instance of the CustomControl Class in Code

HBox hbox = new HBox();
CustomControl customControl = new CustomControl();
customControl.setText("Hello World!");
hbox.getChildren().add(customControl);

Example 4-8 Using an Instance of the CustomControl Class in Markup

<HBox>
    <CustomControl text="Hello World!"/>
</HBox>

Download the CustomControlExample.zip file to see the completed source code of the Custom Control application.

Close Window

Table of Contents

JavaFX: Mastering FXML

Expand | Collapse