是否有一种简单(统一)的方法从定义的节点(可能来自Scene本身)递归下降JavaFX小部件树?
以下代码:
static class Visitor {
public void visit(Node node){
...
}
}
protected void walkWidgets(Node n, Visitor cb) {
if (n instanceof Parent) {
Parent p = (Parent) n;
for (Node c : p.getChildrenUnmodifiable()) {
walkWidgets(c, cb);
}
}
cb.visit(n);
}
... 不工作,因为"孩子"一些容器(例如:SplitPane,BorderPane等)在其子属性中列出 。
为了解决这个问题,我应该专门编写代码以允许所有不同小部件的所有怪癖。当您开始使用"标准"之外的小部件库时,这尤其令人讨厌。规定。
我错过了什么吗? (我当然希望如此!)
答案 0 :(得分:1)
这似乎工作正常:它获取BorderPane
,SplitPane
和TabPane
中的所有子节点。
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class WalkComponentTree extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
root.setTop(new Label("Title"));
SplitPane splitPane = new SplitPane();
root.setCenter(splitPane);
ListView<String> list = new ListView<>();
list.getItems().addAll("One", "Two", "Three");
TabPane tabPane = new TabPane();
Tab tab1 = new Tab();
tab1.setContent(new TextArea());
Tab tab2 = new Tab();
tab2.setContent(new Label("Tab 2"));
tabPane.getTabs().addAll(tab1, tab2);
splitPane.getItems().addAll(tabPane, list);
Button button = new Button("Walk tree");
button.setOnAction(event -> walkTree(root, node ->
System.out.println(node.getClass())));
root.setBottom(button);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void walkTree(Node node, Consumer<Node> visitor) {
visitor.accept(node);
if (node instanceof Parent) {
((Parent) node).getChildrenUnmodifiable()
.forEach(n -> walkTree(n, visitor));
}
}
public static void main(String[] args) {
launch(args);
}
}
请注意,您也可以使用node.lookupAll("*");
,但这不太健壮,因为只有在css应用于节点后才能使用。
答案 1 :(得分:0)
在我看来,你说没有&#34;标准&#34;是正确的。浏览JavaFX场景图的方法。
一个原因是Tab
不是来自Node
,因此您无法从Parent.getChildrenUnmodifiable()
获取标签列表。另一个原因是,ScrollPane
和TitledPane
不会在Parent.getChildrenUnmodifiable()
中发布其内容节点。其他一些窗格Accordion
,SplitPane
和Toolbar
也不会使用Parent.getChildrenUnmodifiable()
发布他们的孩子。所以你需要自己处理。
有关详细信息,请参阅: Walking the JavaFX Scene Graph