web-dev-qa-db-fra.com

Puis-je générer automatiquement des classes de contrôleur à partir de FXML?

Si je comprends bien, lorsque vous utilisez FXML pour décrire une scène Java FX, la classe de contrôleur est écrite manuellement et ses variables membres et Les méthodes peuvent ensuite être référencées à partir du fichier .fxml. Lors du chargement de la scène à l'aide de FXMLLoader, les variables membres sont définies sur les éléments de scène correspondants et les méthodes sont câblées automatiquement aux événements correspondants. Cela fonctionne mais est très lourd car les changements doivent être effectués à deux endroits et les erreurs n'apparaîtront qu'au moment de l'exécution.

J'ai vu d'autres frameworks GUI qui vous permettent de générer à la place le contrôleur à partir d'une description de scène en tant que classe abstraite qui doit être implémentée pour accéder aux éléments de la scène et gérer les événements. Un exemple de ce que je veux dire:

Je créerais le fichier .fxml Suivant (par exemple en utilisant JavaFX Scene Builder):

<AnchorPane ... >
  <children>
     <Button fx:id="button" ... text="Button" onAction="#buttonPressed" />
  </children>
</AnchorPane>

Quelque part dans mon processus de construction, le fichier .Java Suivant serait créé (par exemple en utilisant un plugin Maven):

abstract class TestController {
    protected final Parent root;
    protected final Button button;

    {
        // Load test.fxml file
        // Assign scene elements to root and button
        // Attach event handler to the button that calls buttonClicked()
    }

    protected abstract void buttonClicked(ActionEvent event);
}

Je pourrais alors, éventuellement plusieurs fois, créer une implémentation concrète de ce contrôleur:

final class TestControllerImpl extends TestController {
    TestControllerImpl(String buttonLabel) {
        button.setText(buttonLabel);
    }

    @Override
    protected void buttonClicked(ActionEvent event) {
        button.setText("I've been clicked! What a great day!");
    }
}

Y a-t-il un projet dans le but de le faire? Ou y a-t-il un problème avec cette approche appliquée à FXML ?

Je vois les avantages suivants de cette approche:

  • Les déclarations des variables membres et des méthodes pour le contrôleur sont générées automatiquement.
  • Toutes les variables membres sont final et protected au lieu de non-final et soit public soit annotées.
  • De même pour les méthodes, elles sont protégées au lieu de public ou annotées.
  • Ne pas implémenter une méthode ou mal orthographier son nom entraînera une erreur de compilation.
  • La configuration par programmation de la scène peut être effectuée dans le constructeur au lieu d'une méthode initialize() car le constructeur s'exécutera après la scène a été chargée et ses éléments affectés aux variables membres.
16
Feuermurmel

Je ne sais rien qui fasse exactement ce que vous proposez dans votre question.

Il est probable que cette réponse finira probablement par être dépassée au fil du temps.

Autres technologies

JRuby réalise la plupart de vos avantages décrits en utilisant une approche légèrement différente - il utilise la magie de programmation dynamique de jRuby pour créer automatiquement Ruby membres de la classe à partir du FXML dynamiquement un runtime.

Tom Schindl a écrit un outil qui génère Java à partir de FXML. Parmi les approches répertoriées dans cette réponse, l'outil de Tom semble le plus proche de votre question.

Squelettes SceneBuilder

Un générateur de code similaire Java de FXML est disponible dans SceneBuilder View | Show Sample Controller Skeleton fonctionnalité, qui est décrite dans cette article de blog . Lorsque j'utilise SceneBuilder, j'utilise cette fonctionnalité tout le temps et j'essaie de garder mes contrôleurs vraiment légers afin qu'ils soient presque tous du code généré automatiquement à partir de la fonctionnalité squelette de SceneBuilder.

