Skip to content

Instantly share code, notes, and snippets.

@andytill
Last active May 7, 2021 06:59
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andytill/3024651 to your computer and use it in GitHub Desktop.
Save andytill/3024651 to your computer and use it in GitHub Desktop.
Utility for for finding a JavaFX node by it's ID
package test;
import javafx.scene.*;
import javafx.scene.control.*;
public class FXUtils {
/**
* Find a {@link Node} within a {@link Parent} by it's ID.
* <p>
* This might not cover all possible {@link Parent} implementations but it's
* a decent crack. {@link Control} implementations all seem to have their
* own method of storing children along side the usual
* {@link Parent#getChildrenUnmodifiable()} method.
*
* @param parent
* The parent of the node you're looking for.
* @param id
* The ID of node you're looking for.
* @return The {@link Node} with a matching ID or {@code null}.
*/
@SuppressWarnings("unchecked")
static <T> T getChildByID(Parent parent, String id) {
String nodeId = null;
if(parent instanceof TitledPane) {
TitledPane titledPane = (TitledPane) parent;
Node content = titledPane.getContent();
nodeId = content.idProperty().get();
if(nodeId != null && nodeId.equals(id)) {
return (T) content;
}
if(content instanceof Parent) {
T child = getChildByID((Parent) content, id);
if(child != null) {
return child;
}
}
}
for (Node node : parent.getChildrenUnmodifiable()) {
nodeId = node.idProperty().get();
if(nodeId != null && nodeId.equals(id)) {
return (T) node;
}
if(node instanceof SplitPane) {
SplitPane splitPane = (SplitPane) node;
for (Node itemNode : splitPane.getItems()) {
nodeId = itemNode.idProperty().get();
if(nodeId != null && nodeId.equals(id)) {
return (T) itemNode;
}
if(itemNode instanceof Parent) {
T child = getChildByID((Parent) itemNode, id);
if(child != null) {
return child;
}
}
}
}
else if(node instanceof Accordion) {
Accordion accordion = (Accordion) node;
for (TitledPane titledPane : accordion.getPanes()) {
nodeId = titledPane.idProperty().get();
if(nodeId != null && nodeId.equals(id)) {
return (T) titledPane;
}
T child = getChildByID(titledPane, id);
if(child != null) {
return child;
}
}
}
else if(node instanceof Parent) {
T child = getChildByID((Parent) node, id);
if(child != null) {
return child;
}
}
}
return null;
}
}
@olpf
Copy link

olpf commented Apr 26, 2013

bug: id.equals(id)

@andytill
Copy link
Author

Good spot, thanks.

@havardge
Copy link

Please consider adding support for the ScrollPane. It exposes its child through getContent(), in the exact same way as TitledPane, so adding it should be straight forward. Thanks.

@embewee
Copy link

embewee commented Jan 21, 2015

Nice, thanks. To work for me, I added some lines to find nodes in TabPanes.

@ckeimel
Copy link

ckeimel commented Mar 9, 2015

Maybe my article about walking the JavaFX scene graph will be helpful in this context: http://www.kware.net/?p=8

@SaiPradeepDandem
Copy link

Nice. I am not criticising, but are there any drawbacks in using the below code instead of your utility ?

Node child = parent.lookup("#"+id);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment