Search code examples
javafxfxml

How to run a code block after the view loads


When using an fxml file and controller, it is possible to have an initialize method, which runs before the view loads. Similarly, is there a way to run a block of code after the view loads?
To be more specific, I have a Rectangle in the fxml file. I want to call the Rectangle's setFill() , method, from the controller, after the view loads and pass a LinearGradient instance. LinearGradient has properties without setters and doesn't have a parameterless constructor, so I don't think the fill property can be assigned in the fxml file.
I tried putting this code in the constructor of the controller but that results in an error. If possible, I would also like to know what procedure takes place with regards to the controller class when FXMLLoader loads an fxml file (when is a constructor called).

Please take a look at this sample code if necessary:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.shape.Rectangle?>

<Pane fx:controller="sample.RectController" xmlns:fx="http://javafx.com/fxml">
    <Rectangle fx:id="rect" height="200.0" width="200.0" />
</Pane>
package sample;
import javafx.fxml.FXML;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;

public class RectController{
    @FXML Rectangle rect;
    {
        //code i would like to run but currently results in an error
        rect.setFill(new LinearGradient(
            0, 0.5, 1, 0.5, true, CycleMethod.NO_CYCLE, 
                new Stop(0, Color.BLUE),
                new Stop(1, Color.RED)
        ));
    }
}

Solution

  • You want your controller to implement a no-arg initialize() method annotated with @FXML (The old way was to implement javafx.fxml.Initializable but as you can see from the docs for that method, you don't need the interface anymore.)

    You can't do it in the controller's constructor because the fields haven't been injected yet by the FXMLLoader.