CHAPITRE 2.4

Intégration Eclipse ↔ FXML

Maîtriser l'intégration entre Eclipse et Scene Builder pour un workflow efficace
Dans cette section, vous allez apprendre à intégrer efficacement Eclipse et Scene Builder pour créer et modifier vos interfaces JavaFX. Vous découvrirez comment ouvrir des fichiers FXML depuis Eclipse, générer et lier des contrôleurs, et organiser correctement le dossier resources. Cette intégration est essentielle pour un workflow de développement fluide et productif.

2.4Intégration Eclipse ↔ FXML

2.4.1 – Ouvrir FXML depuis Eclipse

Pour travailler efficacement avec FXML et Scene Builder, il est important de savoir comment ouvrir et modifier des fichiers FXML depuis Eclipse. Cette section vous guide à travers le processus.

🔧 Configuration préalable : Lier Scene Builder à Eclipse

Avant de pouvoir ouvrir des fichiers FXML depuis Eclipse, vous devez configurer le chemin vers Scene Builder :

  1. Dans Eclipse, allez dans Window → Preferences (ou Eclipse → Preferences sur macOS)
  2. Dans le panneau de gauche, naviguez vers JavaFX
  3. Dans le champ Scene Builder executable, cliquez sur Browse...
  4. Sélectionnez le fichier exécutable de Scene Builder :
    • Windows : C:\Program Files\SceneBuilder\SceneBuilder.exe
    • macOS : /Applications/SceneBuilder.app/Contents/MacOS/SceneBuilder
    • Linux : /opt/scenebuilder/SceneBuilder
  5. Cliquez sur Apply and Close
Note : Si vous ne trouvez pas l'option JavaFX dans les préférences, assurez-vous que le plugin e(fx)clipse est bien installé (voir Chapitre 1.2.2).

📂 Créer un fichier FXML dans Eclipse

