[英]JavaFX looping over scenegraph controls
如何遍歷場景的控件? 我嘗試使用 getChildrenUnmodifiable() 但它只返回第一級兒童。
public void rec(Node node){
f(node);
if (node instanceof Parent) {
Iterator<Node> i = ((Parent) node).getChildrenUnmodifiable().iterator();
while (i.hasNext()){
this.rec(i.next());
}
}
}
您需要遞歸掃描。 例如:
private void scanInputControls(Pane parent) {
for (Node component : parent.getChildren()) {
if (component instanceof Pane) {
//if the component is a container, scan its children
scanInputControls((Pane) component);
} else if (component instanceof IInputControl) {
//if the component is an instance of IInputControl, add to list
lstInputControl.add((IInputControl) component);
}
}
}
這是我正在使用的amru 答案的修改版本,此方法為您提供特定類型的組件:
private <T> List<T> getNodesOfType(Pane parent, Class<T> type) {
List<T> elements = new ArrayList<>();
for (Node node : parent.getChildren()) {
if (node instanceof Pane) {
elements.addAll(getNodesOfType((Pane) node, type));
} else if (type.isAssignableFrom(node.getClass())) {
//noinspection unchecked
elements.add((T) node);
}
}
return Collections.unmodifiableList(elements);
}
獲取所有組件:
List<Node> nodes = getNodesOfType(pane, Node.class);
只獲取按鈕:
List<Button> buttons= getNodesOfType(pane, Button.class);
您還可以傳入一個謂詞,它允許進行任何類型的選擇。
Predicate<Node> p= n -> null ≃ n.getId() && n instanceof TextInputControl
將獲得所有 TextFields 和 TextAreas。
你可以把它全部打包成一個接口,Java 8 風格,然后你只需要在 Pane 或其他容器中實現Parent getRoot()
。
@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 );
}
}
}
}
假設您的窗格稱為窗格:
FXUIScraper scraper = () ->pane;
List<Node> textNodesWithId =
scraper.scrape(n -> null ≃ n.getId()
&& n instanceof TextInputControl);
如果您有有意義的 id,例如實體的字段名稱或 json 對象中的鍵名稱,那么將結果處理成所需的形式就變得微不足道了。 github上有一個項目包含 fxuiscraper作為一個單獨的項目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.