Aller au contenu principal

É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éthode handle(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 :

  1. Utilisez setOnAction() pour ajouter un gestionnaire à un bouton
  2. Utilisez event.getSource() pour identifier quel bouton a déclenché l'événement
  3. Transtyper la source en Button pour accéder aux propriétés du bouton
  4. Implémentez votre logique métier dans le gestionnaire
  5. Optionnellement, appelez event.consume() pour empêcher la propagation de l'événement