1

I have a Scene called modSelectorScene, based on an fxml made in Scene Builder, the root element of which is a ScrollPane. The ScrollPane contains a VBox, which contains a few TitledPanes, each of which contains an AnchorPane, each of which contains a few Buttons.

The trouble all started when I tried to use modSelectorScene.lookup() with each button's fx:id to assign the buttons to Button objects in my code - each one was turning up null. I found I could assign an fx:id to the ScrollPane and lookup that, but nothing else. If I wrap the ScrollPane in, say, an AnchorPane and move one of the buttons into the AnchorPane, I can get at it normally with the lookup method.

So the solution I'm looking at right now involves alternating calls of getContent() and getChildren() on the ScrollPane and everything inside it to dig my way down and get my buttons that way. That works, but it's not very...elegant. So what I'd like to know is why the Buttons and all the other elements are somehow invisible to the lookup method while they're behind that ScrollPane, and whether there's any way to remedy that.

Here's one example:

modSelectorScene = new Scene(FXMLLoader.load(getClass().getResource("Dialog/ModSelector.fxml")));
...
ScrollPane modScrollPane = (ScrollPane) modSelectorScene.lookup("#modScrollPane");
Button modStr = (Button) modSelectorScene.lookup("#modStr");

Trying to add an EventHandler to modStr, for instance, throws a NullPointerException, but the ScrollPane is assigned as expected. Even the VBox directly inside it returns a null on lookup.

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • Why not to involve the controller of the fxml. After at all adding an event handler to controls is a job of controller imo, and in that controller class you can easily get the buttons by injecting them with @FXML annotation. See [this use case](http://stackoverflow.com/a/10753277) – Uluk Biy Jul 23 '15 at 04:26
  • @UlukBiy Yeah, we've thought about switching it over to using a controller class and the FXML annotations, but we're pretty deep into the project with the method we're using and we have a deadline of sorts coming up soon, so we're probably gonna wait until after to do any major rework like that. It will probably be what we end up using ultimately, but for now I'm curious to see if another solution exists. – Jake Elzinga Jul 23 '15 at 04:33

2 Answers2

2

It seems for layouts having getContent() (instead of getChildren()) method like ScrollPane and TitledPane, the lookup will work after the scene is shown. So you can try to wrap the lookup code into runnable:

Platform.runLater(() ->
{
    // lookup code
});
Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • Alright, this helped. I'm able to move the lookup code and the EventHandlers into a method that's called after modSelectorStage is shown and it looks to be working. Thanks! – Jake Elzinga Jul 23 '15 at 05:30
0

try to use getContent() before lookup(...):

titledPane.getContent().lookup("#id")
polmabri
  • 1,103
  • 8
  • 10