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:
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.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.
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".
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.
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.
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.
@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.
Maintenant, vous pouvez facilement le faire avec Eclipse Suivez simplement ces étapes simples: