如何在场景的控件上循环?我尝试使用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());
}
}
}
您还可以传入谓词,它允许任何类型的选择。
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。
你需要递归扫描。例如:
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);
问题内容: 我有一个使用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类如下