JavaFX - obsługa zdarzeń

W JavaFX możemy tworzyć aplikacje GUI, aplikacje internetowe i aplikacje graficzne. W takich aplikacjach za każdym razem, gdy użytkownik wchodzi w interakcję z aplikacją (węzłami), mówi się, że wystąpiło zdarzenie.

Na przykład kliknięcie przycisku, poruszenie myszą, wpisanie znaku z klawiatury, wybranie pozycji z listy, przewijanie strony to czynności, które powodują wystąpienie zdarzenia.

Rodzaje wydarzeń

Zdarzenia można ogólnie podzielić na następujące dwie kategorie -

  • Foreground Events- Wydarzenia, które wymagają bezpośredniej interakcji użytkownika. Są generowane jako konsekwencje osoby wchodzącej w interakcję z elementami graficznymi w graficznym interfejsie użytkownika. Na przykład kliknięcie przycisku, poruszenie myszą, wpisanie znaku za pomocą klawiatury, wybranie pozycji z listy, przewijanie strony itp.

  • Background Events- Te zdarzenia, które wymagają interakcji użytkownika końcowego, nazywane są zdarzeniami w tle. Przerwy w systemie operacyjnym, awaria sprzętu lub oprogramowania, upływ czasu, zakończenie operacji to przykłady zdarzeń w tle.

Wydarzenia w JavaFX

JavaFX zapewnia obsługę wielu rodzajów zdarzeń. Klasa o nazwieEvent pakietu javafx.event jest klasą bazową dla zdarzenia.

Wystąpienie dowolnej jej podklasy jest zdarzeniem. JavaFX zapewnia szeroką gamę wydarzeń. Niektóre z nich są wymienione poniżej.

  • Mouse Event- To jest zdarzenie wejściowe, które występuje po kliknięciu myszą. Jest reprezentowana przez nazwaną klasęMouseEvent. Obejmuje działania takie jak kliknięcie myszą, naciśnięcie myszy, zwolnienie myszy, przesunięcie myszy, cel wprowadzony myszą, cel opuszczony przez mysz itp.

  • Key Event- To jest zdarzenie wejściowe, które wskazuje, że naciśnięcie klawisza nastąpiło w węźle. Jest reprezentowana przez nazwaną klasęKeyEvent. To zdarzenie obejmuje czynności, takie jak naciśnięcie klawisza, zwolnienie klawisza i wpisanie klawisza.

  • Drag Event- To jest zdarzenie wejściowe, które występuje, gdy mysz jest przeciągnięta. Jest reprezentowana przez nazwaną klasęDragEvent. Obejmuje działania takie jak przeciągnij wprowadzony, przeciągnij upuść, przeciągnij wprowadzony cel, przeciągnij opuszczony cel, przeciągnij po itp.

  • Window Event- To jest zdarzenie związane z wyświetlaniem / ukrywaniem okien. Jest reprezentowana przez nazwaną klasęWindowEvent. Obejmuje działania takie jak ukrywanie okna, pokazywanie okna, ukrywanie okna, pokazywanie okna itp.

Obsługa zdarzeń

Obsługa zdarzeń to mechanizm, który kontroluje zdarzenie i decyduje, co powinno się stać, jeśli wystąpi zdarzenie. Ten mechanizm zawiera kod, który jest znany jako moduł obsługi zdarzeń, który jest wykonywany, gdy wystąpi zdarzenie.

JavaFX zapewnia programy obsługi i filtry do obsługi zdarzeń. W JavaFX każde zdarzenie ma -

  • Target- węzeł, w którym wystąpiło zdarzenie. Celem może być okno, scena i węzeł.

  • Source- Źródło, z którego generowane jest zdarzenie, będzie źródłem zdarzenia. W powyższym scenariuszu źródłem zdarzenia jest mysz.

  • Type- rodzaj zaistniałego zdarzenia; w przypadku zdarzenia myszy - typem zdarzeń jest wciśnięcie myszki, zwolnienie myszy.

Załóżmy, że mamy aplikację, która ma przyciski Circle, Stop i Play wstawione za pomocą obiektu grupy w następujący sposób -

Jeśli klikniesz przycisk odtwarzania, źródłem będzie mysz, węzłem docelowym będzie przycisk odtwarzania, a typ generowanego zdarzenia to kliknięcie myszą.

Fazy ​​obsługi zdarzeń w JavaFX

Za każdym razem, gdy generowane jest zdarzenie, JavaFX przechodzi następujące fazy.

Budowa trasy

Za każdym razem, gdy generowane jest zdarzenie, domyślna / początkowa trasa zdarzenia jest określana przez konstrukcję Event Dispatch chain. Jest to ścieżka prowadząca ze sceny do węzła źródłowego.

Poniżej znajduje się łańcuch wysyłania zdarzeń dla zdarzenia wygenerowanego po kliknięciu przycisku odtwarzania w powyższym scenariuszu.

Faza przejmowania wydarzeń

