1

This is likely pilot error, but the FXML attribute is not binding to the controller class on fx:id. I've whittled it down to a trivial example, but still "no joy". What am I overlooking?

FXML file...

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane fx:id="mainFrame" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.controller.BorderPaneCtrl">
  <left>
    <AnchorPane fx:id="anchorPaneLeft" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
  </left>
</BorderPane>

The associated Java code is...

package sample.controller;

import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;

public class BorderPaneCtrl {
    @FXML private AnchorPane anchorPaneLeft;

    public BorderPaneCtrl() {
        /* so, @FXML-annotated variables are accessible, but not
         *   yet populated
         */
        if (anchorPaneLeft == null) {
            System.out.println("anchorPaneLeft is null");
        }
    }

/* this is what was missing...added for "completeness"
 */
@FXML
public void initialize() {
    /* anchorPaneLeft has now been populated, so it's now
     *   usable
     */
    if (anchorPaneLeft != null) {
        // do cool stuff
    }
}

Ego is not an issue here, I'm pretty sure I'm overlooking something simple.

SoCal
  • 801
  • 1
  • 10
  • 23
  • 1
    I don't see a package in your `BorderPaneCtrl` class. In the FXML file, you have `sample.controller.BorderPaneCtrl` – Michael Markidis Aug 24 '16 at 22:50
  • The package statement is there, but it was not the issue. I annotated my original post to show what I was missing. – SoCal Aug 25 '16 at 14:51

1 Answers1

1

FXML elements are not assigned yet in constuctor, but you can use Initializable interface where elements are already assigned.

public class Controller implements Initializable {
    @FXML
    AnchorPane anchorPaneLeft;

    public Controller() {
        System.out.println(anchorPaneLeft); //null
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println(anchorPaneLeft); //AnchorPane
    }
}

I assume that you know that you should create controllers with FXML by using for example: FXMLLoader.load(getClass().getResource("sample.fxml");

pr0gramist
  • 8,305
  • 2
  • 36
  • 48
  • The prior question (referenced at the top of this thread) correctly addresses the issue. It is not necessary to implement Initializable, but having an FXML-annotated initialize is needed, as the bound variables are not populated until after the constructor has been called. Grazi... – SoCal Aug 25 '16 at 14:49