如何在 JavaFX 中获取父节点中的所有节点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24986776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get all nodes in a parent in JavaFX?
提问by Will
In C# I found a method that was pretty sweet that allowed you to get all the descendants and all of THEIR descendants from a specified control.
在 C# 中,我发现了一种非常棒的方法,它允许您从指定的控件中获取所有后代和所有 THEIR 后代。
I'm looking for a similar method for JavaFX.
我正在为 JavaFX 寻找类似的方法。
I saw that the Parent
class is what I want to work with since it is the class from which all Node classes that bear children are derived.
我看到这个Parent
类是我想要使用的类,因为它是所有带有子节点的 Node 类的派生类。
This is what I have so far (and I haven't really found anything on google with searches like "JavaFX get all nodes from a scene"):
这就是我到目前为止所拥有的(而且我还没有在谷歌上真正找到任何类似“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)
);
});
}
So how do I tell if N is a parent (or extended from a parent)? Am I doing that right? It doesn't seem to be working... It's grabbing all the nodes from the root (parent) node but not from the nodes with children in them. I feel like this is something that's probably got an answer to it but I'm just asking the question... wrong. How do I go about doing this?
那么我如何判断 N 是否是父级(或从父级扩展而来)?我这样做对吗?它似乎没有工作......它从根(父)节点中获取所有节点,而不是从其中包含子节点的节点中获取。我觉得这可能是有答案的,但我只是在问这个问题……错了。我该怎么做?
采纳答案by Hans Brende
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);
}
}
回答by Helkaruthion
I'd like to add to Hans' answer, that you have to check if parent is a SplitPane
. Because SplitPane
s have an empty list using getUnmodifiableChildren()
, you'll have to use getItems()
instead. (I do not know if there are other parents that do not provide their children via getUnmodifiableChildren()
. SplitPane
was the first I found...)
我想补充一下 Hans 的回答,您必须检查 parent 是否为SplitPane
. 因为SplitPane
s 有一个使用 的空列表getUnmodifiableChildren()
,所以您必须改为使用getItems()
。(我不知道是否有其他父母不通过getUnmodifiableChildren()
.SplitPane
是我发现的第一个......)
回答by Zon
Unfortunately this won't get subnodes for most container components. If you try a TabPane
as parent, you'll find no children, but you can find tabs in it with getTabs()
. The same is with SplitPane
and other. So every container will require a specific approach.
不幸的是,对于大多数容器组件,这不会获得子节点。如果您尝试将 aTabPane
作为父项,您将找不到子项,但您可以在其中找到带有getTabs()
. 与SplitPane
和其他相同。因此,每个容器都需要特定的方法。
You could use node.lookupAll("*")
, but it also doesn't look inside.
您可以使用node.lookupAll("*")
,但它也看不到内部。
The solution could be a "Prototype" pattern - creating a meta class with common interface of getChildren()
method, which is realized in subclasses - one for each type.
解决方案可能是“原型”模式——创建一个具有通用getChildren()
方法接口的元类,它在子类中实现——每个类型一个。
Approach example is given here.
方法示例在此处给出。
回答by George Siggouroglou
I use this,
我用这个,
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;
}
}
Usage,
用法,
List<Node> nodes = NodeUtils.paneNodes(aVBoxOrAnotherContainer);
This source code uses the references of the existing nodes. It does not clone them.
此源代码使用现有节点的引用。它不会克隆它们。
回答by Red wine
This seems to get ALL nodes. (In Kotlin)
这似乎获得了所有节点。(在科特林)
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
}
回答by Marcel Wieczorek
This works for me:
这对我有用:
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;
}
}