Cependant, il est légèrement ennuyeux car il ne permet pas une séparation nette du code généré du code écrit à la main, vous devez donc être prudent lorsque vous effectuez des mises à jour du FXML et que vous souhaitez générer un nouveau squelette et le copier-coller sur des parties de votre contrôleur existant (en plus c'est une opération manuelle légèrement sujette aux erreurs qui prend un peu de temps au développeur).

Code source pour SceneBuilder est disponible si vous voulez voir comment cela fonctionne.

Plugins d'outils de construction potentiels

Une telle fonctionnalité de génération de code pourrait constituer un ajout utile à certains des outils de construction existants dans l'écosystème JavaFX, tels que plug-in JavaFX Maven ou plug-in JavaFX Gradle (ou un autre plugin dans son propre droit).

Développement futur

Je pense qu'Oracle travaille également sur une extension de fonctionnalité pour FXML pour une future version de JavaFX (post Java 8) qui compile FXML directement en Java octet code ( fichiers de classe), en contournant l'étape Java code source. Ce type de fonctionnalité permettrait probablement d'obtenir la plupart des avantages décrits.

8
jewelsea

Ceci est désormais pris en charge dans SceneBuilder, NetBeans et Eclipse. Notez que cela fonctionne par défaut dans NetBeans et SceneBuilder, mais dans Eclipse, vous avez d'abord besoin du plugin clipse e (fx).

SceneBuilder: Avec un fichier FXML ouvert dans l'éditeur, entrez dans le menu pour sélectionner "Afficher" et "Afficher l'exemple de squelette de contrôleur".

Eclipse: ouvrez le fichier fxml afin que le contenu soit affiché dans le volet d'édition de code (vous devriez voir le fxml en XML clair avec mise en évidence de la syntaxe dans Eclipse, non rendu visuellement dans SceneBuilder). Faites un clic droit sur le code dans Eclipse et sélectionnez "Code" puis "Générer le contrôleur".

NetBeans: Dans NetBeans, c'est encore plus simple, faites un clic droit sur le fichier fxml dans l'explorateur de projet et sélectionnez "Make Controller".

9
Mishax

C'est possible avec NetBeans version 8.

Ouvrez FXML, accédez à Source et cliquez sur générer un contrôleur.

Edit: Maintenant, cela peut être fait dans n'importe quel IDE, Eclipse a besoin d'une pensée de plugin.

7
user3224416

Comme je le sais, il existe deux types de solutions dans les netbeans.

Tout d'abord, la fonction interne de Netbeans "Make Controller", que vous pouvez voir avec un clic droit de la souris sur le document fxml. il générera une classe de contrôleur qui fonctionnera avec FXMLLoader. Le contrôleur Java doit être indiqué dans le document fxml. (Panneau de gauche -> Contrôleur -> Classe du contrôleur)

Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

Deuxièmement, le plugin de netbeans "FXML 2 Java Converter", que vous pouvez installer à partir du menu (Outil -> Plugin -> Plugin disponible -> FXML 2 Java Converter ) et vous pouvez voir l'élément de menu "Générer une classe abstraite" avec un clic droit sur le document fxml. Il générera du code source à partir du document fxml et vous pouvez l'utiliser comme une classe abstraite sans utiliser FXMLLoader comme un projet JavaFX normal et non un projet JavaFXML.

1
Chun

Si vous utilisez IntelliJ ide, vous devrez peut-être essayer FXML Helper brancher.

Tout d'abord, installez le plugin à partir du Fichier | Paramètres ... | Plugins . Après l'installation, redémarrez l'ide, cliquez maintenant avec le bouton droit sur le document . Fxml et sélectionnez le FXML Helper menu. C'est tout.

0
ucMedia

@Feuermurmel
non, il n'y a aucun moyen de générer automatiquement la classe de contrôleur pour le fichier .fxml particula.
vous devez définir dynamiquement déclarer variable et méthode avec anotation @fxml et définir (lier) dans scence builder.

0
Maulik Patel

Maintenant, vous pouvez facilement le faire avec Eclipse Suivez simplement ces étapes simples:

  1. Accédez à votre fichier fxml pour lequel vous souhaitez créer un contrôleur
  2. Clic droit et source de clic
  3. Cliquez sur Générer le contrôleur

Cliquez ici pour voir l'image de la façon de le faire.

0