Mastering FXML

Previous
Next

3 FXML—What's New in JavaFX 2.2

This page contains a list of FXML enhancements added in JavaFX 2.2.

  • <fx:constant> tag

    The <fx:constant> tag has been added to FXML to facilitate lookup of class constants. For example, the NEGATIVE_INFINITY constant defined by the java.lang.Double class can now be referenced as follows:

    <Double fx:constant="NEGATIVE_INFINITY"/>
    
  • Improved access to sub-controllers in FXML

    In JavaFX 2.1 and earlier, it was not easy to access subcontrollers from a root controller class. This made it difficult to use a controller to open and populate a dialog window whose contents were defined in an include statement, for example.

    JavaFX 2.2 maps nested controller instances directly to member fields in the including document's controller, making it much easier to interact with nested controllers. Consider the following FXML document and controller:

    <VBox fx:controller="com.foo.MainController"> 
    ...
        <fx:include fx:id="dialog" source="dialog.fxml"/>
    ...
    </VBox>
    
    public class MainController extends Controller { 
        @FXML private Window dialog;
        @FXML private DialogController dialogController;
    
        ...
    }
    

    When the controller's initialize() method is called, the dialog field will contain the root element loaded from the dialog.fxml file, and the dialogController object will contain the include statement's controller. The main controller can then invoke methods on the include statement's controller, to populate and show the dialog, for example.

  • Support for controller initialization via reflection

    In JavaFX 2.1 and earlier, controller classes were required to implement the Initializable interface to be notified when the contents of the associated FXML document had been completely loaded. In JavaFX 2.2, this is no longer necessary. An instance of the FXMLLoader class simply looks for the initialize() method on the controller and calls it, if available. Note that, similar to other FXML callback methods such as event handlers, this method must be annotated with the @FXML annotation if it is not public.

    It is recommended that developers use this approach for new development. The Initializable interface has not been deprecated, but might be in a future release.

  • Simplified creation of FXML-based custom controls

    In previous releases, it was fairly cumbersome to create custom controls whose internal structure was defined in FXML. JavaFX 2.2 includes some subtle but powerful enhancements that significantly simplify this process. The new setRoot() and setController() methods enable the calling code to inject document root and controller values, respectively, into the document namespace, rather than delegate creation of these objects to FXMLLoader. This enables a developer to create reusable controls that are internally implemented using markup, but (from an API perspective) appear identical to controls implemented programmatically.

    For example, the following code markup defines 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:

    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <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>
    

    The <fx:root> tag, which was added for JavaFX 2.2, specifies that the element's value will be obtained by calling the getRoot() method of the FXMLLoader class. Prior to calling the load()method, the calling code must specify this value by calling the setRoot() method. The calling code can also provide a value for the document's controller by calling the setController() method.

    For more information, see Creating a Custom Control with FXML.

Previous
Next