как получить все узлы сцены в javafx?

<p>в c # я нашел довольно приятный метод, который позволил вам получить всех потомков и всех их потомков из указанного элемента управления.</p><p>я ищу аналогичный метод для javafx.</p><p>я видел, что класс <code>parent</code> - это то, с чем я хочу работать, так как это класс, из которого получены все классы node, которые имеют дочерние классы.</p><p>это то, что я до сих пор (и я действительно не нашел ничего в google с поиском, как "javafx получить все узлы из сцены"):</p><pre><code>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) ); }); } </code></pre><p>итак, как мне узнать, является ли n родительским (или расширенным от родительского)? я делаю это правильно? кажется, он не работает ... он захватывает все узлы из корневого (родительского) узла, но не из узлов с дочерними элементами в них. я чувствую, что это то, на что, вероятно, есть ответ, но я просто задаю вопрос ... неправильно. как мне это сделать?</p>

<pre><code>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); } } </code></pre>

<p>я использую это,</p><pre><code>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; } } </code></pre><p>использование,</p><pre><code>list<node> nodes = nodeutils.panenodes(avboxoranothercontainer); </code></pre><p>этот исходный код использует ссылки на существующие узлы. это не клонирует их.</p>

<p>к сожалению, для большинства компонентов контейнера это не даст подузлов. если вы попробуете <code>tabpane</code> в качестве родителя, вы не найдете дочерних элементов, но вы можете найти в нем вкладки с помощью <code>gettabs()</code>. то же самое с <code>splitpane</code> и другим. таким образом, каждый контейнер потребует особого подхода.</p><p>вы можете использовать <code>node.lookupall("*")</code>, но она также не заглядывает внутрь.</p><p>решением может быть шаблон «прототип» - создание мета-класса с общим интерфейсом метода <code>getchildren()</code>, который реализуется в подклассах - по одному для каждого типа.</p><p>пример подхода приведен <a href="https://stackoverflow.com/a/17117677/1112963">здесь</a> .</p>

<p>это работает для меня:</p><pre><code>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; } } </code></pre>

<p>это, кажется, получить все узлы . (в kotlin)</p><pre><code>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 } </code></pre>

<p>я хотел бы добавить к ответу ганса, что вы должны проверить, является ли parent <code>splitpane</code>. поскольку у <code>splitpane</code>s есть пустой список с использованием <code>getunmodifiablechildren()</code>, вам придется использовать вместо него <code>getitems()</code>. (я не знаю, есть ли другие родители, которые не предоставляют своих детей через <code>getunmodifiablechildren()</code>. <code>splitpane</code> был первым, кого я нашел ...)</p>