JavaFX: ScrollPane method getChildren() is not visible

pkaramol picture pkaramol · Oct 14, 2014 · Viewed 7.3k times · Source

I have created a Stage from an AnchorPane and some children elements (the AnchorPane and its children have been created in Java Scene Builder) and the hierarchy is shown below: Scene hierarchy

The stage and the scene are of course created programmatically at program initialization. I want to also add programmatically a GridPane as a child of the ScrollPane shown in the image. In my program (the controller of the specific window) I can get a reference to the ScrollPane:

@FXML
private ScrollPane srcPaneUsers;

(the id srcPaneUsers has been given through the respective field of the properties windows of Scene Builder)

HOWEVER!!: When I try to add programmatically a new GridPane created at run-time through the following lines of the initialize method of the controller:

public void initialize(URL location, ResourceBundle resources) {
    myGridPane = new GridPane();
    srcPaneUsers.getChildren().add(myGridPane);
}

I get a compile time error that says "The method getChildren() from the type Parent is not visible." And so I cannot add my GridPane at run time. Any ideas?

Answer

James_D picture James_D · Oct 14, 2014

You are calling the wrong method. You need

srcPaneUsers.setContent(myGridPane);

The getChildren() method defined in Parent is a protected method. It is overridden in Pane to be a public method, so for layout panes (GridPane, BorderPane, etc) you can directly manipulate the list of child nodes.

ScrollPane's hierarchy is ScrollPane extends Control extends Region extends Parent, so it inherits the protected getChildren() method. And this actually makes sense: the child nodes of a ScrollPane are things like the viewport (which clips the view of the content) and scrollbars: you don't really want the user to be manipulating those, otherwise what you end up with is likely not to function correctly any more. ScrollPanes really only have one node that is configurable: the node of which the ScrollPane is providing a view: this is referred to as its content and accessed via the contentProperty(), getContent(), and setContent() methods.

Other "container-like controls" work similarly. The TabPane class exposes a getTabs() method that returns an ObservableList<Tab>; and the Tab class in turn exposes a contentProperty() so you can access the content of each individual tab. The SplitPane tab exposes a getItems() method returning an ObservableList<Node> for the nodes displayed in the pane. In the case of a SplitPane its child nodes are more than the items: they include the visual components representing the dividers, etc. In both these cases, the getChildren() method is a protected method (inherited from Parent).

Note that Parent also defines a public getChildrenUnmodifiable() method, which returns an unmodifiable view of the list of child nodes. You can use this to examine the node hierarchy of any parent, but not modify it. (For debugging purposes, however, especially for working with CSS, I recommend using ScenicView.)