在C#中,我找到了一个非常好的方法,允许你从指定的控件中获取所有后代和所有的后代。
我正在为JavaFX寻找类似的方法。
我看到Parent
类是我想要使用的类,因为它是从中派生所有带子项的Node类的类。
这就是我到目前为止所做的事情(我还没有真正在google上找到像&#34这样的搜索内容; JavaFX从场景中获取所有节点"):
public static ArrayList<Node> GetAllNodes(Parent root){
ArrayList<Node> Descendents = new ArrayList<>();
root.getChildrenUnmodifiable().stream().forEach(N -> {
if (!Descendents.contains(N)) Descendents.add(N);
if (N.getClass() == Parent.class) Descendents.addAll(
GetAllNodes((Parent)N)
);
});
}
那么如何判断N是父母(或从父母延伸)?我这样做了吗?它似乎没有工作......它从根(父)节点抓取所有节点,但不从其中包含子节点的节点抓取。我觉得这可能是一个可以得到答案的东西,但我只是问这个问题......错了。我该怎么做呢?
答案 0 :(得分:16)
public static ArrayList<Node> getAllNodes(Parent root) {
ArrayList<Node> nodes = new ArrayList<Node>();
addAllDescendents(root, nodes);
return nodes;
}
private static void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
nodes.add(node);
if (node instanceof Parent)
addAllDescendents((Parent)node, nodes);
}
}
答案 1 :(得分:1)
不幸的是,这不会获得大多数容器组件的子节点。如果您尝试使用TabPane
作为父级,则不会找到任何子级,但您可以使用getTabs()
找到其中的标签。同样是SplitPane
和其他。所以每个容器都需要特定的方法。
您可以使用node.lookupAll("*")
,但它也无法查看。
解决方案可能是&#34;原型&#34; pattern - 使用getChildren()
方法的公共接口创建一个元类,该方法在子类中实现 - 每种类型一个。
方法示例为here。
答案 2 :(得分:1)
我用这个,
public class NodeUtils {
public static <T extends Pane> List<Node> paneNodes(T parent) {
return paneNodes(parent, new ArrayList<Node>());
}
private static <T extends Pane> List<Node> paneNodes(T parent, List<Node> nodes) {
for (Node node : parent.getChildren()) {
if (node instanceof Pane) {
paneNodes((Pane) node, nodes);
} else {
nodes.add(node);
}
}
return nodes;
}
}
用法,
List<Node> nodes = NodeUtils.paneNodes(aVBoxOrAnotherContainer);
此源代码使用现有节点的引用。它不会克隆它们。
答案 3 :(得分:0)
这似乎获得了所有节点。 (在科特林)
fun getAllNodes(root: Parent): ArrayList<Node> {
var nodes = ArrayList<Node>()
fun recurseNodes(node: Node) {
nodes.add(node)
if(node is Parent)
for(child in node.childrenUnmodifiable) {
recurseNodes(child)
}
}
recurseNodes(root)
return nodes
}
答案 4 :(得分:0)
这对我有用:
public class FXUtil {
public static final List<Node> getAllChildren(final Parent parent) {
final List<Node> result = new LinkedList<>();
if (parent != null) {
final List<Node> childrenLvl1 = parent.getChildrenUnmodifiable();
result.addAll(childrenLvl1);
final List<Node> childrenLvl2 =
childrenLvl1.stream()
.filter(c -> c instanceof Parent)
.map(c -> (Parent) c)
.map(FXUtil::getAllChildren)
.flatMap(List::stream)
.collect(Collectors.toList());
result.addAll(childrenLvl2);
}
return result;
}
}