JavaFX - Gestione eventi

In JavaFX, possiamo sviluppare applicazioni GUI, applicazioni web e applicazioni grafiche. In tali applicazioni, ogni volta che un utente interagisce con l'applicazione (nodi), si dice che si è verificato un evento.

Ad esempio, fare clic su un pulsante, spostare il mouse, inserire un carattere tramite la tastiera, selezionare un elemento dall'elenco, scorrere la pagina sono le attività che provocano un evento.

Tipi di eventi

Gli eventi possono essere classificati a grandi linee nelle due seguenti categorie:

  • Foreground Events- Quegli eventi che richiedono l'interazione diretta di un utente. Vengono generati come conseguenza dell'interazione di una persona con i componenti grafici in un'interfaccia utente grafica. Ad esempio, fare clic su un pulsante, spostare il mouse, immettere un carattere tramite la tastiera, selezionare un elemento dall'elenco, scorrere la pagina, ecc.

  • Background Events- Gli eventi che richiedono l'interazione dell'utente finale sono noti come eventi in background. Le interruzioni del sistema operativo, il guasto hardware o software, la scadenza del timer, il completamento dell'operazione sono un esempio di eventi in background.

Eventi in JavaFX

JavaFX fornisce supporto per gestire un'ampia varietà di eventi. La classe denominataEvent del pacchetto javafx.event è la classe base per un evento.

Un'istanza di una qualsiasi delle sue sottoclassi è un evento. JavaFX fornisce un'ampia varietà di eventi. Alcuni di loro sono elencati di seguito.

  • Mouse Event- Questo è un evento di input che si verifica quando si fa clic su un mouse. È rappresentato dalla classe denominataMouseEvent. Include azioni come clic con il mouse, pressione del mouse, rilascio del mouse, spostamento del mouse, destinazione inserita con il mouse, destinazione uscita dal mouse, ecc.

  • Key Event- Questo è un evento di input che indica la pressione del tasto avvenuta su un nodo. È rappresentato dalla classe denominataKeyEvent. Questo evento include azioni come tasto premuto, tasto rilasciato e tasto digitato.

  • Drag Event- Questo è un evento di input che si verifica quando il mouse viene trascinato. È rappresentato dalla classe denominataDragEvent. Include azioni come trascinamento inserito, trascinamento rilasciato, trascina destinazione inserita, trascina destinazione uscita, trascina sopra, ecc.

  • Window Event- Questo è un evento relativo alle azioni di visualizzazione / occultamento di finestre. È rappresentato dalla classe denominataWindowEvent. Include azioni come nascondere la finestra, mostrare la finestra, nascondere la finestra, mostrare la finestra, ecc.

Gestione degli eventi

La gestione degli eventi è il meccanismo che controlla l'evento e decide cosa dovrebbe accadere, se si verifica un evento. Questo meccanismo ha il codice noto come gestore di eventi che viene eseguito quando si verifica un evento.

JavaFX fornisce gestori e filtri per gestire gli eventi. In JavaFX ogni evento ha:

  • Target- Il nodo su cui si è verificato un evento. Un obiettivo può essere una finestra, una scena e un nodo.

  • Source- La fonte da cui viene generato l'evento sarà la fonte dell'evento. Nello scenario precedente, il mouse è l'origine dell'evento.

  • Type- Tipo di evento accaduto; in caso di evento del mouse - mouse premuto, mouse rilasciato sono il tipo di eventi.

Supponiamo di avere un'applicazione che ha i pulsanti Circle, Stop e Play inseriti utilizzando un oggetto di gruppo come segue:

Se si fa clic sul pulsante di riproduzione, la sorgente sarà il mouse, il nodo di destinazione sarà il pulsante di riproduzione e il tipo di evento generato è il clic del mouse.

Fasi della gestione degli eventi in JavaFX

Ogni volta che viene generato un evento, JavaFX subisce le seguenti fasi.

Costruzione del percorso

