Solution à l'exception de chargement JavaFX FXML
- Raisons à l’origine de l’exception de chargement JavaFX FXML
- Solution à l’exception de chargement JavaFX FXML
Ce didacticiel explique les raisons à l’origine de l’exception de chargement JavaFX FXML et fournit une solution rapide.
Raisons à l’origine de l’exception de chargement JavaFX FXML
La première raison d’obtenir l’exception de chargement JavaFX FXML est lorsque le chemin d’accès à un fichier FXML n’est pas spécifié correctement à un chargeur. Le chemin /fxml/view.fxml
fait référence à un fichier view.fxml
dans un dossier nommé fxml
qui réside dans le dossier resources
, c’est-à-dire sur le classpath
.
L’appel getClass().getResource()
invoque un objet classloader
à l’exécution, qui recherche le classpath
d’une ressource qui lui est transmise. De cette façon, il trouvera le dossier fxml
et le fichier view.fxml
à l’intérieur de ce dossier.
La deuxième raison peut être d’avoir un ID de composant incompatible, ce qui signifie que nous avons peut-être mis à jour un ID de composant dans notre fichier Controller
mais que nous avons oublié de modifier cet ID dans le fichier FXML (ou vice-versa). Dans ce cas, le Contrôleur
ne serait pas en mesure de lier ce composant sur le fichier view.fxml
.
Voir le morceau suivant pour avoir une compréhension claire.
Sur le fichier Controller
:
@FXML
Button btnName1
Sur le fichier FXML View
:
fx:id="btnName_1"
Voici la solution à ces deux raisons.
Solution à l’exception de chargement JavaFX FXML
Pour exécuter cette application, nous utilisons Java 18, JavaFX 13 et NetBeans IDE version 13. Vous pouvez tous les utiliser selon votre choix.
Exemple de code (fichier view.fxml
, le fichier de vue) :
<!--Step1: XML declaration-->
<?xml version="1.0" encoding="UTF-8"?>
<!--Step 2: import necessary java types in FXML-->
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<!--Step 3: specify the FXML namespace-->
<AnchorPane prefHeight="300.0" prefWidth="400.0"
xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.mycompany.javafx_fxml_loadexception.viewController">
<!--Step 4: layout pane have children-->
<children>
<Button fx:id="btTest" layoutX="170.0"
layoutY="208.0" mnemonicParsing="false"
onAction="#onBtTestAction" text="Button" />
<Label layoutX="167.0" layoutY="126.0" text="Cick here!" />
</children>
</AnchorPane>
Voici l’explication étape par étape du code ci-dessus.
-
Nous écrivons une déclaration XML en décrivant la version et l’encodage.
-
Importez tous les types Java nécessaires dans FXML.
-
Nous utilisons la balise
AnchorPane
pour déclarer le préfixe d’espace de nomsfx
. Cette balise permet aux bords des nœuds enfants d’être ancrés au décalage à partir d’un bord du volet d’ancrage.S’il y a un rembourrage ou une bordure dans le volet d’ancrage, les décalages seront mesurés à partir des bords intérieurs de ces encarts. La balise
AnchorPane
a diverses propriétés énumérées ci-dessous avec une brève explication.- Les propriétés
prefHeight
etprefWidth
peuvent être utilisées pour remplacer la hauteur et la largeur préférées calculées de la région. - En FXML, le
fx:controller
est utilisé pour spécifier le contrôleur sur un élémentroot
. N’oubliez pas que nous sommes autorisés à avoir un contrôleur par document FXML et qu’il doit être spécifié sur l’élémentroot
.
Quel est l’élément
root
dans ce code ? La baliseAchnorPane
est l’élémentracine
de cet exemple de code qui est un objet de niveau supérieur dans un graphe d’objets du document FXML.Tous les éléments de l’interface utilisateur seront ajoutés à cet élément. De plus, nous devons également connaître les règles auxquelles un contrôleur doit satisfaire ; ces règles sont énumérées ci-dessous :
- Un contrôleur est instancié par le loader
FXML
. - Un contrôleur doit avoir le constructeur public
no-args
. Le chargeurFXML
serait incapable de l’instancier s’il n’est pas là, ce qui entraînerait une exception au moment du chargement. - Un contrôleur peut contenir des fonctions accessibles qui peuvent également être spécifiées comme gestionnaires d’événements dans le FXML.
- Le contrôleur
FXML
recherche automatiquement la ou les variables d’instance accessibles d’un contrôleur. Si le nom de la variable d’instance accessible correspond à l’attributfx:id
d’un élément, une référence d’objet du FXML sera automatiquement copiée dans une variable d’instance du contrôleur.
Cette fonctionnalité rendra les références des éléments de l’interface utilisateur dans le FXML accessibles au contrôleur. Ensuite, le contrôleur pourrait les utiliser.
- Un contrôleur peut aussi accéder à la fonction
initialize()
, qui ne doit pas accepter d’arguments et retourner le typevoid
. Une fois le processus de chargement du document FXML terminé, le chargeurFXML
appelle la fonctioninitialize()
.
- Les propriétés
-
Dans FXML, les volets de mise en page contiennent les enfants en tant qu’éléments enfants. Compte tenu des exigences du projet, nous pouvons ajouter des étiquettes, des boutons et d’autres éléments.
Exemple de code (classe viewController.java
, la classe contrôleur) :
// Step 1: replace this package name with your package name
package com.mycompany.javafx_fxml_loadexception;
// Step 2: import necessary libraries
import javafx.fxml.FXML;
import javafx.scene.control.Button;
// Step 3: viewController class
public class viewController {
// define button
@FXML private Button btTest;
// define the action when the button is clicked
@FXML
public void onBtTestAction() {
System.out.println("CLICK");
} // end onBtTestAction method
} // end viewController class
La classe viewController.java
est une classe contrôleur qui utilise l’annotation @FXML
sur certains membres. N’oubliez pas que cette annotation peut être utilisée sur les constructeurs et les classes.
A l’aide de cette annotation, nous précisons que le loader FXML
peut facilement accéder à ce membre même s’il est private
. Nous n’avons pas besoin d’utiliser l’annotation FXML
si le chargeur FXML
utilise un membre public
.
Cependant, utiliser @FXML
pour un membre public
ne génère aucune erreur. Il est donc bon d’annoter chaque membre.
Le FXML
suivant définit la fonction onBtTestAction()
d’une classe de contrôleur en tant que gestionnaire d’événements pour le Button
:
<Button fx:id="btTest" layoutX="170.0" layoutY="208.0" mnemonicParsing="false" onAction="#onBtTestAction" text="Button" />
Exemple de code (classe App.java
, la classe principale) :
// Step 1: replace the package name with your package name
package com.mycompany.javafx_fxml_loadexception;
// Step 2: import necessary libraries
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
// Step 3: primary launch class extending the Application class
public class App extends Application {
/**
*
* @param stage
*/
@Override
public void start(Stage stage) {
// load the view.fxml file, add it to the scene and show it
try {
Parent parent = FXMLLoader.load(getClass().getResource("/fxml/view.fxml"));
// create a scene
Scene scene = new Scene(parent);
// set scene to a stage
stage.setScene(scene);
// show the stage
stage.show();
} // end try
catch (IOException e) {
e.printStackTrace();
} // end catch
} // end start method
public static void main(String[] args) {
launch(args);
} // end main method
} // end App class
Le fichier principal étend la classe Application
et redéfinit sa méthode abstraite start()
. Dans la méthode start()
, nous chargeons le fichier view.fxml
, créons une scène, définissons cette scène sur une scène et affichons cette scène.
OUTPUT (imprime le mot CLICK
sur la console de l’IDE chaque fois que nous cliquons sur le Button
):
Vérifiez la capture d’écran suivante pour placer chaque fichier au bon emplacement :