JavaFX - Manejo de eventos
En JavaFX, podemos desarrollar aplicaciones GUI, aplicaciones web y aplicaciones gráficas. En tales aplicaciones, siempre que un usuario interactúa con la aplicación (nodos), se dice que ha ocurrido un evento.
Por ejemplo, hacer clic en un botón, mover el mouse, ingresar un carácter a través del teclado, seleccionar un elemento de la lista, desplazarse por la página son las actividades que hacen que suceda un evento.
Tipos de eventos
Los eventos se pueden clasificar ampliamente en las siguientes dos categorías:
Foreground Events- Aquellos eventos que requieran la interacción directa de un usuario. Se generan como consecuencia de la interacción de una persona con los componentes gráficos en una interfaz gráfica de usuario. Por ejemplo, hacer clic en un botón, mover el mouse, ingresar un carácter a través del teclado, seleccionar un elemento de la lista, desplazarse por la página, etc.
Background Events- Aquellos eventos que requieren la interacción del usuario final se conocen como eventos de fondo. Las interrupciones del sistema operativo, fallas de hardware o software, expiración del temporizador, finalización de la operación son ejemplos de eventos en segundo plano.
Eventos en JavaFX
JavaFX proporciona soporte para manejar una amplia variedad de eventos. La clase nombradaEvent del paquete javafx.event es la clase base para un evento.
Una instancia de cualquiera de su subclase es un evento. JavaFX proporciona una amplia variedad de eventos. Algunos de ellos se enumeran a continuación.
Mouse Event- Este es un evento de entrada que ocurre cuando se hace clic en un mouse. Está representado por la clase llamadaMouseEvent. Incluye acciones como hacer clic con el ratón, pulsar el ratón, soltar el ratón, mover el ratón, objetivo introducido con el ratón, objetivo salido del ratón, etc.
Key Event- Este es un evento de entrada que indica que la pulsación de tecla se produjo en un nodo. Está representado por la clase llamadaKeyEvent. Este evento incluye acciones como tecla presionada, tecla soltada y tecla tecleada.
Drag Event- Este es un evento de entrada que ocurre cuando se arrastra el mouse. Está representado por la clase llamadaDragEvent. Incluye acciones como arrastrar ingresado, arrastrar soltado, arrastrar destino ingresado, arrastrar destino salido, arrastrar sobre, etc.
Window Event- Este es un evento relacionado con acciones de mostrar / ocultar ventanas. Está representado por la clase llamadaWindowEvent. Incluye acciones como ocultar ventana, mostrar ventana, ventana oculta, mostrar ventana, etc.
Manejo de eventos
El Manejo de Eventos es el mecanismo que controla el evento y decide qué debe suceder, si ocurre un evento. Este mecanismo tiene el código conocido como controlador de eventos que se ejecuta cuando ocurre un evento.
JavaFX proporciona controladores y filtros para manejar eventos. En JavaFX cada evento tiene:
Target- El nodo en el que ocurrió un evento. Un objetivo puede ser una ventana, una escena y un nodo.
Source- La fuente a partir de la cual se genera el evento será la fuente del evento. En el escenario anterior, el mouse es la fuente del evento.
Type- Tipo de evento ocurrido; en el caso de un evento de mouse, el tipo de evento es el mouse presionado, el mouse soltado.
Supongamos que tenemos una aplicación que tiene un círculo, botones de parada y reproducción insertados utilizando un objeto de grupo de la siguiente manera:
Si hace clic en el botón de reproducción, la fuente será el mouse, el nodo de destino será el botón de reproducción y el tipo de evento generado es el clic del mouse.
Fases del manejo de eventos en JavaFX
Siempre que se genera un evento, JavaFX pasa por las siguientes fases.
Construcción de ruta
Siempre que se genera un evento, la ruta predeterminada / inicial del evento se determina mediante la construcción de un Event Dispatch chain. Es el camino desde el escenario hasta el nodo de origen.
A continuación se muestra la cadena de distribución de eventos para el evento generado, cuando hacemos clic en el botón de reproducción en el escenario anterior.
Fase de captura de eventos
Después de la construcción de la cadena de distribución de eventos, el nodo raíz de la aplicación distribuye el evento. Este evento viaja a todos los nodos de la cadena de distribución (de arriba a abajo). Si alguno de estos nodos tiene unfilterregistrado para el evento generado, se ejecutará. Si ninguno de los nodos en la cadena de distribución tiene un filtro para el evento generado, entonces se pasa al nodo de destino y finalmente el nodo de destino procesa el evento.
Fase de burbujeo del evento
En la fase de burbujeo de eventos, el evento se viaja desde el nodo de destino al nodo de etapa (de abajo hacia arriba). Si alguno de los nodos de la cadena de envío de eventos tiene unhandlerregistrado para el evento generado, se ejecutará. Si ninguno de estos nodos tiene manejadores para manejar el evento, entonces el evento llega al nodo raíz y finalmente se completará el proceso.
Controladores y filtros de eventos
Los filtros y controladores de eventos son aquellos que contienen lógica de aplicación para procesar un evento. Un nodo puede registrarse en más de un controlador / filtro. En el caso de los nodos padre-hijo, puede proporcionar un filtro / controlador común a los padres, que se procesa de forma predeterminada para todos los nodos secundarios.
Como se mencionó anteriormente, durante el evento, el procesamiento es un filtro que se ejecuta y durante la fase de propagación del evento, se ejecuta un controlador. Todos los controladores y filtros implementan la interfaz.EventHandler del paquete javafx.event.
Agregar y eliminar filtro de eventos
Para agregar un filtro de eventos a un nodo, debe registrar este filtro usando el método addEventFilter() del Node clase.
//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);
De la misma manera, puede eliminar un filtro utilizando el método removeEventFilter () como se muestra a continuación:
circle.removeEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);
Ejemplo de manejo de eventos
A continuación se muestra un ejemplo que demuestra el manejo de eventos en JavaFX utilizando los filtros de eventos. Guarde este código en un archivo con nombreEventFiltersExample.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);
}
}
Compile y ejecute el archivo java guardado desde el símbolo del sistema utilizando los siguientes comandos.
javac EventFiltersExample.java
java EventFiltersExample
Al ejecutarse, el programa anterior genera una ventana JavaFX como se muestra a continuación.
Agregar y eliminar controladores de eventos
Para agregar un controlador de eventos a un nodo, debe registrar este controlador utilizando el método addEventHandler() del Node clase como se muestra a continuación.
//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);
De la misma manera, puede eliminar un controlador de eventos utilizando el método removeEventHandler () como se muestra a continuación:
circle.removeEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
Ejemplo
El siguiente programa es un ejemplo que demuestra el manejo de eventos en JavaFX usando los controladores de eventos.
Guarde este código en un archivo con nombre 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);
}
}
Compile y ejecute el archivo java guardado desde el símbolo del sistema utilizando los siguientes comandos.
javac EventHandlersExample.java
java EventHandlersExample
Al ejecutarse, el programa anterior genera una ventana JavaFX que muestra un campo de texto y un cuadro 3D como se muestra a continuación:
Aquí, si escribe una letra en el campo de texto, el cuadro 3D comienza a girar a lo largo del eje x. Si vuelve a hacer clic en el cuadro, la rotación se detiene.
Uso de métodos prácticos para la gestión de eventos
Algunas de las clases de JavaFX definen las propiedades del controlador de eventos. Al establecer los valores de estas propiedades utilizando sus respectivos métodos de establecimiento, puede registrarse en un controlador de eventos. Estos métodos se conocen como métodos de conveniencia.
La mayoría de estos métodos existen en las clases como Node, Scene, Window, etc., y están disponibles para todas sus subclases.
Por ejemplo, para agregar un detector de eventos del mouse a un botón, puede usar el método de conveniencia setOnMouseClicked() Como se muestra abajo.
playButton.setOnMouseClicked((new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
System.out.println("Hello World");
pathTransition.play();
}
}));
Ejemplo
El siguiente programa es un ejemplo que demuestra el manejo de eventos en JavaFX usando los métodos de conveniencia.
Guarde este código en un archivo con el nombre 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);
}
}
Compile y ejecute el archivo java guardado desde el símbolo del sistema utilizando los siguientes comandos.
javac ConvinienceMethodsExample.java
java ConvinienceMethodsExample
Al ejecutarse, el programa anterior genera una ventana JavaFX como se muestra a continuación. Aquí haga clic en el botón de reproducción para iniciar la animación y haga clic en el botón de detener para detener la animación.