如果我搜索VBox,scene.lookup()返回null

Nig*_*aye 2 java javafx javafx-8

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

所以我试着打印一下scene.lookup()发现的东西,它只是找到null(duh),但我不明白为什么。

这是我的主班:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的fxml文件:

<?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>
Run Code Online (Sandbox Code Playgroud)

Jam*_*s_D 5

首先,您实际上根本不需要这样做。只需将注入VBox控制器,然后在该处执行您需要做的任何事情:

public class Controller {

    @FXML
    private VBox vBox ;

    public void initialize() {
        // do something with vBox...
    }
}
Run Code Online (Sandbox Code Playgroud)

要直接解决您的问题:

在应用CSS(通常在第一个渲染脉冲上)之前,查找将不起作用。最早在显示该阶段之前,不会发生这种情况。

如果在显示阶段之后将查找代码移至,则可能可行:

@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"));
}
Run Code Online (Sandbox Code Playgroud)

通常,查询不是很可靠。如上所述,您实际上应该只访问控制器中FXML的元素。只给你一个选择,你可以得到namespaceFXMLLoader,这是一个Map<String, Object>蕴含有所有的FXML的元素fx:idS(除其他事项外)。

因此,您可以执行以下操作:

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

另外,请注意

    Controller controller = new Controller();
    controller.setScene(scene);
Run Code Online (Sandbox Code Playgroud)

什么也没做 创建新的控制器与获取由控制器为您创建的控制器不同FXMLLoader。(无论如何,这都是多余的,您始终可以vBox.getScene()在控制器中进行操作以获取场景。)