Événements
Introduction
En JavaFX, nous développons des applications graphiques (GUI). Lorsqu'un utilisateur interagit avec les éléments de l'application (comme un bouton), un événement est créé et doit être géré. Pour les boutons, l'événement principal est l'ActionEvent, qui se déclenche lorsque l'utilisateur clique sur le bouton.
Qu'est-ce qu'un ActionEvent ?
Un ActionEvent est un événement qui se produit lorsqu'une action est déclenchée sur un contrôle d'interface, notamment :
- Un clic sur un bouton
- La sélection d'un élément dans un menu déroulant
- L'appui sur la touche Entrée dans un champ de texte
Pour les boutons, c'est l'événement le plus courant et le plus simple à gérer.
Anatomie d'un événement
Tous les événements JavaFX possèdent trois caractéristiques :
- Type : Qu'est-ce qui s'est produit ? (Exemple : clic sur bouton)
- Source : Qu'est-ce qui a produit l'événement ? (Exemple : le bouton lui-même)
- Cible : Sur quoi s'est produit l'événement ? (Exemple : le bouton)
Gestion d'un événement de bouton
Structure de base
Pour gérer un événement de bouton, nous utilisons un gestionnaire d'événement (handler). Il existe plusieurs approches pour implémenter cela.
Approche 1 : Classe anonyme
La forme la plus explicite implique une classe anonyme qui implémente EventHandler<ActionEvent> :
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Bouton cliqué !");
// Votre logique personnalisée ici
}
});
Classes impliquées :
javafx.event.EventHandler<ActionEvent>: interface générique qui définit la méthodehandle(ActionEvent event)- Classe anonyme : implémente anonymement l'interface
Approche 2 : Expression Lambda (courte et moderne)
La forme la plus concise en utilisant une expression lambda (Java 8+) :
button.setOnAction(event -> {
System.out.println("Bouton cliqué !");
// Votre logique personnalisée ici
});
Transformation : Java traduit automatiquement cette expression en instance de EventHandler<ActionEvent>
Identifier la source d'un événement
Lorsque vous gérez un événement, vous avez besoin de savoir quel élément l'a déclenché. Pour cela, utilisez la méthode getSource() :
Principe
Object source = actionEvent.getSource();
Exemple : Identifier un bouton
button.setOnAction(event -> {
Object source = event.getSource();
if (source instanceof Button) {
Button clickedButton = (Button) source;
System.out.println("Bouton cliqué : " + clickedButton.getText());
}
});
Gérer plusieurs boutons avec un même gestionnaire
Approche 1 : Ajouter le gestionnaire à chaque bouton
Button btnSauvegarder = new Button("Sauvegarder");
Button btnAnnuler = new Button("Annuler");
EventHandler<ActionEvent> handler = event -> {
Object source = event.getSource();
if (source instanceof Button) {
Button btn = (Button) source;
String buttonText = btn.getText();
if (buttonText.equals("Sauvegarder")) {
System.out.println("Données sauvegardées");
} else if (buttonText.equals("Annuler")) {
System.out.println("Opération annulée");
}
}
};
btnSauvegarder.setOnAction(handler);
btnAnnuler.setOnAction(handler);
Approche 2 : Utiliser setId() pour identifier les boutons
Button btn1 = new Button("Action 1");
btn1.setId("btn1");
Button btn2 = new Button("Action 2");
btn2.setId("btn2");
EventHandler<ActionEvent> handler = event -> {
Button source = (Button) event.getSource();
String id = source.getId();
switch(id) {
case "btn1":
System.out.println("Action 1 exécutée");
break;
case "btn2":
System.out.println("Action 2 exécutée");
break;
}
};
btn1.setOnAction(handler);
btn2.setOnAction(handler);
Accès aux informations du bouton
Une fois la source identifiée comme un bouton, vous pouvez accéder à ses propriétés :
button.setOnAction(event -> {
Button clickedButton = (Button) event.getSource();
// Accéder au texte du bouton
String text = clickedButton.getText();
// Accéder à l'ID du bouton
String id = clickedButton.getId();
// Modifier les propriétés du bouton
clickedButton.setStyle("-fx-font-size: 14;");
clickedButton.setDisable(true);
});
Différences entre getSource() et getTarget()
Bien que pour les boutons ces deux méthodes retournent généralement le même objet, voici les différences :
- getSource() : Retourne l'objet qui a déclenché l'événement (le bouton cliqué)
- getTarget() : Retourne l'objet qui est la cible directe de l'événement
Pour un clic simple sur un bouton, les deux retournent le bouton. Les différences apparaissent dans des scénarios plus complexes où l'événement se propage dans une hiérarchie de composants.
Consommation d'événements
Vous pouvez empêcher un événement de se propager ultérieurement :
button.setOnAction(event -> {
System.out.println("Bouton cliqué");
event.consume(); // Empêche d'autres gestionnaires de traiter cet événement
});
Exemple complet
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ButtonEventDemo extends Application {
@Override
public void start(Stage primaryStage) {
// Création des boutons
Button btnSauvegarder = new Button("Sauvegarder");
Button btnAnnuler = new Button("Annuler");
// Gestionnaire pour le bouton Sauvegarder
btnSauvegarder.setOnAction(event -> {
Button btn = (Button) event.getSource();
System.out.println("Vous avez cliqué sur : " + btn.getText());
System.out.println("Données en cours de sauvegarde...");
});
// Gestionnaire pour le bouton Annuler
btnAnnuler.setOnAction(event -> {
Button btn = (Button) event.getSource();
System.out.println("Vous avez cliqué sur : " + btn.getText());
System.out.println("Opération annulée");
});
// Mise en page et affichage
VBox root = new VBox(10);
root.getChildren().addAll(btnSauvegarder, btnAnnuler);
Scene scene = new Scene(root, 300, 150);
primaryStage.setTitle("Gestion des événements de bouton");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Autres événements de bouton
Bien que l'ActionEvent soit le plus courant, vous pouvez aussi gérer d'autres interactions avec les boutons :
- MOUSE_ENTERED : Quand la souris entre dans la zone du bouton
- MOUSE_EXITED : Quand la souris quitte la zone du bouton
- MOUSE_PRESSED : Quand le bouton de la souris est enfoncé
- MOUSE_RELEASED : Quand le bouton de la souris est relâché
button.addEventFilter(MouseEvent.MOUSE_ENTERED, event -> {
button.setStyle("-fx-font-size: 16; -fx-text-fill: blue;");
});
button.addEventFilter(MouseEvent.MOUSE_EXITED, event -> {
button.setStyle("-fx-font-size: 14;");
});
## Autres types d'événements en JavaFX
En JavaFX, plusieurs familles d'événements peuvent être générées. Comme vu au dernier cours, on utilise un `EventHandler<T>` pour les traiter.
Exemples fréquents :
* **MouseEvent** : clics, survols, glisser-deposer (`MOUSE_CLICKED`, `MOUSE_MOVED`, `MOUSE_DRAGGED`).
* **KeyEvent** : clavier (`KEY_PRESSED`, `KEY_RELEASED`, `KEY_TYPED`).
* **ActionEvent** : actions de haut niveau (boutons, menus, `TextField` avec Entrée).
* **ScrollEvent** : molette et défilement (`SCROLL`).
* **TouchEvent** : interactions tactiles (`TOUCH_PRESSED`, `TOUCH_MOVED`).
* **DragEvent** : glisser-deposer (`DRAG_DETECTED`, `DRAG_DROPPED`).
* **WindowEvent** : fenêtre et cycle de vie (`WINDOW_SHOWN`, `WINDOW_CLOSE_REQUEST`).
Tous ces événements se gèrent via un `EventHandler<T>` et peuvent être branchés avec `setOnXxx(...)` ou `addEventFilter(...)`.
Résumé
Pour gérer les événements de bouton en JavaFX :
- Utilisez setOnAction() pour ajouter un gestionnaire à un bouton
- Utilisez event.getSource() pour identifier quel bouton a déclenché l'événement
- Transtyper la source en Button pour accéder aux propriétés du bouton
- Implémentez votre logique métier dans le gestionnaire
- Optionnellement, appelez event.consume() pour empêcher la propagation de l'événement