Pour créer un nouveau fichier FXML dans votre projet Eclipse :

  1. Faites un clic droit sur le package application (ou sur un dossier resources si vous l'avez créé)
  2. Sélectionnez New → File
  3. Donnez un nom au fichier avec l'extension .fxml (par exemple main.fxml)
  4. Cliquez sur Finish
Note : Par défaut, e(fx)clipse ne crée pas de dossier resources. Vous pouvez créer vos fichiers FXML directement dans le package application, ou créer manuellement un dossier resources dans src pour une meilleure organisation.
Convention de nommage : Utilisez des noms descriptifs en minuscules avec des tirets si nécessaire : accueil.fxml, formulaire-connexion.fxml, etc.

🚀 Ouvrir un fichier FXML avec Scene Builder

Une fois Scene Builder configuré, vous pouvez ouvrir un fichier FXML de plusieurs manières :

Méthode 1 : Clic droit dans Eclipse

  1. Dans Eclipse, faites un clic droit sur le fichier FXML
  2. Sélectionnez Open with Scene Builder
  3. Scene Builder s'ouvre avec le fichier chargé

Méthode 2 : Ouvrir avec Scene Builder par défaut

  1. Faites un clic droit sur le fichier FXML
  2. Sélectionnez Open With → Other...
  3. Choisissez Scene Builder
  4. Cochez Use it for all '.fxml' files pour en faire l'éditeur par défaut
  5. Cliquez sur OK
Astuce : Une fois configuré comme éditeur par défaut, un double-clic sur un fichier FXML l'ouvrira automatiquement dans Scene Builder.

🔄 Synchronisation Eclipse ↔ Scene Builder

Scene Builder et Eclipse se synchronisent automatiquement :

  • Sauvegarde dans Scene Builder : Quand vous sauvegardez dans Scene Builder (Ctrl+S), les modifications sont immédiatement visibles dans Eclipse
  • Actualisation dans Eclipse : Eclipse détecte automatiquement les changements et vous propose de recharger le fichier
  • Modification dans Eclipse : Si vous modifiez le FXML directement dans Eclipse, vous devrez recharger dans Scene Builder
Important : Évitez de modifier le même fichier FXML simultanément dans Eclipse et Scene Builder. Sauvegardez toujours avant de changer d'outil.

📝 Éditer le FXML directement dans Eclipse

Vous pouvez aussi éditer le FXML directement dans Eclipse si vous préférez :

  1. Faites un clic droit sur le fichier FXML
  2. Sélectionnez Open With → Text Editor (ou votre éditeur XML préféré)
  3. Modifiez le code XML directement
  4. Sauvegardez (Ctrl+S)
Conseil : L'édition directe du XML est utile pour des modifications mineures, mais pour des changements structurels importants, Scene Builder est plus pratique et moins sujet aux erreurs.

🔍 Vérifier la syntaxe FXML

Eclipse peut valider la syntaxe de vos fichiers FXML :

  • Validation automatique : Eclipse vérifie automatiquement la syntaxe XML
  • Erreurs visuelles : Les erreurs sont marquées avec un point rouge dans l'éditeur
  • Messages d'erreur : Passez la souris sur l'erreur pour voir le message détaillé
Astuce : Si vous avez des erreurs dans votre FXML, vérifiez que tous les imports sont corrects et que la structure XML est valide (balises fermées, attributs corrects, etc.).

2.4.2 – Génération et liaison du contrôleur

Scene Builder peut vous aider à générer automatiquement la structure de base d'un contrôleur et à le lier à votre FXML. Cette section vous montre comment procéder.

🎯 Déclarer le contrôleur dans le FXML

Avant de générer le contrôleur, vous devez d'abord le déclarer dans le FXML :

  1. Ouvrez votre fichier FXML dans Scene Builder
  2. Sélectionnez l'élément racine (VBox, BorderPane, etc.)
  3. Dans l'onglet Code de l'inspecteur, dans le champ Controller, entrez le nom complet de la classe (par exemple application.MonController)
  4. Sauvegardez le fichier
Note : Le nom du contrôleur doit inclure le package complet. Par exemple, si votre contrôleur est dans le package application et s'appelle MonController, entrez application.MonController.

📝 Créer le contrôleur manuellement

Pour créer un contrôleur dans Eclipse :

  1. Dans Eclipse, faites un clic droit sur le package application (ou le package où vous voulez créer le contrôleur)
  2. Sélectionnez New → Class
  3. Donnez un nom à la classe (par exemple MonController)
  4. Cliquez sur Finish
  5. Ajoutez les annotations et méthodes nécessaires

🔗 Générer automatiquement les fx:id

Scene Builder peut vous aider à générer automatiquement les références dans le contrôleur :

  1. Dans Scene Builder, définissez les fx:id pour vos composants (onglet Code)
  2. Sauvegardez le fichier FXML
  3. Dans Eclipse, créez votre classe contrôleur
  4. Ajoutez les champs correspondants avec l'annotation @FXML
Exemple : Si vous avez défini fx:id="labelMessage" dans Scene Builder, ajoutez dans votre contrôleur :
@FXML private Label labelMessage;

💻 Structure de base d'un contrôleur

Voici la structure de base que vous devez créer :

package application;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;

public class MonController {
    
    // Références aux composants du FXML
    @FXML
    private Label labelMessage;
    
    @FXML
    private TextField champNom;
    
    @FXML
    private Button btnValider;
    
    // Méthode d'initialisation (optionnelle)
    @FXML
    private void initialize() {
        // Code exécuté après le chargement du FXML
        // Par exemple : initialiser les valeurs par défaut
    }
    
    // Gestionnaires d'événements
    @FXML
    private void handleValider() {
        // Code exécuté quand on clique sur le bouton
    }
}

🔍 Vérifier la liaison FXML ↔ Contrôleur

Pour vérifier que la liaison fonctionne correctement :

  1. Vérifiez le package : Le package dans fx:controller doit correspondre au package de votre classe
  2. Vérifiez les fx:id : Les fx:id dans le FXML doivent correspondre aux noms des champs dans le contrôleur
  3. Vérifiez les méthodes : Les noms dans onAction doivent correspondre aux méthodes dans le contrôleur
  4. Testez l'application : Lancez l'application et vérifiez qu'il n'y a pas d'erreurs

⚠️ Erreurs courantes et solutions

Erreur 1 : Contrôleur introuvable

Symptôme : Erreur "Controller class not found"
Solution :

  • Vérifiez que le package dans fx:controller est correct
  • Vérifiez que la classe contrôleur existe et est compilée
  • Vérifiez que le nom de la classe est correct (sensible à la casse)

Erreur 2 : fx:id introuvable

Symptôme : Erreur "fx:id 'xxx' has not been injected"
Solution :

  • Vérifiez que le fx:id dans le FXML correspond exactement au nom du champ
  • Vérifiez que le champ est annoté @FXML
  • Vérifiez que le type du champ correspond au type du composant

Erreur 3 : Méthode d'événement introuvable

Symptôme : Erreur "Method 'xxx' not found"
Solution :

  • Vérifiez que la méthode existe dans le contrôleur
  • Vérifiez que la méthode est annotée @FXML
  • Vérifiez que le nom de la méthode correspond à celui dans onAction
Conseil : Si vous avez des erreurs, vérifiez d'abord la console Eclipse pour voir les messages d'erreur détaillés. Ils indiquent généralement exactement ce qui ne va pas.

📋 Exemple complet : Créer un contrôleur de A à Z

Voici un exemple complet de création d'un contrôleur :

Étape 1 : Créer le FXML dans Scene Builder

  1. Créez un fichier formulaire.fxml
  2. Ajoutez un VBox comme racine
  3. Ajoutez un Label avec fx:id="labelMessage"
  4. Ajoutez un TextField avec fx:id="champNom"
  5. Ajoutez un Button avec fx:id="btnValider" et onAction="handleValider"
  6. Dans l'onglet Code du VBox, définissez Controller : application.FormulaireController
  7. Sauvegardez

Étape 2 : Créer le contrôleur dans Eclipse

  1. Dans Eclipse, créez une nouvelle classe FormulaireController dans le package application
  2. Ajoutez les imports nécessaires
  3. Ajoutez les champs avec @FXML
  4. Ajoutez la méthode handleValider()

Étape 3 : Code du contrôleur

package application;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;

public class FormulaireController {
    
    @FXML
    private Label labelMessage;
    
    @FXML
    private TextField champNom;
    
    @FXML
    private Button btnValider;
    
    @FXML
    private void initialize() {
        // Initialisation : désactiver le bouton au départ
        btnValider.setDisable(true);
        
        // Activer le bouton seulement si le champ n'est pas vide
        champNom.textProperty().addListener((obs, oldVal, newVal) -> {
            btnValider.setDisable(newVal.trim().isEmpty());
        });
    }
    
    @FXML
    private void handleValider() {
        String nom = champNom.getText();
        if (!nom.trim().isEmpty()) {
            labelMessage.setText("Bonjour, " + nom + " !");
            champNom.clear();
        }
    }
}

Étape 4 : Charger le FXML dans Main.java

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        // Charger le fichier FXML
        FXMLLoader loader = new FXMLLoader(getClass().getResource("formulaire.fxml"));
        VBox root = loader.load();
        
        // Créer la Scene
        Scene scene = new Scene(root, 400, 300);
        
        // Afficher
        primaryStage.setScene(scene);
        primaryStage.setTitle("Mon Formulaire");
        primaryStage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}
