2015-09-29 3 views
1

J'ai deux fichiers fxml. Je les connecter avec une déclaration include:L'injection du contrôleur JavaFX ne fonctionne pas

Le fichier "principal" fxml ressemble à ce que:

<?import javafx.geometry.*?> 
// ... 

<BorderPane prefHeight="962" prefWidth="1280" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MyMainController"> 
    <center> 
     <SplitPane dividerPositions="0.63" BorderPane.alignment="CENTER"> 
      <items> 
       <fx:include source="AnotherFile.fxml" /> 
       // ... 
      </items> 
     </SplitPane> 
    </center> 
    <top> 
     // ... 
    </top> 
</BorderPane> 

Et le second (= "AnotherFile.fxml") comme ça:

<?import java.lang.*?> 
// ... 

<SplitPane dividerPositions="0.15" orientation="VERTICAL" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1"> 
    <items> 
     // ... 
     <Label fx:id="oneOfMyLabels" text="myText" GridPane.columnIndex="2" GridPane.rowIndex="1" /> 
    </items> 
</SplitPane> 

maintenant, je me sers des injections dans le "principal" -Controller application.MyMainController:

@FXML 
private Label oneOfMyLabels; 

Si j'exécute le contrôleur, j'obtiens une exception java.lang.NullPointerException, respectivement une . En mode de débogage, j'ai découvert que le Label injecté est null!

Maintenant, ma question: Impossible d'atteindre le MyMainController à partir du "fichier fxml principal" les composants du fichier fxml inclus ?? Dois-je utiliser un propre contrôleur sur chaque fichier fxml, s'il est inclus ou non ?!

Merci pour votre aide !!

Répondre

4

Vous devez avoir un contrôleur différent pour chaque fichier FXML, et les fx:id éléments non-notés de chaque fichier seront injectés dans l'instance correspondante du contrôleur.

Lorsque vous avez inclus les fichiers FXML, vous pouvez injecter le contrôleur pour le fichier inclus dans le contrôleur du fichier, y compris, en définissant un attribut fx:id sur l'élément fx:include:

« principale » fichier FXML:

<?import javafx.geometry.*?> 
// ... 

<BorderPane prefHeight="962" prefWidth="1280" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MyMainController"> 
    <center> 
     <SplitPane dividerPositions="0.63" BorderPane.alignment="CENTER"> 
      <items> 
       <fx:include fx:id="another" source="AnotherFile.fxml" /> 
       // ... 
      </items> 
     </SplitPane> 
    </center> 
    <top> 
     // ... 
    </top> 
</BorderPane> 

et dans le « contrôleur principal »:

public class MyMainController { 

    @FXML 
    private AnotherController anotherController ; 

    // ... 
} 

(la règle étant que le nom de domaine est la valeur de e e attribut fx:id avec "Controller" en annexe). Ici AnotherController est la classe de contrôleur pour AnotherFile.fxml.

Maintenant, vous pouvez, par exemple, exposer les données vous devez accéder au « contrôleur inclus »:

public class AnotherController { 

    @FXML 
    private Label oneOfMyLabels ; 

    public StringProperty textProperty() { 
     return oneOfMyLabels.textProperty(); 
    } 

    public final String getText() { 
     return textProperty().get(); 
    } 

    public final setText(String text) { 
     textProperty().set(text); 
    } 

    // ... 
} 

et votre contrôleur principal peut faire des choses comme

anotherController.setText(...); 

ce qui va bien sûr mettre à jour l'étiquette. Cela préserve l'encapsulation, de sorte que si vous choisissez d'utiliser un autre contrôle à la place d'une étiquette, ces modifications ne doivent pas se propager en dehors du contrôleur immédiat.

+0

Il faut se souvenir que l'élément racine du fichier fxml inclus doit contenir un propre attribut fx: controller! – mrbela

+0

Est-il possible d'injecter le 'MyMainController' dans le' AnotherController'? J'ai besoin d'invoquer une méthode dans le contrôleur principal hors du contrôleur secondaire ... – mrbela