当前位置: 首页 > 知识库问答 >
问题:

JavaFX在场景图控件上循环

赏新知
2023-03-14

如何在场景的控件上循环?我尝试使用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());
        }
    }
}

共有3个答案

范承教
2023-03-14

您还可以传入谓词,它允许任何类型的选择。

Predicate<Node> p= n -> null ≃ n.getId() && n instanceof TextInputControl 

会得到所有的文本字段和文本区域。

您可以将其全部打包到一个Java 8风格的接口中,然后只需在窗格或其他容器中实现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。

葛骏
2023-03-14

你需要递归扫描。例如:

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);
        }
    }
}
羊舌琛
2023-03-14

这是我正在使用的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);
 类似资料:
  • 问题内容: 我有一个使用javafx Scene来渲染某些东西的应用程序,并且我想将该渲染结果放入我在Javafx中创建的某些GUI中。我该怎么做? 基本上,有一些容器可以放入场景,然后将其放入GUI。 抱歉,如果是新手问题,我是JavaFX的新手 问题答案: 该场景只有一个顶级父节点作为根。您可以获取它并放入另一个场景。

  • 我创建了一个游戏,我想给它添加一个开始屏幕,我使用FXML添加了它,还添加了两个按钮(开始和退出)。 按下开始按钮后,我希望游戏加载场景并切换到游戏开始。我对如何做有一个粗略的想法,但我有点挣扎,因为我的SampleController类不知道如何启动游戏等,因为所有代码(以及加载初始开始菜单的代码)都在我的主类中,所以我尝试了这样的事情: 我尝试使用一个函数来切换场景,但它不起作用,也试图使用获

  • 问题内容: 有什么方法可以从关联的类控制器获取FXML加载文件的Scene对象。 我正在做这样的事情: 但是我想要一个不引用AnchorPane控件的解决方案。 问题答案: 为什么不?Controller是一个抽象类,除非您有意让他知道,否则他不了解UI。 节点(包括AnchorPane)是另一个故事,它们几乎不存在于场景图的外部。因此,最好向Node询问有关其父母或场景的信息。 如果您仍然想单独

  • 但我想要一个不引用AnchorPane控件的解决方案。

  • 我想在一个扩展场景的类中画一张画布。当我按下场景上的按钮时,这个场景应该显示出来,这个场景是在扩展的类“GUI”中创建的。 为设置图像(我不知道要将ImageView作为子节点添加到哪个节点{类似不起作用}) 试图在画布上画画。(与上面的问题相同。在哪里添加此画布?) 类: 和类: PS:Jeah!我在这个论坛上的第一个问题。你好世界!

  • 我正在设计一款跳棋游戏,一旦游戏结束,一个新窗口就会打开,你可以开始一个新游戏,也可以退出。我对JavaFX了解不多,我一直在努力让我的代码正常工作,但我没有成功。。。 我有一个困难,我的电路板没有显示为fxml文件,但它是用Java代码创建的,并放在我的边框窗格的中心。边框窗格的顶部是fxml文件。然后,游戏结束后的另一个窗口也是另一个fxml文件: 这个fxml文件的Controller类如下