2015-09-25 39 views
0

基本上,我需要從fxml文件中檢索VBox,並使用scene.lookup。 但是,如果我搜索它,它只是崩潰與NullPointerException。如果我搜索VBox,scene.lookup()返回null

所以我試圖打印什麼scene.lookup()發現,它只是發現null(杜),但我不明白爲什麼。

這是我的主類:

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> 
+0

您是否試過單步執行代碼?如果是這樣,它會崩潰在哪條線上? – StillLearnin

+0

@StillLearnin你不需要單步執行代碼。您可以從堆棧跟蹤中讀取它。但是,OP指出'scene.lookup(「#vBox」)正在返回null。 –

回答

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元素。只是爲了給你另外一個選擇,你可以從FXMLLoader得到namespace,這是一個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()以獲取該場景。)

+0

上帝,謝謝你,這實際上是非常翔實的! – Nightaye