JavaFX 2.0 + FXML – 奇怪的查找行为

感谢Node#lookup()我希望在装有FXMLoader的场景中找到一个VBox节点,但是我得到以下exception:

java.lang.ClassCastException: com.sun.javafx.scene.control.skin.SplitPaneSkin$Content cannot be cast to javafx.scene.layout.VBox

代码 :

 public class Main extends Application { public static void main(String[] args) { Application.launch(Main.class, (java.lang.String[]) null); } @Override public void start(Stage stage) throws Exception { AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("test.fxml")); Scene scene = new Scene(page); stage.setScene(scene); stage.show(); VBox myvbox = (VBox) page.lookup("#myvbox"); myvbox.getChildren().add(new Button("Hello world !!!")); } } 

fxml文件:

           

我想知道 :
1.为什么查找方法返回SplitPaneSkin$Content而不是VBox
2.我如何以另一种方式获得VBox

提前致谢

  1. SplitPane将所有项目放在单独的堆栈窗格中(称为SplitPaneSkin$Content )。 由于未知原因,FXMLLoader为它们分配与root child相同的id。 您可以通过下一个实用方法获得所需的VBox:

     public  T lookup(Node parent, String id, Class clazz) { for (Node node : parent.lookupAll(id)) { if (node.getClass().isAssignableFrom(clazz)) { return (T)node; } } throw new IllegalArgumentException("Parent " + parent + " doesn't contain node with id " + id); } 

    然后使用它:

     VBox myvbox = lookup(page, "#myvbox", VBox.class); myvbox.getChildren().add(new Button("Hello world !!!")); 
  2. 您可以使用Controller并添加自动填充字段:

     @FXML VBox myvbox; 

获取VBox引用的最简单方法是调用FXMLLoader#getNamespace()。 例如:

 VBox myvbox = (VBox)fxmlLoader.getNamespace().get("myvbox"); 

请注意,您需要创建FXMLLoader的实例并调用load()的非静态版本才能使其正常工作:

 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("test.fxml")); AnchorPane page = (AnchorPane) fxmlLoader.load();