2017-04-02 28 views
0

我正在製作一個應用程序,其中的PuzzleBlocks是在5x5矩形的網格中構建的。此前手動添加控制器時FXML對象上的nullPointerException

@Override 
    public void start(Stage primaryStage) throws Exception { 
     FXMLLoader baseViewLoader = new FXMLLoader(getClass().getResource("Views/BaseView.fxml")); 
     baseViewLoader.setLocation(getClass().getResource("Views/BaseView.fxml")); 
     baseViewLoader.setController(new DockViewController()); 
     Parent root = baseViewLoader.load(); 

     FXMLLoader dockLoader = new FXMLLoader(getClass().getResource("Views/DockView.fxml")); 
     dockLoader.setLocation(getClass().getResource("Views/DockView.fxml")); 
     dockLoader.setController(new DockViewController()); 
     Parent dockView = dockLoader.load(); 

     primaryStage.setResizable(false); 
     primaryStage.sizeToScene(); 

     primaryStage.setTitle("Tiles 2059275"); 

     Scene gameScene = new Scene(root); 

     primaryStage.setScene(gameScene); 

     primaryStage.show(); 

     new GameController(); 
    } 

現在,當它是通過經.fxml文件已宣佈這段代碼在控制器完成的:我從宣佈FX搬走:控制器在.fxml文件,並在主,而不是這樣做我DockViewController的初始化會正常工作:發生

@FXML 
    StackPane dockStackPane; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     for (int i = 0; i < 5; i++) { 
      for (int j = 0; j < 5; j++) { 
       tile1 = createSquare(Color.GREY); 
       tile2 = createSquare(Color.GREY); 
       tile3 = createSquare(Color.GREY); 

       tile1.setTranslateX(32 * (i) - 176); 
       tile1.setTranslateY(32 * (j) - 48); 

       tile2.setTranslateX(32 * (i) - 16); 
       tile2.setTranslateY(32 * (j) - 48); 

       tile3.setTranslateX(32 * (i) + 144); 
       tile3.setTranslateY(32 * (j) - 48); 

       dockStackPane.getChildren().add(tile1); 
       dockStackPane.getChildren().add(tile2); 
       dockStackPane.getChildren().add(tile3); 

       puzzleBlock1.add(tile1); 
       puzzleBlock2.add(tile2); 
       puzzleBlock3.add(tile3); 
      } 
     } 
     System.out.println("Ini test"); 
    } 

誤差在dockStackPane.getChildren().add(tile1);因爲dockStackPane爲空。如果我手動刪除在我的Main中添加控制器並返回在FXML文件中添加具有fx:controller的控制器,它可以正常工作。但後來我沒有提及我的控制器。

DockView.fxml

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

<?import javafx.scene.layout.Pane?> 
<?import javafx.scene.layout.StackPane?> 

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="128.0" prefWidth="384.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 
    <children> 
     <StackPane fx:id="dockStackPane" prefHeight="128.0" prefWidth="384.0" /> 
    </children> 
</Pane> 

而且DockView包括在基本視點

+0

@Fabian'''@FXML StackPane dockStackPane;''當我嘗試使用它時,返回null,我手動分配了Controller。如果我在視圖中通過fx:controller添加控制器,那麼它確實有效。但後來我沒有參考我的DockViewController –

+0

爲什麼你對兩個控制器使用相同的控制器類?兩個FXML文件都有一個'dockStackPane'嗎? 'baseViewLoader.load()'或'dockLoader.load()'過程中發生異常嗎? –

+0

@James_D在dockLoader.load()期間,因爲它正在嘗試初始化。再一次,當我在DockView.fxml中將窗格元素上的fx:controller設置爲DockViewController時,此代碼正常工作。 –

回答

0

多虧了評論我的問題我能解決它的解決方案是增加一個FX:id來在包括我BaseView.fxml:

<fx:include fx:id="includedDockView" source="DockView.fxml" /> 

確保包括那麼,元件具有FX:控制器設置爲這樣:

<Pane fx:id="dockPane" fx:controller="tiles.Controllers.DockViewController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="128.0" prefWidth="384.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 

然後在BaseViewController你可以這樣做:

@FXML 
    private DockViewController includedDockViewController; 

    public DockViewController getDockViewController() { 
     return includedDockViewController; 
    } 

,並在主可以通過基本視點這樣:

public void start(Stage primaryStage) throws Exception { 
    FXMLLoader baseViewLoader = new FXMLLoader(getClass().getResource("Views/BaseView.fxml")); 
    baseViewLoader.setLocation(getClass().getResource("Views/BaseView.fxml")); 
    baseViewLoader.setController(new BaseViewController()); 
    Parent root = baseViewLoader.load(); 

    primaryStage.setResizable(false); 
    primaryStage.sizeToScene(); 

    primaryStage.setTitle("Tiles 2059275"); 

    Scene gameScene = new Scene(root); 

    primaryStage.setScene(gameScene); 

    primaryStage.show(); 

    new GameController(baseViewLoader); 
} 
+0

該代碼的最後一行不做任何事情:除此之外,這看起來像正確的方法。 –