2017-04-02 2 views
0

Je crée une application dans laquelle les PuzzleBlocks sont construits dans une grille de rectangles 5x5. Je suis passé loin de déclarer fx: contrôleur dans le fichier .fxml et au lieu fait cela dans le principal:nullPointerException sur un objet FXML lors de l'ajout manuel de contrôleurs

@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(); 
    } 

Maintenant auparavant quand il a été fait via le contrôleur ayant déclaré via le fichier .fxml ce morceau de code Initialize de mon DockViewController fonctionnerait correctement:

@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"); 
    } 

l'erreur se produit à dockStackPane.getChildren().add(tile1); parce dockStackPane est nulle. Si je supprime manuellement en ajoutant les contrôleurs dans mon Main et que je reviens à ajouter les contrôleurs avec fx: controller dans le fichier FXML cela fonctionne correctement. Mais je n'ai pas de référence à mon contrôleur.

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> 

Et le DockView est inclus dans les BaseView

+0

@Fabian '' '@FXML StackPane dockStackPane,' ' 'renvoie null lorsque j'essaie de l'utiliser maintenant que j'ai assigné manuellement le contrôleur. Si j'ajoute plutôt le contrôleur via fx: controller dans la vue, alors ça marche. Mais alors je n'ai pas de référence à mon DockViewController –

+0

Pourquoi utilisez-vous la même classe de contrôleur pour les deux contrôleurs? Les deux fichiers FXML ont-ils un dockStackPane? L'exception se produit-elle pendant 'baseViewLoader.load()' ou 'dockLoader.load()'? –

+0

@James_D Pendant dockLoader.load() parce que c'est quand il essaie d'initialiser. Encore une fois quand j'avais fx: controller réglé sur l'élément volet à DockViewController dans DockView.fxml ce code fonctionnait correctement. –

Répondre

0

Merci aux commentaires à ma question, j'ai pu travailler dehors la solution est d'ajouter fx: id l'inclure dans mon BaseView.fxml:

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

Assurez-vous que l'élément include a alors fx: contrôleur défini comme ceci:

<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"> 

Ensuite, dans le BaseViewController vous pouvez faire:

@FXML 
    private DockViewController includedDockViewController; 

    public DockViewController getDockViewController() { 
     return includedDockViewController; 
    } 

Et dans la principale, vous pouvez passer le BaseView en tant que tel:

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

La dernière ligne de ce code ne fait rien: sauf que cela ressemble à la bonne approche. –