Résultat : Quand vous lancez l'application, le formulaire s'affiche. Quand vous tapez dans le champ et cliquez sur "Valider", le message change pour afficher "Bonjour, [nom] !".
📦 Projet d'exemple : Génération et liaison du contrôleur

Ce projet illustre la création complète d'un contrôleur lié à un fichier FXML :
  • Fichier FXML formulaire.fxml avec fx:controller déclaré
  • Composants avec fx:id : labelMessage, champNom, btnValider
  • Contrôleur FormulaireController avec annotations @FXML
  • Méthode initialize() pour l'initialisation
  • Gestionnaire d'événement handleValider() pour le bouton
  • Liaison complète FXML ↔ Contrôleur fonctionnelle
📥 Télécharger le projet

2.4.3 – Organisation du dossier resources

Une bonne organisation de vos fichiers est essentielle pour maintenir un projet JavaFX propre et facile à maintenir. Cette section vous présente les bonnes pratiques pour organiser le dossier resources.

📁 Structure par défaut vs Structure recommandée

Structure par défaut d'e(fx)clipse

Quand vous créez un projet JavaFX avec e(fx)clipse, la structure par défaut est :

src/
└── application/
    ├── Main.java          # Classe principale
    ├── application.css    # Fichier CSS (créé automatiquement)
    └── (vos fichiers FXML ici si vous les créez)
