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

时间:2015-09-25 02:28:24

标签: 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);
    }
}

这是我的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>

1 个答案:

答案 0 :(得分:3)

首先,你根本不需要这样做。只需将VBox注入控制器,然后在那里做任何你需要做的事情:

public class Controller {

    @FXML
    private VBox vBox ;

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

直接解决您的问题:

在应用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"));
}

一般来说,查找不是很强大。如上所述,您应该只是访问控制器中的FXML元素。只是为了给您另外一个选项,您可以从namespace获取FXMLLoader,这是一个Map<String, Object>,其中包含FXML的所有fx:id个元素(其中)其他事情)。

所以你可以这样做:

    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()来获取场景。)