devoured elysium
devoured elysium

Reputation: 105067

FXML declared custom control can't access declared fields at initialization time

I'm developing a control using JavaFX / FXML that can then be used like this:

<MyControl myNumber="123" />

The control is supposed to use myNumber when first shown to the user.

The problem seems to be that nowhere at startup do I seem to have access to the updated value of 123. I don't have it when running the constructor (expectable) but I also don't have it when running the Control's initialize() method.

Here's the code with some debugging statements:

public class MyControl extends VBox implements Initializable {
    @FXML int myNumber = -1;

    public int getMyNumber() { return myNumber; }

    public void setMyNumber(int myNumber) {
        System.out.println("setMyNumber");
        this.myNumber = myNumber;
    }

    public MyControl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myControl.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }

        System.out.println("constructor = " + myNumber);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println("initializable = " + myNumber);
    }
}

printing

initializable = -1
constructor = -1
setMyNumber

How to solve this situation?

Upvotes: 0

Views: 69

Answers (1)

Pagbo
Pagbo

Reputation: 690

If you want to use this attribute in the FXML you should declare a constructor with the @NamedArg annotation.

In your case this will be something like the following example :

public MyControl(@NamedArg("myNumber") int pMyNumber) {
    myNumber = pMyNumber;
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myControl.fxml"));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);

    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }
    System.out.println("constructor = " + myNumber);
}

Upvotes: 1

Related Questions