如果我搜索我的VBox,scene.lookup()返回null [英] scene.lookup() returns null if i search my VBox

查看:116
本文介绍了如果我搜索我的VBox,scene.lookup()返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我需要从fxml文件中检索VBox,我正在使用scene.lookup。
但是如果我搜索它,它只会崩溃并发生NullPointerException。

Basically, i need to retrieve a VBox from an fxml file and i'm using scene.lookup. But if i search for it, it just crashes with a NullPointerException.

所以我试图打印出scene.lookup()找到的内容,它只是发现null(duh),但我不明白为什么。

So i tried to print what scene.lookup() finds, and it just finds null (duh), but i can't understand why.

这是我的主类:

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception{

        FXMLLoader loader = new FXMLLoader(getClass().getResource("MainWindow.fxml"));
        Parent root = loader.load();
        Scene scene = new Scene(root, 600, 575);
        Controller controller = new Controller();
        controller.setScene(scene);
        System.out.println(scene.lookup("#vBox"));


        stage.setScene(scene);
        stage.setTitle("Test");
        stage.setResizable(false);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这是我的fxml文件:

And this is my fxml file:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane fx:id="borderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="575.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <top>
      <ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
        <items>
          <Button fx:id="addBtn" mnemonicParsing="false" onAction="#addEventHandler" prefHeight="30.0" prefWidth="75.0" text="Add" />
            <Button fx:id="editBtn" mnemonicParsing="false" prefHeight="30.0" prefWidth="75.0" text="Edit..." />
            <Button fx:id="delBtn" mnemonicParsing="false" prefHeight="30.0" prefWidth="75.0" text="Delete" />
        </items>
      </ToolBar>
   </top>
   <center>
      <ScrollPane fx:id="scrollPane" prefHeight="515.0" prefWidth="600.0" BorderPane.alignment="CENTER">
         <content>
            <VBox fx:id="vBox" fillWidth="true" />
         </content>
      </ScrollPane>
   </center>
</BorderPane>


推荐答案

首先,你真的不应该这样做一点都不只需将 VBox 注入控制器,然后在那里做任何你需要做的事情:

First, you really shouldn't need to do this at all. Just inject the VBox into the controller, and then do whatever you need to do to it there:

public class Controller {

    @FXML
    private VBox vBox ;

    public void initialize() {
        // do something with vBox...
    }
}

直接解决您的问题:

在应用CSS之前,查找将无效,这通常是在第一个渲染脉冲上。直到最早显示该阶段才会发生这种情况。

Lookups will not work until CSS has been applied, which is typically on the first rendering pulse. This will not happen until the stage has been displayed, at the earliest.

如果在显示阶段后将查找代码移动到它,可能 em> work:

If you move the lookup code to after you show the stage, it might work:

@Override
public void start(Stage stage) throws Exception{

    FXMLLoader loader = new FXMLLoader(getClass().getResource("MainWindow.fxml"));
    Parent root = loader.load();
    Scene scene = new Scene(root, 600, 575);


    stage.setScene(scene);
    stage.setTitle("Test");
    stage.setResizable(false);
    stage.show();

    System.out.println(scene.lookup("#vBox"));
}

查询一般来说不是很强大。如上所述,您应该只是访问控制器中的FXML元素。只是为了给你另一个选项,你可以从 FXMLLoader 获得命名空间,这是一个 Map< String,Object> 包含FXML的所有元素,其中包含 fx:id s(以及其他内容)。

Lookups in general are not very robust. As indicated above, you should really just access elements of the FXML in the controller. Just to give you one other option, you can get the namespace from the FXMLLoader, which is a Map<String, Object> containing all the elements of the FXML which have fx:ids (among other things).

所以你可以这样做:

    FXMLLoader loader = new FXMLLoader(getClass().getResource("MainWindow.fxml"));
    Parent root = loader.load();
    Map<String, Object> namespace = loader.getNamespace();
    System.out.println(namespace.get("vBox"));

除此之外,请注意

    Controller controller = new Controller();
    controller.setScene(scene);

什么都不做。创建新控制器与获取 FXMLLoader 为您创建的控制器不同。 (无论如何,你总是可以在控制器中执行 vBox.getScene()来获取场景。)

doesn't do anything. Creating a new controller is not the same as getting the controller that was created for you by the FXMLLoader. (It's redundant anyway, you can always do vBox.getScene() in the controller to get the scene.)

这篇关于如果我搜索我的VBox,scene.lookup()返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