you could also pass in a predicate, which allows any kind of selection.
Predicate<Node> p= n -> null ≃ n.getId() && n instanceof TextInputControl
would get all TextFields and TextAreas.
You can pack it all in an interface, Java 8 style, and then you only need to implement Parent getRoot()
in the Pane or other container.
@FunctionalInterface
public interface FXUIScraper {
// abstract method.
Parent getRoot();
default List<Node> scrape( Predicate<Node> filter ) {
Parent top = getRoot();
List<Node> result = new ArrayList<>();
scrape( filter, result, top );
return result;
}
static void scrape( Predicate<Node> filter, List<Node> result, Parent top ) {
ObservableList<Node> childrenUnmodifiable = top.getChildrenUnmodifiable();
for ( Node node : childrenUnmodifiable ) {
if ( filter.test( node ) ) {
result.add( node );
}
if ( node instanceof Parent ) {
scrape( filter, result, (Parent)node );
}
}
}
}
Assuming that your Pane is called pane:
FXUIScraper scraper = () ->pane;
List<Node> textNodesWithId =
scraper.scrape(n -> null ≃ n.getId()
&& n instanceof TextInputControl);
If you have meaningful ids like names of fields of an entity or key names in json object, it becomes trivial to process the result into a desired form.
There is a project on github containing the fxuiscraper as a separate project.
ScrollPane
since it extendsControl
, notPane
... – Rockwell