1Qué es un evento

Un evento es una señal que indica que ha ocurrido algo: un clic, la pulsación de una tecla, un cambio de texto, el movimiento del ratón, la finalización de una tarea, etc.

  • Evento (Event): el tipo de evento que ocurre.
  • Fuente de evento (Event source): el origen del evento (p.ej. un botón).
  • Destino de evento (Event target): el nodo al que se dirige el evento.
  • Manejador de evento (Event handler): el objeto oyente que implementa EventHandler con su método handle().
CategoríaClase baseEjemplo
AcciónActionEventPulsar botón, seleccionar menú
RatónMouseEventClic, movimiento, arrastre
TecladoKeyEventPulsar o soltar tecla
DesplazamientoScrollEventDesplazamiento con la rueda
Entrada de textoInputMethodEventEscribir texto
FocoFocusEventGanar/perder el foco
Arrastrar/soltarDragEventDrag and drop
VentanaWindowEventMostrar/ocultar ventanas
PersonalizadosEventDefinidos por el programador

2Propagación del evento (cuatro fases)

  1. Selección del objetivo: JavaFX decide qué nodo recibe el evento (teclado → nodo con foco; ratón → nodo bajo el cursor; si hay nodos superpuestos, el superior/visible lo recibe).
  2. Construcción de la ruta: se arma una cadena de envío (event dispatch chain) desde el nodo raíz (Stage) hasta el nodo objetivo. Ejemplo: Stage → Scene → Pane → Rectangle → Triangle (objetivo).
  3. Captura del evento: el evento viaja desde la raíz hacia el objetivo; en cada paso se ejecutan los Event Filters que existan. Si uno consume el evento (event.consume()), no llega al objetivo.
  4. Burbujeo del evento: el evento regresa desde el objetivo hacia el Stage, ejecutando los Event Handlers. Si un manejador lo consume, los nodos superiores no lo procesan.
MecanismoCuándo actúaEfecto de consumir
Event FilterAntes de llegar al objetivo (fase de captura)El evento no llega al hijo
Event HandlerDespués de llegar al objetivo (fase de burbujeo)El evento no sube al padre
java
event.consume(); // detiene la propagación del evento

3Tres formas de manejar un evento

java
// 1) Clase anónima
Button btn = new Button("Haz clic");
btn.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
        System.out.println("¡Has hecho clic en el botón!");
    }
});

// 2) Expresión lambda
Button btn2 = new Button("Haz clic");
btn2.setOnAction(e -> System.out.println("¡Botón presionado!"));

// 3) Implementando EventHandler en una clase
public class MiManejador implements EventHandler<ActionEvent> {
    @Override
    public void handle(ActionEvent e) {
        System.out.println("Evento manejado desde otra clase.");
    }
}
btn.setOnAction(new MiManejador());

Añadir un manejador siempre sigue tres pasos: (1) tener una fuente de evento (un control que puede generar eventos), (2) crear el manejador implementando EventHandler y su método handle(), (3) registrarlo con un método como setOnAction().

java
public class HolaMundo extends Application {
    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        btn.setText("Escribir 'Hola mundo'");

        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("¡Hola mundo!");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setTitle("Hola mundo.");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

4Ejemplos: ratón, teclado y burbujeo

java
button.setOnMouseEntered(e -> System.out.println("El ratón está sobre el botón"));
button.setOnMouseExited(e -> System.out.println("El ratón salió del botón"));
button.setOnMousePressed(e -> System.out.println("Botón del ratón presionado"));
button.setOnMouseReleased(e -> System.out.println("Botón del ratón soltado"));
button.setOnMouseClicked(e -> System.out.println("Clic completo"));
e.getButton(); // Botón del ratón (PRIMARY, SECONDARY...)
e.getX();      // Coordenada X del clic
e.getY();      // Coordenada Y del clic
java
scene.setOnKeyPressed(e -> System.out.println("Tecla presionada: " + e.getCode()));
scene.setOnKeyReleased(e -> System.out.println("Tecla liberada: " + e.getCode()));
e.getCode(); // Devuelve el código de la tecla (KeyCode.A, KeyCode.ENTER, etc.)

Ejemplo de burbujeo: un clic sobre un círculo dentro de un VBox dispara primero el manejador del círculo y después el del VBox (a menos que el primero consuma el evento).

java
circle.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
    System.out.println("Círculo clicado. Fuente: "
        + e.getSource().getClass().getSimpleName());
    // e.consume(); // Descomentar para evitar el burbujeo
});

root.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
    System.out.println("VBox clicado. Fuente: "
        + e.getSource().getClass().getSimpleName());
    System.out.println("Target del evento: "
        + e.getTarget().getClass().getSimpleName());
});

Ejemplo completo combinando estilo dinámico en hover y una alerta al pulsar:

java
Button btn = new Button("Haz clic aquí");
btn.setStyle("-fx-font-size: 14px; -fx-padding: 10px 20px; "
           + "-fx-background-color: lightgray;");

btn.setOnMouseEntered(e -> {
    btn.setStyle("-fx-font-size: 14px; -fx-padding: 10px 20px; "
               + "-fx-background-color: lightgray; "
               + "-fx-border-color: blue; -fx-border-width: 2px; "
               + "-fx-border-insets: 2px;");
});

btn.setOnMouseExited(e -> {
    btn.setStyle("-fx-font-size: 14px; -fx-padding: 10px 20px; "
               + "-fx-background-color: lightgray;");
});

btn.setOnAction(e -> {
    Alert alerta = new Alert(AlertType.INFORMATION);
    alerta.setTitle("Mensaje");
    alerta.setHeaderText(null);
    alerta.setContentText("Bienvenido a JavaFX");
    alerta.showAndWait();
});

✓Ideas clave que debes dominar

  • Cuatro fases: selección del objetivo → construcción de la ruta → captura (filtros) → burbujeo (handlers).
  • event.consume() corta la propagación en el punto donde se llama.
  • Tres formas de manejar un evento: clase anónima, lambda, clase que implementa EventHandler.

Adaptado de Eventos y acción de los componentes.