【问题标题】:JavaFX 2.0 + FXML - strange lookup behaviourJavaFX 2.0 + FXML - 奇怪的查找行为
【发布时间】:2012-09-01 17:34:43
【问题描述】:

感谢Node#lookup(),我想在加载了FXMLoader 的场景中找到一个VBox 节点,但我得到以下异常:

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 文件:

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" >
  <children>
    <SplitPane dividerPositions="0.5" focusTraversable="true" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <items>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
        <VBox fx:id="myvbox" prefHeight="398.0" prefWidth="421.0" />
      </items>
    </SplitPane>
  </children>
</AnchorPane>

我想知道:
1. 为什么查找方法返回SplitPaneSkin$Content 而不是VBox
2.我怎样才能通过其他方式获得VBox

提前致谢

【问题讨论】:

    标签: java javafx-2 fxml


    【解决方案1】:

    获取对 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();
    

    【讨论】:

      【解决方案2】:
      1. SplitPane 将所有项目放在单独的堆栈窗格中(想象为SplitPaneSkin$Content)。由于未知原因,FXMLLoader 为它们分配了与根子节点相同的 id。你可以通过下一个实用方法获得你需要的VBox:

        public <T> T lookup(Node parent, String id, Class<T> 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;
        

      【讨论】:

      • 我用一个简单的例子更新了我的帖子。我知道@FXML 注释,但我不能使用它,因为 id 是自动生成的。
      • 太好了,效果很好。我不认为 FXMLoader 为它们分配了与 root 孩子相同的 id。我很高兴看到 Oracle JavaFX UI 团队的 QA 技术负责人回答了 stackoverflow 的问题。 非常感谢
      • 不客气,但请看下面格雷格的回答。看起来更清晰了。
      猜你喜欢
      • 1970-01-01
      • 2012-05-07
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      • 2017-03-17
      • 2015-01-15
      • 1970-01-01
      相关资源
      最近更新 更多