Note : Par défaut, e(fx)clipse ne crée pas de dossier resources. Les fichiers CSS et FXML peuvent être placés directement dans le package application.

Structure recommandée (avec dossier resources)

Pour une meilleure organisation, vous pouvez créer manuellement un dossier resources dans src et le configurer comme Source Folder :

src/
├── application/
│   ├── Main.java
│   ├── AccueilController.java
│   ├── ProfilController.java
│   └── ...
└── resources/             # Dossier à créer manuellement (Source Folder)
    ├── main.fxml          # Fichier FXML principal
    ├── accueil.fxml       # Fichier FXML pour l'écran d'accueil
    ├── profil.fxml        # Fichier FXML pour l'écran de profil
    ├── style.css          # Fichier CSS principal
    ├── theme-light.css    # Thème clair
    ├── theme-dark.css     # Thème sombre
    ├── images/            # Dossier pour les images
    │   ├── logo.png
    │   ├── icon.png
    │   └── ...
    └── styles/            # Dossier pour organiser les CSS
        └── style.css      # Exemple : CSS dans un sous-dossier
    └── fonts/             # Dossier pour les polices personnalisées
        └── custom-font.ttf
📦 Projet d'exemple : Organisation simple avec resources dans src/

Ce projet illustre la structure simple avec le dossier resources dans src/ :
  • Structure : src/resources/ avec sous-dossiers images/ et styles/
  • Fichier FXML dans src/resources/main.fxml
  • CSS dans src/resources/styles/style.css (référencé avec @styles/style.css dans le FXML)
  • Images dans src/resources/images/logo.png (référencé avec @images/logo.png dans le FXML)
  • Chargement du FXML avec getResource("/resources/main.fxml") (le / indique la racine du classpath)
  • Le dossier src/resources peut être configuré comme Source Folder dans .classpath pour utiliser le chemin absolu
📥 Télécharger le projet

📂 Organisation par fonctionnalité

Pour des projets plus complexes, vous pouvez organiser par fonctionnalité :

resources/
├── vues/                  # Tous les fichiers FXML
│   ├── accueil.fxml
│   ├── profil.fxml
│   ├── parametres.fxml
│   └── ...
├── styles/                # Tous les fichiers CSS
│   ├── style.css
│   ├── theme-light.css
│   ├── theme-dark.css
│   └── components/
│       ├── buttons.css
│       └── forms.css
├── images/                # Images
│   └── ...
└── fonts/                 # Polices
    └── ...
Avantage : Cette organisation facilite la navigation et la maintenance, surtout pour des projets avec beaucoup de fichiers.

Configuration importante : Le dossier resources n'est pas créé automatiquement par e(fx)clipse. Vous devez :
  1. Créer manuellement le dossier resources dans src
  2. Le configurer comme Source Folder : clic droit sur resourcesBuild Path → Use as Source Folder
  3. Une fois configuré, il apparaîtra comme un Source Folder dans votre projet et vous pourrez utiliser les chemins absolus avec / (ex: /main.fxml)

🔗 Charger les fichiers depuis des sous-dossiers

Si vous organisez vos fichiers en sous-dossiers, vous devez adapter les chemins dans votre code :

Charger un FXML depuis un sous-dossier

Si vous utilisez un dossier resources configuré comme Source Folder :

// FXML dans src/resources/vues/accueil.fxml
// Le / au début indique la racine du classpath (resources devient partie du classpath)
FXMLLoader loader = new FXMLLoader(getClass().getResource("/vues/accueil.fxml"));
VBox root = loader.load();

Si vos fichiers sont dans le package application :

