There are a couple of reasons why your application doesn't work:
- You need to make the Controller and the Application separate classes.
- You should allow the FXML system to inject the TreeView instance rather than creating a new instance (as Aaron points out in his answer).
The way you have your application currently structured what will happen is:
- The Java system will create an instance of
MyControllerClass
on startup (and invoke it's start
method).
- The
FXMLLoader
will create another instance of MyControllerClass
each time the myInterface.fxml
file is loaded.
- The
FXMLLoader
will create a new TreeView
instance and perform the FXML injection on the locationTreeView
member of the new MyControllerClass
instance it creates.
- The
FXMLLoader
will try to invoke the initialize
method on the new MyControllerClass
(of which you have none).
- The
FXMLLoader
will not invoke the start
method on the new MyControllerClass
.
- Your original
start
method invocation on your original MyControllerClass
will continue processing and create another new TreeView
instance which it will set the locationTreeView
member of the old MyControllerClass
instance to.
I updated your code to make the modifications I suggested above and the code now works. The updated code is available.
A sample screenshot from the running code is:

MyApplicationClass.java
import javafx.animation.*;
import javafx.application.Application;
import javafx.event.*;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.stage.*;
import javafx.util.Duration;
/** Sample application to demonstrate programming an FXML interface. */
public class MyApplicationClass extends Application {
@Override public void start(final Stage stage) throws Exception {
// load the scene fxml UI.
// grabs the UI scenegraph view from the loader.
// grabs the UI controller for the view from the loader.
final FXMLLoader loader = new FXMLLoader(getClass().getResource("myInterface.fxml"));
final Parent root = (Parent) loader.load();
final MyControllerClass controller = loader.<MyControllerClass>getController();
// continuously refresh the TreeItems.
// demonstrates using controller methods to manipulate the controlled UI.
final Timeline timeline = new Timeline(
new KeyFrame(
Duration.seconds(3),
new TreeLoadingEventHandler(controller)
)
);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
// close the app if the user clicks on anywhere on the window.
// just provides a simple way to kill the demo app.
root.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent t) {
stage.hide();
}
});
// initialize the stage.
stage.setScene(new Scene(root));
stage.initStyle(StageStyle.TRANSPARENT);
stage.getIcons().add(new Image(getClass().getResourceAsStream("myIcon.png")));
stage.show();
}
/** small helper class for handling tree loading events. */
private class TreeLoadingEventHandler implements EventHandler<ActionEvent> {
private MyControllerClass controller;
private int idx = 0;
TreeLoadingEventHandler(MyControllerClass controller) {
this.controller = controller;
}
@Override public void handle(ActionEvent t) {
controller.loadTreeItems("Loaded " + idx, "Loaded " + (idx + 1), "Loaded " + (idx + 2));
idx += 3;
}
}
// main method is only for legacy support - java 8 won't call it for a javafx application.
public static void main(String[] args) { launch(args); }
}
MyControllerClass.java
import javafx.fxml.FXML;
import javafx.scene.control.*;
/** Sample controller class. */
public class MyControllerClass {
// the FXML annotation tells the loader to inject this variable before invoking initialize.
@FXML private TreeView<String> locationTreeView;
// the initialize method is automatically invoked by the FXMLLoader - it's magic
public void initialize() {
loadTreeItems("initial 1", "initial 2", "initial 3");
}
// loads some strings into the tree in the application UI.
public void loadTreeItems(String... rootItems) {
TreeItem<String> root = new TreeItem<String>("Root Node");
root.setExpanded(true);
for (String itemString: rootItems) {
root.getChildren().add(new TreeItem<String>(itemString));
}
locationTreeView.setRoot(root);
}
}
myInterface.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns:fx="http://javafx.com/fxml" fx:controller="test.MyControllerClass">
<TreeView fx:id="locationTreeView" layoutX="0" layoutY="0" prefHeight="193.0" prefWidth="471.0" />
</AnchorPane>