Ogni volta che viene generato un evento, il percorso predefinito / iniziale dell'evento è determinato dalla costruzione di un file Event Dispatch chain. È il percorso dallo stage alla sorgente Node.

Di seguito è riportata la catena di invio dell'evento per l'evento generato, quando si fa clic sul pulsante di riproduzione nello scenario precedente.

Fase di cattura dell'evento

Dopo la costruzione della catena di distribuzione degli eventi, il nodo radice dell'applicazione invia l'evento. Questo evento viaggia a tutti i nodi della catena di distribuzione (dall'alto verso il basso). Se uno di questi nodi ha l'estensionefilterregistrato per l'evento generato, verrà eseguito. Se nessuno dei nodi nella catena di distribuzione dispone di un filtro per l'evento generato, viene passato al nodo di destinazione e infine il nodo di destinazione elabora l'evento.

Fase di ribollimento dell'evento

Nella fase di bubbling dell'evento, l'evento viene viaggiato dal nodo target al nodo dello stage (dal basso verso l'alto). Se uno qualsiasi dei nodi nella catena di invio dell'evento ha l'estensionehandlerregistrato per l'evento generato, verrà eseguito. Se nessuno di questi nodi dispone di gestori per gestire l'evento, l'evento raggiunge il nodo radice e alla fine il processo sarà completato.

Gestori di eventi e filtri

I filtri e i gestori degli eventi sono quelli che contengono la logica dell'applicazione per elaborare un evento. Un nodo può registrarsi su più di un gestore / filtro. In caso di nodi padre-figlio, è possibile fornire un filtro / gestore comune ai genitori, che viene elaborato come predefinito per tutti i nodi figlio.

Come accennato in precedenza, durante l'evento, l'elaborazione è un filtro che viene eseguito e durante la fase di bubbling dell'evento viene eseguito un gestore. Tutti i gestori e filtri implementano l'interfacciaEventHandler del pacchetto javafx.event.

Aggiunta e rimozione del filtro eventi

Per aggiungere un filtro eventi a un nodo, è necessario registrare questo filtro utilizzando il metodo addEventFilter() del Node classe.

//Creating the mouse event handler 
EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() { 
   @Override 
   public void handle(MouseEvent e) { 
      System.out.println("Hello World"); 
      circle.setFill(Color.DARKSLATEBLUE);  
   } 
};   
//Adding event Filter 
Circle.addEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);

Allo stesso modo, puoi rimuovere un filtro usando il metodo removeEventFilter () come mostrato di seguito -

circle.removeEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);

Esempio di gestione degli eventi

Di seguito è riportato un esempio che mostra la gestione degli eventi in JavaFX utilizzando i filtri degli eventi. Salva questo codice in un file con nomeEventFiltersExample.java.

import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.event.EventHandler;
 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 

import javafx.scene.text.Font; 
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text; 
import javafx.stage.Stage; 
         
public class EventFiltersExample extends Application { 
   @Override 
   public void start(Stage stage) {      
      //Drawing a Circle 
      Circle circle = new Circle(); 
      
      //Setting the position of the circle 
      circle.setCenterX(300.0f); 
      circle.setCenterY(135.0f); 
      
      //Setting the radius of the circle 
      circle.setRadius(25.0f); 
      
      //Setting the color of the circle 
      circle.setFill(Color.BROWN); 
      
      //Setting the stroke width of the circle 
      circle.setStrokeWidth(20);      
       
      //Setting the text 
      Text text = new Text("Click on the circle to change its color"); 
      
      //Setting the font of the text 
      text.setFont(Font.font(null, FontWeight.BOLD, 15));     
      
      //Setting the color of the text 
      text.setFill(Color.CRIMSON); 
  
      //setting the position of the text 
      text.setX(150); 
      text.setY(50); 
       
      //Creating the mouse event handler 
      EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() { 
         @Override 
         public void handle(MouseEvent e) { 
            System.out.println("Hello World"); 
            circle.setFill(Color.DARKSLATEBLUE);
         } 
      };  
      //Registering the event filter 
      circle.addEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);   
       
