JavaFX
Créez des interfaces graphiques riches et interactives
JavaFX est une boîte à outils puissante pour développer des applications de bureau avec des interfaces graphiques (GUI) en Java. Imaginez des applications avec des fenêtres, des boutons, des menus, etc. : c'est ce que JavaFX permet de créer !
Pourquoi choisir JavaFX ?
- Multiplateforme : Vos applications fonctionneront sur différents systèmes d'exploitation (Windows, macOS, Linux) sans modification.
- Richesse de composants : JavaFX offre une large gamme de composants d'interface utilisateur (boutons, zones de texte, listes, etc.) pour construire des interfaces attrayantes et fonctionnelles.
- Séparation de la logique et de l'interface : Vous pouvez concevoir l'apparence de votre application (l'interface) indépendamment du code qui gère son fonctionnement (la logique).
- Intégration avec Java : JavaFX s'intègre parfaitement avec le langage Java, ce qui facilite l'apprentissage et l'utilisation pour les développeurs Java.
Comment créer des interfaces avec JavaFX ?
Il existe deux approches principales pour créer des interfaces JavaFX :
- Fichiers FXML : Vous pouvez décrire l'interface dans un fichier XML (FXML), puis charger ce fichier dans votre application Java. Cette approche est idéale pour séparer la conception de l'interface du code. Des outils comme Scene Builder facilitent la création de fichiers FXML.
- Code Java : Vous pouvez créer l'interface directement dans votre code Java en utilisant les classes et les composants de JavaFX. Cette approche est plus adaptée pour les interfaces simples ou lorsque vous avez besoin de plus de contrôle sur la création des éléments.
Ce cours se concentrera sur la création d'interfaces directement en code Java.
Les bases de JavaFX : Stage, Scene et Node
Pour comprendre comment construire une interface JavaFX, il est essentiel de connaître trois concepts clés :
- Stage : C'est la fenêtre principale de votre application. Imaginez-le comme le cadre qui contient tout le reste.
- Scene : C'est le contenu de votre fenêtre (le Stage). Une scène contient tous les éléments graphiques (boutons, zones de texte, etc.).
- Node : C'est un élément graphique individuel dans votre scène. Un bouton, une zone de texte, une image, etc., sont tous des Nodes.
Schéma de l'architecture JavaFX
Stage (Fenêtre)
└── Scene (Contenu de la fenêtre)
└── Node (Éléments graphiques)
├── Button
├── TextField
├── Label
└── ...
Exemple minimal (fenêtre avec un texte)
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloJavaFX extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Bonjour JavaFX !");
StackPane root = new StackPane(label);
Scene scene = new Scene(root, 300, 150);
primaryStage.setTitle("Hello JavaFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Idée clé : un Label est un Node, placé dans un StackPane, lui‑même dans une Scene.
Exemple de code JavaFX (bouton avec action)
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MonApplicationJavaFX extends Application {
@Override
public void start(Stage primaryStage) {
// Création d'un label
Label label = new Label("Aucun clic");
// Création d'un bouton
Button bouton = new Button("Cliquez ici !");
// Action du bouton
bouton.setOnAction(e -> label.setText("Bouton cliqué !"));
// Création d'un conteneur (StackPane) pour organiser les éléments
StackPane root = new StackPane();
root.getChildren().addAll(label, bouton);
// Création d'une scène (Scene) avec le conteneur et les dimensions
Scene scene = new Scene(root, 300, 200);
// Configuration du Stage (fenêtre)
primaryStage.setTitle("Mon application JavaFX");
primaryStage.setScene(scene); // Ajout de la scène au Stage
primaryStage.show(); // Affichage de la fenêtre
}
public static void main(String[] args) {
launch(args);
}
}
Explication du code
Application: La classe principale de votre application JavaFX doit hériter de la classeApplication.start(Stage primaryStage): Cette méthode est appelée au démarrage de l'application. Le paramètreprimaryStagereprésente la fenêtre principale.Button: Création d'un bouton avec le texte "Cliquez ici !".StackPane: Un conteneur qui permet d'organiser les éléments graphiques. Ici, il est utilisé pour centrer le bouton dans la fenêtre.Scene: Création d'une scène avec le conteneur et les dimensions de la fenêtre.primaryStage.setTitle(): Définit le titre de la fenêtre.primaryStage.setScene(): Ajoute la scène (le contenu) à la fenêtre (le Stage).primaryStage.show(): Affiche la fenêtre.launch(args): Lance l'application JavaFX.
Séparer les layouts et les contrôles d'interface
En JavaFX, tout est un Node, mais on distingue deux grandes familles :
1) Layouts (conteneurs)
Ils organisent les éléments à l'écran (placement, espacement, alignement).
Exemples courants :
- VBox / HBox : alignement vertical / horizontal
- BorderPane : régions haut/bas/gauche/droite/centre
- GridPane : grille (formulaires)
- StackPane : empilement (centre par défaut)
- AnchorPane : positions ancrées
- FlowPane / TilePane : disposition fluide / en tuiles
2) Contrôles d'interface (UI Controls)
Ils affichent l'information ou interagissent avec l'utilisateur.
Exemples courants :
- Label : texte statique
- Button : action
- TextField / PasswordField : saisie courte
- TextArea : saisie longue
- CheckBox / RadioButton : choix
- ComboBox / ChoiceBox : listes déroulantes
- ListView / TableView : listes et tableaux
- Slider / ProgressBar : valeurs et progression
Idée clé : un layout contient des contrôles (ex. VBox avec des Button et TextField).
Les différents types de layouts (conteneurs)
JavaFX offre plusieurs types de conteneurs pour organiser vos éléments graphiques. Voici les principaux :
VBox - Disposition verticale
Le VBox organise les éléments verticalement, les uns en dessous des autres.
Schéma visuel :
┌──────────────┐
│ [Label] │
│ [Btn 1] │
│ [Btn 2] │
│ [Btn 3] │
└──────────────┘
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class VBoxExample extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Bienvenue dans JavaFX");
Button btn1 = new Button("Bouton 1");
Button btn2 = new Button("Bouton 2");
Button btn3 = new Button("Bouton 3");
VBox vbox = new VBox(10); // Espacement de 10 pixels entre les éléments
vbox.getChildren().addAll(label, btn1, btn2, btn3);
Scene scene = new Scene(vbox, 300, 200);
primaryStage.setTitle("Exemple VBox");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Résultat visuel : Une fenêtre avec un label en haut, suivi de trois boutons empilés verticalement avec un espacement de 10 pixels entre chaque élément.
HBox - Disposition horizontale
Le HBox organise les éléments horizontalement, côte à côte.
Schéma visuel :
┌─────────────────────────────────┐
│ [Précédent] [Suivant] [Annuler] │
└─────────────────────────────────┘
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class HBoxExample extends Application {
@Override
public void start(Stage primaryStage) {
Button btn1 = new Button("Précédent");
Button btn2 = new Button("Suivant");
Button btn3 = new Button("Annuler");
HBox hbox = new HBox(15); // Espacement de 15 pixels
hbox.getChildren().addAll(btn1, btn2, btn3);
Scene scene = new Scene(hbox, 400, 100);
primaryStage.setTitle("Exemple HBox");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Résultat visuel : Une fenêtre avec trois boutons alignés horizontalement avec un espacement de 15 pixels entre chacun.
BorderPane - Disposition en régions
Le BorderPane divise la fenêtre en 5 régions : haut (top), bas (bottom), gauche (left), droite (right) et centre (center).
Schéma visuel :
┌───────────── Top ─────────────┐
│ (Header) │
├──── Left ──┬── Center ────────┤
│ │ │
│ │ │
├────────────┴─ Bottom ─────────┤
│ (Footer) │
└───────────────────────────────┘
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class BorderPaneExample extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane();
// Haut : barre de menu
Label titre = new Label("Éditeur de texte");
borderPane.setTop(titre);
// Centre : zone de texte
TextArea textArea = new TextArea();
borderPane.setCenter(textArea);
// Bas : boutons d'action
HBox boutonsBar = new HBox(10);
Button btnSave = new Button("Enregistrer");
Button btnOpen = new Button("Ouvrir");
Button btnQuit = new Button("Quitter");
boutonsBar.getChildren().addAll(btnSave, btnOpen, btnQuit);
borderPane.setBottom(boutonsBar);
Scene scene = new Scene(borderPane, 500, 400);
primaryStage.setTitle("Exemple BorderPane");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Résultat visuel : Une fenêtre ressemblant à un éditeur de texte avec un titre en haut, une grande zone de texte au centre, et trois boutons alignés horizontalement en bas.
GridPane - Disposition en grille
Le GridPane organise les éléments dans une grille (lignes et colonnes), idéal pour les formulaires.
Schéma visuel :
┌───────────────┬───────────────┐
│ Nom : │ [__________] │
├───────────────┼───────────────┤
│ Prénom : │ [__________] │
├───────────────┼───────────────┤
│ Email : │ [__________] │
└───────────────┴───────────────┘
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class GridPaneExample extends Application {
@Override
public void start(Stage primaryStage) {
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(8); // Espacement vertical
grid.setHgap(10); // Espacement horizontal
// Ligne 0
Label labelNom = new Label("Nom :");
GridPane.setConstraints(labelNom, 0, 0);
TextField textNom = new TextField();
GridPane.setConstraints(textNom, 1, 0);
// Ligne 1
Label labelPrenom = new Label("Prénom :");
GridPane.setConstraints(labelPrenom, 0, 1);
TextField textPrenom = new TextField();
GridPane.setConstraints(textPrenom, 1, 1);
// Ligne 2
Label labelEmail = new Label("Email :");
GridPane.setConstraints(labelEmail, 0, 2);
TextField textEmail = new TextField();
GridPane.setConstraints(textEmail, 1, 2);
// Ligne 3
Button btnSubmit = new Button("Soumettre");
GridPane.setConstraints(btnSubmit, 1, 3);
grid.getChildren().addAll(
labelNom, textNom,
labelPrenom, textPrenom,
labelEmail, textEmail,
btnSubmit
);
Scene scene = new Scene(grid, 350, 200);
primaryStage.setTitle("Formulaire - GridPane");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Résultat visuel : Un formulaire propre avec trois champs de saisie (Nom, Prénom, Email) alignés en colonnes avec leurs labels à gauche, et un bouton "Soumettre" en bas.
Exemple complet : Formulaire avec plusieurs contrôles
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class FormulaireComplet extends Application {
@Override
public void start(Stage primaryStage) {
GridPane grid = new GridPane();
grid.setPadding(new Insets(15, 15, 15, 15));
grid.setVgap(10);
grid.setHgap(10);
// Ligne 0 : Nom
Label lblNom = new Label("Nom :");
TextField txtNom = new TextField();
GridPane.setConstraints(lblNom, 0, 0);
GridPane.setConstraints(txtNom, 1, 0);
// Ligne 1 : Âge
Label lblAge = new Label("Âge :");
TextField txtAge = new TextField();
GridPane.setConstraints(lblAge, 0, 1);
GridPane.setConstraints(txtAge, 1, 1);
// Ligne 2 : Genre (Radio buttons)
Label lblGenre = new Label("Genre :");
RadioButton rbMasculin = new RadioButton("Masculin");
RadioButton rbFeminin = new RadioButton("Féminin");
RadioButton rbAutre = new RadioButton("Autre");
ToggleGroup genreGroup = new ToggleGroup();
rbMasculin.setToggleGroup(genreGroup);
rbFeminin.setToggleGroup(genreGroup);
rbAutre.setToggleGroup(genreGroup);
HBox genreBox = new HBox(10);
genreBox.getChildren().addAll(rbMasculin, rbFeminin, rbAutre);
GridPane.setConstraints(lblGenre, 0, 2);
GridPane.setConstraints(genreBox, 1, 2);
// Ligne 3 : Intérêts (CheckBoxes)
Label lblInterets = new Label("Intérêts :");
CheckBox cbSport = new CheckBox("Sport");
CheckBox cbMusique = new CheckBox("Musique");
CheckBox cbLecture = new CheckBox("Lecture");
HBox interetsBox = new HBox(10);
interetsBox.getChildren().addAll(cbSport, cbMusique, cbLecture);
GridPane.setConstraints(lblInterets, 0, 3);
GridPane.setConstraints(interetsBox, 1, 3);
// Ligne 4 : Pays (ComboBox)
Label lblPays = new Label("Pays :");
ComboBox<String> comboPays = new ComboBox<>();
comboPays.getItems().addAll("Canada", "France", "Belgique", "Suisse");
comboPays.setValue("Canada");
GridPane.setConstraints(lblPays, 0, 4);
GridPane.setConstraints(comboPays, 1, 4);
// Ligne 5 : Commentaires (TextArea)
Label lblCommentaire = new Label("Commentaire :");
TextArea txtCommentaire = new TextArea();
txtCommentaire.setPrefRowCount(3);
GridPane.setConstraints(lblCommentaire, 0, 5);
GridPane.setConstraints(txtCommentaire, 1, 5);
// Ligne 6 : Boutons
Button btnValider = new Button("Valider");
Button btnAnnuler = new Button("Annuler");
HBox boutonBox = new HBox(10);
boutonBox.getChildren().addAll(btnValider, btnAnnuler);
GridPane.setConstraints(boutonBox, 1, 6);
// Ajout de tous les éléments
grid.getChildren().addAll(
lblNom, txtNom,
lblAge, txtAge,
lblGenre, genreBox,
lblInterets, interetsBox,
lblPays, comboPays,
lblCommentaire, txtCommentaire,
boutonBox
);
Scene scene = new Scene(grid, 500, 450);
primaryStage.setTitle("Formulaire complet");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Résultat visuel : Un formulaire complet incluant :
- Champs de texte (nom, âge)
- Boutons radio pour le genre (un seul choix possible)
- Cases à cocher pour les intérêts (plusieurs choix possibles)
- Liste déroulante pour le pays
- Zone de texte multiligne pour les commentaires
- Deux boutons d'action (Valider/Annuler)
Ressources utiles
- Tutoriels JavaFX de Jenkov : https://jenkov.com/tutorials/javafx/index.html