Po skonstruowaniu łańcucha wysyłania zdarzeń węzeł główny aplikacji wywołuje zdarzenie. To zdarzenie jest przenoszone do wszystkich węzłów w łańcuchu wysyłki (od góry do dołu). Jeśli którykolwiek z tych węzłów ma rozszerzeniefilterzarejestrowane dla wygenerowanego zdarzenia, zostanie wykonane. Jeśli żaden z węzłów w łańcuchu wysyłki nie ma filtru dla wygenerowanego zdarzenia, jest on przekazywany do węzła docelowego, a ostatecznie węzeł docelowy przetwarza zdarzenie.

Faza propagacji wydarzeń

W fazie propagacji zdarzenia zdarzenie jest przesyłane z węzła docelowego do węzła etapu (od dołu do góry). Jeśli którykolwiek z węzłów w łańcuchu wysyłania zdarzeń ma rozszerzeniehandlerzarejestrowane dla wygenerowanego zdarzenia, zostanie wykonane. Jeśli żaden z tych węzłów nie ma programów obsługi do obsługi zdarzenia, zdarzenie dotrze do węzła głównego i ostatecznie proces zostanie zakończony.

Programy obsługi zdarzeń i filtry

Filtry i programy obsługi zdarzeń to te, które zawierają logikę aplikacji do przetwarzania zdarzenia. Węzeł może zarejestrować się w więcej niż jednej obsłudze / filtrze. W przypadku węzłów nadrzędny-podrzędny można udostępnić rodzicom wspólny filtr / procedurę obsługi, która jest przetwarzana domyślnie dla wszystkich węzłów podrzędnych.

Jak wspomniano powyżej, podczas zdarzenia przetwarzanie jest filtrem, który jest wykonywany, a podczas fazy propagacji zdarzeń wykonywany jest moduł obsługi. Wszystkie programy obsługi i filtry implementują interfejsEventHandler pakietu javafx.event.

Dodawanie i usuwanie filtru wydarzeń

Aby dodać filtr zdarzeń do węzła, musisz zarejestrować ten filtr przy użyciu tej metody addEventFilter() z Node klasa.

//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);

W ten sam sposób możesz usunąć filtr za pomocą metody removeEventFilter (), jak pokazano poniżej -

circle.removeEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);

Przykład obsługi zdarzeń

Poniżej znajduje się przykład demonstrujący obsługę zdarzeń w języku JavaFX przy użyciu filtrów zdarzeń. Zapisz ten kod w pliku o nazwieEventFiltersExample.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); 
   } 
}

Skompiluj i uruchom zapisany plik java z wiersza poleceń, używając następujących poleceń.

javac EventFiltersExample.java 
java EventFiltersExample

Podczas wykonywania powyższy program generuje okno JavaFX, jak pokazano poniżej.

Dodawanie i usuwanie programów obsługi zdarzeń

Aby dodać procedurę obsługi zdarzeń do węzła, należy zarejestrować tę procedurę obsługi przy użyciu metody addEventHandler() z Node klasa, jak pokazano poniżej.

//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);

W ten sam sposób możesz usunąć procedurę obsługi zdarzeń za pomocą metody removeEventHandler (), jak pokazano poniżej -

circle.removeEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);

Przykład

Poniższy program to przykład demonstrujący obsługę zdarzeń w języku JavaFX przy użyciu programów obsługi zdarzeń.

Zapisz ten kod w pliku o nazwie 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); 
   } 
}

Skompiluj i uruchom zapisany plik java z wiersza poleceń, używając następujących poleceń.

javac EventHandlersExample.java 
java EventHandlersExample

Podczas wykonywania powyższy program generuje okno JavaFX wyświetlające pole tekstowe i ramkę 3D, jak pokazano poniżej -

Tutaj, jeśli wpiszesz literę w polu tekstowym, pole 3D zacznie się obracać wzdłuż osi x. Jeśli ponownie klikniesz to pole, obrót zostanie zatrzymany.

Korzystanie z wygodnych metod obsługi zdarzeń

Niektóre klasy w JavaFX definiują właściwości modułu obsługi zdarzeń. Ustawiając wartości tych właściwości przy użyciu odpowiednich metod ustawiających, można zarejestrować się w programie obsługi zdarzeń. Metody te są znane jako metody wygodne.

Większość z tych metod istnieje w klasach takich jak Node, Scene, Window itd. I są one dostępne dla wszystkich ich podklas.

Na przykład, aby dodać detektor zdarzeń myszy do przycisku, możesz skorzystać z wygodnej metody setOnMouseClicked() jak pokazano niżej.

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

Przykład

Poniższy program jest przykładem, który demonstruje obsługę zdarzeń w JavaFX przy użyciu wygodnych metod.

Zapisz ten kod w pliku o nazwie 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); 
   } 
}

Skompiluj i uruchom zapisany plik java z wiersza poleceń, używając następujących poleceń.

javac ConvinienceMethodsExample.java 
java ConvinienceMethodsExample

Podczas wykonywania powyższy program generuje okno JavaFX, jak pokazano poniżej. Tutaj kliknij przycisk odtwarzania, aby rozpocząć animację i kliknij przycisk zatrzymania, aby zatrzymać animację.