      //Creating a Group object  
      Group root = new Group(circle, text); 
         
      //Creating a scene object 
      Scene scene = new Scene(root, 600, 300); 
       
      //Setting the fill color to the scene 
      scene.setFill(Color.LAVENDER);  
      
      //Setting title to the Stage 
      stage.setTitle("Event Filters Example");       
         
      //Adding scene to the stage 
      stage.setScene(scene); 
         
      //Displaying the contents of the stage 
      stage.show(); 
   } 
   public static void main(String args[]){ 
      launch(args); 
   } 
}

Compilare ed eseguire il file java salvato dal prompt dei comandi utilizzando i seguenti comandi.

javac EventFiltersExample.java 
java EventFiltersExample

All'esecuzione, il programma di cui sopra genera una finestra JavaFX come mostrato di seguito.

Aggiunta e rimozione di gestori di eventi

Per aggiungere un gestore di eventi a un nodo, è necessario registrare questo gestore utilizzando il metodo addEventHandler() del Node classe come mostrato di seguito.

//Creating the mouse event handler 
EventHandler<javafx.scene.input.MouseEvent> eventHandler = 
   new EventHandler<javafx.scene.input.MouseEvent>() { 
   
   @Override 
   public void handle(javafx.scene.input.MouseEvent e) { 
      System.out.println("Hello World"); 
      circle.setFill(Color.DARKSLATEBLUE);             
   } 
};    
//Adding the event handler 
circle.addEventHandler(javafx.scene.input.MouseEvent.MOUSE_CLICKED, eventHandler);

Allo stesso modo, puoi rimuovere un gestore di eventi usando il metodo removeEventHandler () come mostrato di seguito -

circle.removeEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);

Esempio

Il seguente programma è un esempio che dimostra la gestione degli eventi in JavaFX utilizzando i gestori di eventi.

Salva questo codice in un file con nome EventHandlersExample.java.

import javafx.animation.RotateTransition; 
import javafx.application.Application; 
import javafx.event.EventHandler; 

import javafx.scene.Group; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.input.KeyEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.PhongMaterial;
 
import javafx.scene.shape.Box; 
import javafx.scene.text.Font; 
import javafx.scene.text.FontWeight; 
import javafx.scene.text.Text;  
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 
import javafx.util.Duration; 
         
public class EventHandlersExample extends Application { 
   
