web-dev-qa-db-fra.com

Comment connecter le contrôleur FX à l'application principale

J'ai une classe principale d'application et une classe fxmlController, mais je suis empêtré dans la connexion/l'organisation (je ne comprends pas comment ils sont appelés et comment je devrais les organiser pour rendre la logique métier connectée à l'interface graphique) la logique métier et l'interface graphique. Quelqu'un peut-il indiquer l'ordre dans lequel les fonctions suivantes sont appelées ou quelqu'un peut-il m'aider à les appeler?

Classe principale:

public void Main()        //constructor
public static void main() // our main
public void start()       //I don't know what it is, what purpose it has
                          // and where should be called
                          //Note: In main function there is a call as following

classe fxmlController:

public void initialize()  //I don't know what it is and what purpose it has
public fxmlController()   // which function should be called here....

REMARQUE: je connais FXMLLoader(); veuillez expliquer à quelqu'un

8
khan

Je pense à un fichier FXML et à son contrôleur correspondant comme une paire qui gère l'interface utilisateur. Dans les applications plus grandes, vous pouvez avoir plusieurs paires de contrôleurs FXML qui composent différentes parties de l'interface utilisateur. Au sein de chaque paire, le fichier FXML définit la disposition de l'interface utilisateur et le contrôleur définit la logique (c'est-à-dire qu'il traite généralement les entrées utilisateur, etc.).

Alors que vous avez dit que vous "connaissiez FXMLLoader", si vous comprenez que vous compreniez réellement certaines des autres choses que vous avez posées, alors:

L'interface utilisateur définie par un fichier FXML et son contrôleur est chargée en mémoire par un FXMLLoader. Dans la configuration la plus simple, le contrôleur est défini par un attribut fx:controller Dans l'élément racine du fichier FXML. Lorsque la méthode load() est appelée sur le FXMLLoader, elle:

  1. Charge le fichier FXML
  2. Crée une instance de la classe de contrôleur spécifiée par l'attribut fx:controller, En appelant son constructeur sans argument
  3. Définit la valeur de tout champ @FXML - annoté dans le contrôleur sur les éléments définis avec les attributs fx:id Correspondants
  4. Enregistre tous les gestionnaires d'événements mappés aux méthodes dans le contrôleur
  5. Appelle la méthode initialize() sur le contrôleur, s'il y en a une.

Remarquez l'ordre de ces événements: le constructeur est appelé avant le @FXML - les champs annotés sont injectés, mais la méthode initialize() est appelée après. Cela signifie que vous pouvez accéder (et configurer) et @FXML - champs annotés dans la méthode initialize(), mais pas dans le constructeur. Il est assez courant (au moins dans les applications simples) de ne définir aucun constructeur dans les classes de contrôleur et simplement d'utiliser la valeur par défaut.

Vous pouvez avoir autant de paires FXML/contrôleur dans votre application que vous en avez besoin. Chaque fichier FXML doit avoir sa propre classe de contrôleur. Vous pouvez charger un fichier FXML autant de fois que vous le souhaitez si vous voulez plusieurs instances de l'interface utilisateur qu'il définit: chaque fois que FXMLLoader créera pour vous une nouvelle instance de contrôleur qui est associée à l'élément d'interface utilisateur que vous avez chargé.

La sous-classe Application (vous l'avez appelée Main) représente l'ensemble de l'application. Vous ne devez avoir qu'une seule classe de ce type par application et une seule instance de celle-ci, qui est créée pour vous par la boîte à outils FX.

Lorsque vous démarrez une application FX (que je décrirai ci-dessous), la boîte à outils FX démarre. Ensuite, une instance de votre sous-classe Application est créée et sa méthode init() est appelée (si vous n'en définissez pas une, l'implémentation par défaut ne fait rien). Le thread d'application FX est alors démarré et la méthode start() de l'instance de Application est appelée sur ce thread.

Votre méthode start() devrait faire un travail assez minimal. En règle générale, il charge votre fichier fxml "principal", place l'interface utilisateur résultante dans une scène, place la scène sur la scène et affiche la scène. Toute la logique sera gérée par le contrôleur pour le fichier FXML, pas par la sous-classe Application.

Dans les applications plus avancées, vous pouvez démarrer certains services d'arrière-plan et/ou créer des modèles de données dans votre méthode init(), et les connecter au contrôleur dans la méthode start(), mais les idées ci-dessus sont les bases.

Le processus de démarrage réel peut se produire de plusieurs manières. Si vous utilisez Oracle JRE standard, lancez une sous-classe Application avec

Java Main

(où Main extends Application) provoquera le processus ci-dessus; en d'autres termes, la boîte à outils FX est démarrée, une instance de Main est créée, sa méthode init() est appelée et sa méthode start() est appelée sur le thread d'application FX .

D'autres environnements (en particulier les IDE) ne connaissent pas le processus de démarrage JavaFX et s'attendent à ce que la classe que vous exécutez ait une méthode public static void main(String[] args), comme toute classe d'application standard Java Java. Pour prendre en charge ces environnements, il est courant que votre sous-classe Application définisse une méthode main(...) qui appelle simplement launch(...) (une méthode statique héritée de Application La méthode launch force le toolkit FX à démarrer, etc. Elle ne peut être appelée qu'une seule fois pendant la durée de vie d'une application.

Alors maintenant, vous avez quelque chose comme:

package com.example ;

// imports...

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        // just load fxml file and display it in the stage:

        FXMLLoader loader = new FXMLLoader(getClass().getResource("mainUI.fxml"));
        Parent root = loader.load();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // main method to support non-JavaFX-aware environments:

    public static void main(String[] args) {
        // starts the FX toolkit, instantiates this class, 
        // and calls start(...) on the FX Application thread:
        launch(args); 
    }
}

Ensuite, vous auriez mainUI.fxml:

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

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import Java.util.ArrayList?>

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.MyController">
    <Label  fx:id="label1"/>
    <Label  fx:id="label2"/>
</VBox>

et le contrôleur

package com.example ;

// imports...

public class MyController {

    @FXML
    private Label label1 ;
    @FXML
    private Label label2 ;

    // called by the FXML loader after the labels declared above are injected:
    public void initialize() {

        // do initialization and configuration work...

        // trivial example, could also be done directly in the fxml:
        label1.setText("Foo");
        label2.setText("Bar");
    }
}
47
James_D

Le contrôleur est lié dans votre fichier fxml ou là où vous appelez la vue principale pour la première fois.

Vous pouvez donc utiliser l'attribut fx:controller Dans le xml ou la méthode FXMLLoader#setController() de votre lanceur.

2
antoniodvr