// FXML dans src/application/vues/accueil.fxml
// Pas de / au début : chemin relatif au package de la classe
FXMLLoader loader = new FXMLLoader(getClass().getResource("vues/accueil.fxml"));
VBox root = loader.load();
Rappel : Quand resources est configuré comme Source Folder, il devient partie du classpath. Le chemin /vues/accueil.fxml cherche dans resources/vues/accueil.fxml. Sans le /, le chemin est relatif au package de la classe appelante.

Lier un CSS depuis un sous-dossier

Si vous utilisez un dossier resources configuré comme Source Folder :

<!-- CSS dans src/resources/styles/style.css -->
<!-- Le @/ indique la racine du classpath (resources) -->
<VBox stylesheets="@/styles/style.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml/1">
   <!-- Contenu -->
</VBox>

Si vos fichiers sont dans le package application :

<!-- CSS dans src/application/styles/style.css -->
<!-- Le @ indique un chemin relatif au package -->
<VBox stylesheets="@styles/style.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml/1">
   <!-- Contenu -->
</VBox>
Note : Le @ dans FXML indique un chemin relatif. Si le CSS est dans resources (Source Folder), utilisez @/ pour indiquer la racine du classpath. Si le CSS est dans le même package que le FXML, utilisez simplement @ suivi du chemin relatif. Dans le projet d'exemple Chapitre2_4_3_OrganisationResources, le CSS est référencé avec @styles/style.css car il est dans resources/styles/style.css.

📋 Bonnes pratiques d'organisation

1. Nommage des fichiers

  • FXML : Utilisez des noms en minuscules avec des tirets si nécessaire : formulaire-connexion.fxml
  • CSS : Utilisez des noms descriptifs : style.css, theme-dark.css
  • Images : Utilisez des noms clairs : logo.png, icone-bouton.png

2. Regrouper les fichiers liés

  • Placez les fichiers FXML, CSS et contrôleurs liés dans le même package ou dossier
  • Utilisez des noms cohérents : accueil.fxmlAccueilController.java

3. Séparer les ressources par type

  • Créez des dossiers séparés pour les images, les polices, les sons, etc.
  • Évitez de mélanger différents types de fichiers dans le même dossier

4. Documenter la structure

  • Créez un fichier README.md dans le dossier resources pour documenter l'organisation
  • Indiquez où se trouvent les différents types de fichiers

🎯 Exemple : Structure pour une application complète

Voici un exemple de structure pour une application avec plusieurs écrans :

src/
└── application/
    ├── Main.java
    ├── controllers/
    │   ├── AccueilController.java
    │   ├── ProfilController.java
    │   └── ParametresController.java
    └── models/
        └── Utilisateur.java

resources/
├── vues/
│   ├── accueil.fxml
│   ├── profil.fxml
│   └── parametres.fxml
├── styles/
│   ├── style.css
│   ├── theme-light.css
│   └── theme-dark.css
├── images/
│   ├── logo.png
│   ├── icones/
│   │   ├── home.png
│   │   └── settings.png
│   └── avatars/
│       └── default.png
└── fonts/
    └── custom-font.ttf

📝 Charger les ressources dans le code

Voici comment charger les différents types de ressources :

Charger un FXML

Avec dossier resources :

// Depuis src/resources/vues/accueil.fxml
FXMLLoader loader = new FXMLLoader(getClass().getResource("/vues/accueil.fxml"));
VBox root = loader.load();

Dans le package application :

// Depuis src/application/vues/accueil.fxml
FXMLLoader loader = new FXMLLoader(getClass().getResource("vues/accueil.fxml"));
VBox root = loader.load();

Charger une image

Avec dossier resources :

// Depuis src/resources/images/logo.png
Image logo = new Image(getClass().getResourceAsStream("/images/logo.png"));
ImageView imageView = new ImageView(logo);

Dans le package application :

// Depuis src/application/images/logo.png
Image logo = new Image(getClass().getResourceAsStream("images/logo.png"));
ImageView imageView = new ImageView(logo);

Charger un CSS

Avec dossier resources :

// Depuis src/resources/styles/style.css
scene.getStylesheets().add(getClass().getResource("/styles/style.css").toExternalForm());

Dans le package application :

// Depuis src/application/styles/style.css
scene.getStylesheets().add(getClass().getResource("styles/style.css").toExternalForm());

