Reputation: 199
I am creating an app which should guide the user through steps as can be seen in the below screenshot:
<Step fx:id="selectConnectionStep" source="SelectConnection" stepLabel="Step 1 : Select a Connection" />
<Step fx:id="selectSObjectStep" source="SelectSObject" stepLabel="Step 2 : Select an SObject" />
<Step fx:id="selectActionStep" stepLabel="Step 3 : Select an Action">
<VBox GridPane.columnSpan="2" GridPane.rowIndex="1">
<Action actionLabel="test" onAction="#test" />
<GridPane.margin>
<Insets bottom="15.0" left="15.0" right="10.0" top="10.0" />
</GridPane.margin>
</VBox>
</Step>
In the app I have more scenes configured to work that way so I want to design it in a way it will be easy to maintain.
I have created Custom Control called "Step" (which is basically extends GridPane)
Each "Step" has title, loadingIcon and the Inner Component.
In the first two steps, i load the inner component using the 'source' attribute I created. I just give the name of the Component's FXML file. In the code I just load the FXML and put the component inside the right place. However, as can be seen in the 3rd step, I try to just populate the Inner Component as the Step child. As can be seen this is working, however I want Step to inject its child inside the right place without specifying any details of where to put it inside the grid.
I.e.
<Step fx:id="selectActionStep" stepLabel="Step 3 : Select an Action">
<VBox>
<Action actionLabel="test" onAction="#test" />
</VBox>
</Step>
If I just don't specify any details, the component will go inside the GridPane on the top left corner.
The question is how can a Custom Control manipulate its FXML child elements ? Is it also ok that i extend GridPane ?
Thanks :)
Upvotes: 0
Views: 306
Reputation: 199
I've also found this post which introduces another solution:
How to add node to another node's child in FXML?
Upvotes: 1
Reputation: 82491
The best way to do this is adding a ListChangeListener
to the child list after adding the "standard" elements, e.g.
private static final Insets MARGIN = new Insets(10, 10, 15, 15);
...
// add standard elements...
getChildren().addListener((ListChangeListener.Change<? extends Node> c) -> {
while (c.next()) {
if (c.wasAdded()) {
for (Node n : c.getAddedSubList()) {
GridPane.setColumnSpan(2);
GridPane.setRowIndex(1);
GridPane.setMargin(MARGIN);
}
}
}
});
Upvotes: 2