   @Override 
   public void start(Stage stage) {
      //Drawing a Box 
      Box box = new Box(); 
      
      //Setting the properties of the Box 
      box.setWidth(150.0); 
      box.setHeight(150.0);   
      box.setDepth(100.0); 
       
      //Setting the position of the box 
      box.setTranslateX(350);  
      box.setTranslateY(150); 
      box.setTranslateZ(50); 
       
      //Setting the text 
      Text text = new Text("Type any letter to rotate the box, 
         and click on the box to stop the rotation"); 
      
      //Setting the font of the text 
      text.setFont(Font.font(null, FontWeight.BOLD, 15));     
      
      //Setting the color of the text 
      text.setFill(Color.CRIMSON); 
      
      //setting the position of the text 
      text.setX(20); 
      text.setY(50); 
       
      //Setting the material of the box 
      PhongMaterial material = new PhongMaterial();  
      material.setDiffuseColor(Color.DARKSLATEBLUE);  
      
      //Setting the diffuse color material to box 
      box.setMaterial(material);       
       
      //Setting the rotation animation to the box    
      RotateTransition rotateTransition = new RotateTransition(); 
      
      //Setting the duration for the transition 
      rotateTransition.setDuration(Duration.millis(1000)); 
      
      //Setting the node for the transition 
      rotateTransition.setNode(box);       
      
      //Setting the axis of the rotation 
      rotateTransition.setAxis(Rotate.Y_AXIS); 
      
      //Setting the angle of the rotation
      rotateTransition.setByAngle(360); 
      
      //Setting the cycle count for the transition 
      rotateTransition.setCycleCount(50); 
      
      //Setting auto reverse value to false 
      rotateTransition.setAutoReverse(false);  
      
      //Creating a text filed 
      TextField textField = new TextField();   
      
      //Setting the position of the text field 
      textField.setLayoutX(50); 
      textField.setLayoutY(100); 
       
      //Handling the key typed event 
      EventHandler<KeyEvent> eventHandlerTextField = new EventHandler<KeyEvent>() { 
         @Override 
         public void handle(KeyEvent event) { 
            //Playing the animation 
            rotateTransition.play(); 
         }           
      };              
      //Adding an event handler to the text feld 
      textField.addEventHandler(KeyEvent.KEY_TYPED, eventHandlerTextField); 
       
      //Handling the mouse clicked event(on box) 
      EventHandler<javafx.scene.input.MouseEvent> eventHandlerBox = 
         new EventHandler<javafx.scene.input.MouseEvent>() { 
         
         @Override 
         public void handle(javafx.scene.input.MouseEvent e) { 
            rotateTransition.stop();  
         } 
      }; 
      //Adding the event handler to the box  
      box.addEventHandler(javafx.scene.input.MouseEvent.MOUSE_CLICKED, eventHandlerBox);
       
      //Creating a Group object
      Group root = new Group(box, textField, text); 
         
      //Creating a scene object 
      Scene scene = new Scene(root, 600, 300);      
      
      //Setting camera 
      PerspectiveCamera camera = new PerspectiveCamera(false); 
      camera.setTranslateX(0); 
      camera.setTranslateY(0); 
      camera.setTranslateZ(0); 
      scene.setCamera(camera);  
      
      //Setting title to the Stage 
      stage.setTitle("Event Handlers Example"); 
         
      //Adding scene to the stage 
      stage.setScene(scene); 
         
      //Displaying the contents of the stage 
      stage.show(); 
   } 
   public static void main(String args[]){ 
      launch(args); 
   } 
}

Compilare ed eseguire il file java salvato dal prompt dei comandi utilizzando i seguenti comandi.

javac EventHandlersExample.java 
java EventHandlersExample

All'esecuzione, il programma di cui sopra genera una finestra JavaFX che mostra un campo di testo e una casella 3D come mostrato di seguito -

Qui, se digiti una lettera nel campo di testo, la casella 3D inizia a ruotare lungo l'asse x. Se fai di nuovo clic sulla casella, la rotazione si interrompe.

Utilizzo di metodi convenienti per la gestione degli eventi

Alcune delle classi in JavaFX definiscono le proprietà del gestore eventi. Impostando i valori su queste proprietà utilizzando i rispettivi metodi setter, è possibile registrarsi a un gestore di eventi. Questi metodi sono noti come metodi di convenienza.

La maggior parte di questi metodi esiste nelle classi come Node, Scene, Window, ecc. E sono disponibili per tutte le loro sottoclassi.

Ad esempio, per aggiungere un listener di eventi del mouse a un pulsante, è possibile utilizzare il metodo conveniente setOnMouseClicked() come mostrato di seguito.

playButton.setOnMouseClicked((new EventHandler<MouseEvent>() { 
   public void handle(MouseEvent event) { 
      System.out.println("Hello World"); 
      pathTransition.play(); 
   } 
}));

Esempio

Il seguente programma è un esempio che dimostra la gestione degli eventi in JavaFX utilizzando i metodi convenienti.

Salva questo codice in un file con il nome ConvinienceMethodsExample.java.

import javafx.animation.PathTransition; 
import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.event.EventHandler; 

import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 

import javafx.scene.shape.Circle; 
import javafx.scene.shape.LineTo; 
import javafx.scene.shape.MoveTo; 
import javafx.scene.shape.Path; 
import javafx.stage.Stage; 
import javafx.util.Duration; 
         
public class ConvinienceMethodsExample extends Application { 
   @Override 
   public void start(Stage stage) {      
      //Drawing a Circle 
      Circle circle = new Circle(); 
      
      //Setting the position of the circle 
      circle.setCenterX(300.0f); 
      circle.setCenterY(135.0f); 
      
      //Setting the radius of the circle 
      circle.setRadius(25.0f);  
      
      //Setting the color of the circle 
      circle.setFill(Color.BROWN); 
      
      //Setting the stroke width of the circle 
      circle.setStrokeWidth(20);      
       
      //Creating a Path 
      Path path = new Path(); 
      
      //Moving to the staring point 
      MoveTo moveTo = new MoveTo(208, 71);               
      
      //Creating 1st line 
      LineTo line1 = new LineTo(421, 161);        
      
      //Creating 2nd line 
      LineTo line2 = new LineTo(226,232); 
      
      //Creating 3rd line 
      LineTo line3 = new LineTo(332,52);        
      
      //Creating 4th line 
      LineTo line4 = new LineTo(369, 250);        
      
      //Creating 5th line 
      LineTo line5 = new LineTo(208, 71);       
      
      //Adding all the elements to the path 
      path.getElements().add(moveTo); 
      path.getElements().addAll(line1, line2, line3, line4, line5);     
      
      //Creating the path transition 
      PathTransition pathTransition = new PathTransition(); 
      
      //Setting the duration of the transition 
      pathTransition.setDuration(Duration.millis(1000));       
      
      //Setting the node for the transition 
      pathTransition.setNode(circle); 
      
      //Setting the path for the transition 
      pathTransition.setPath(path); 
      
      //Setting the orientation of the path 
      pathTransition.setOrientation(
         PathTransition.OrientationType.ORTHOGONAL_TO_TAN GENT);
      
      //Setting the cycle count for the transition 
      pathTransition.setCycleCount(50); 
      
      //Setting auto reverse value to true 
      pathTransition.setAutoReverse(false);
      
      //Creating play button 
      Button playButton = new Button("Play"); 
      playButton.setLayoutX(300); 
      playButton.setLayoutY(250); 
       
      circle.setOnMouseClicked (new EventHandler<javafx.scene.input.MouseEvent>() { 
         @Override 
         public void handle(javafx.scene.input.MouseEvent e) { 
            System.out.println("Hello World"); 
            circle.setFill(Color.DARKSLATEBLUE);             
         } 
      });   
      playButton.setOnMouseClicked((new EventHandler<MouseEvent>() { 
         public void handle(MouseEvent event) { 
            System.out.println("Hello World");  
            pathTransition.play(); 
         } 
      })); 
       
      //Creating stop button 
      Button stopButton = new Button("stop"); 
      stopButton.setLayoutX(250); 
      stopButton.setLayoutY(250); 
      
      stopButton.setOnMouseClicked((new EventHandler<MouseEvent>() { 
         public void handle(MouseEvent event) { 
            System.out.println("Hello World"); 
            pathTransition.stop(); 
         } 
      }));
      //Creating a Group object  
      Group root = new Group(circle, playButton, stopButton); 
         
      //Creating a scene object 
      Scene scene = new Scene(root, 600, 300); 
      scene.setFill(Color.LAVENDER);  
      
      //Setting title to the Stage 
      stage.setTitle("Convenience Methods Example");  
         
      //Adding scene to the stage 
      stage.setScene(scene); 
         
      //Displaying the contents of the stage 
      stage.show(); 
   } 
   public static void main(String args[]){ 
      launch(args); 
   } 
}

Compilare ed eseguire il file java salvato dal prompt dei comandi utilizzando i seguenti comandi.

javac ConvinienceMethodsExample.java 
java ConvinienceMethodsExample

All'esecuzione, il programma di cui sopra genera una finestra JavaFX come mostrato di seguito. Qui fai clic sul pulsante di riproduzione per avviare l'animazione e fai clic sul pulsante di interruzione per interrompere l'animazione.