Charger une police

Avec dossier resources :

// Depuis src/resources/fonts/custom-font.ttf
Font customFont = Font.loadFont(getClass().getResourceAsStream("/fonts/custom-font.ttf"), 16);

Dans le package application :

// Depuis src/application/fonts/custom-font.ttf
Font customFont = Font.loadFont(getClass().getResourceAsStream("fonts/custom-font.ttf"), 16);
Note : Utilisez getResource() pour les fichiers texte (FXML, CSS) et getResourceAsStream() pour les fichiers binaires (images, polices). Le / au début du chemin indique la racine de src (pour le dossier resources), tandis que sans /, le chemin est relatif au package de la classe.

📥 Projet d'exemple

Pour voir un exemple concret d'organisation avec le dossier resources, vous pouvez télécharger ce projet Eclipse :

📦 Projet d'exemple : Organisation du dossier resources

Ce projet illustre la structure recommandée avec un dossier resources configuré comme Source Folder :
  • Structure : resources/ à la racine du projet (au même niveau que src/) avec sous-dossiers images/ et styles/
  • Fichier FXML dans resources/main.fxml
  • CSS dans resources/styles/style.css (référencé avec @styles/style.css dans le FXML)
  • Images dans resources/images/logo.png (référencé avec @images/logo.png dans le FXML)
  • Chargement du FXML avec getResource("/main.fxml") (le / indique la racine du classpath)
  • Le dossier resources est configuré comme Source Folder dans .classpath (ligne 4 : <classpathentry kind="src" path="resources"/>)
📥 Télécharger le projet

⚠️ Erreurs courantes

Erreur 1 : Fichier introuvable

Symptôme : NullPointerException ou "Resource not found"
Solution :

  • Vérifiez que le fichier existe bien (dans src/application/ ou src/resources/)
  • Vérifiez que le chemin est correct (sensible à la casse)
  • Vérifiez que le fichier est bien inclus dans le build (dans les propriétés du projet Eclipse)
  • Si vous utilisez un dossier resources : Assurez-vous qu'il est bien dans src et qu'il est configuré comme Source Folder (clic droit → Build Path → Use as Source Folder). Vérifiez dans .classpath qu'il y a une entrée <classpathentry kind="src" path="resources"/>

Erreur 2 : Chemin incorrect

Symptôme : Le fichier n'est pas trouvé malgré qu'il existe
Solution :

  • Si le fichier est dans le package application : Utilisez un chemin relatif sans / au début (ex: "main.fxml" ou "vues/accueil.fxml")
  • Si le fichier est dans resources (Source Folder) : Utilisez / au début pour indiquer la racine du classpath (ex: "/main.fxml" ou "/vues/accueil.fxml"). Le / cherche à la racine du classpath, et comme resources est un Source Folder, il fait partie du classpath.
  • Vérifiez les séparateurs de dossier : utilisez / même sur Windows
  • Important : Assurez-vous que resources est bien configuré comme Source Folder, sinon les chemins avec / ne fonctionneront pas
Conseil : Pour éviter les erreurs de chemin, utilisez des chemins relatifs simples et testez toujours que vos ressources se chargent correctement avant de continuer le développement.

📋 Checklist d'organisation

Utilisez cette checklist pour vérifier que votre projet est bien organisé :

  • ✅ Les fichiers sont organisés de manière logique (dans application ou dans resources si créé)
  • ✅ Les fichiers FXML sont regroupés dans un dossier dédié
  • ✅ Les fichiers CSS sont regroupés dans un dossier dédié
  • ✅ Les images sont dans un dossier séparé
  • ✅ Les noms de fichiers sont cohérents et descriptifs
  • ✅ Les chemins dans le code correspondent à la structure réelle (avec ou sans / selon l'emplacement)
  • ✅ Toutes les ressources sont accessibles depuis le code
Prochaine étape : Maintenant que vous maîtrisez FXML, Scene Builder et CSS, vous êtes prêt à passer au Chapitre 3 pour apprendre à utiliser les différents layouts (VBox, HBox, BorderPane, etc.) pour créer des interfaces plus complexes !