Last active
May 7, 2021 06:59
-
-
Save andytill/3024651 to your computer and use it in GitHub Desktop.
Utility for for finding a JavaFX node by it's ID
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Good spot, thanks.
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.
Nice, thanks. To work for me, I added some lines to find nodes in TabPanes.
Maybe my article about walking the JavaFX scene graph will be helpful in this context: http://www.kware.net/?p=8
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
bug: id.equals(id)