I want to find a VBox node in a scene loaded with FXMLoader
thanks to Node#lookup()
but I get the following exception :
java.lang.ClassCastException: com.sun.javafx.scene.control.skin.SplitPaneSkin$Content cannot be cast to javafx.scene.layout.VBox
The code :
public class Main extends Application {
public static void main(String[] args) {
Application.launch(Main.class, (java.lang.String[]) null);
}
@Override
public void start(Stage stage) throws Exception {
AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("test.fxml"));
Scene scene = new Scene(page);
stage.setScene(scene);
stage.show();
VBox myvbox = (VBox) page.lookup("#myvbox");
myvbox.getChildren().add(new Button("Hello world !!!"));
}
}
The fxml file:
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" >
<children>
<SplitPane dividerPositions="0.5" focusTraversable="true" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
<VBox fx:id="myvbox" prefHeight="398.0" prefWidth="421.0" />
</items>
</SplitPane>
</children>
</AnchorPane>
I would like to know :
1. Why lookup method return a SplitPaneSkin$Content
and not a VBox
?
2. How I can get the VBox
in another manner ?
Thanks in advance
The easiest way to get a reference to the VBox is by calling FXMLLoader#getNamespace(). For example:
VBox myvbox = (VBox)fxmlLoader.getNamespace().get("myvbox");
Note that you'll need to create an instance of FXMLLoader and call the non-static version of load() in order for this to work:
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("test.fxml"));
AnchorPane page = (AnchorPane) fxmlLoader.load();
SplitPane puts all items in separate stack panes (fancied as SplitPaneSkin$Content
). For unknown reason FXMLLoader assign them the same id as root child. You can get VBox you need by next utility method:
public <T> T lookup(Node parent, String id, Class<T> clazz) {
for (Node node : parent.lookupAll(id)) {
if (node.getClass().isAssignableFrom(clazz)) {
return (T)node;
}
}
throw new IllegalArgumentException("Parent " + parent + " doesn't contain node with id " + id);
}
and use it next way:
VBox myvbox = lookup(page, "#myvbox", VBox.class);
myvbox.getChildren().add(new Button("Hello world !!!"));
you can use Controller and add autopopulated field:
@FXML
VBox myvbox;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With