JavaFX Event Example
This is a JavaFX Event Example. In general, the term event is used to describe an occurrence of interest. In a GUI application, an event is an occurrence of a user interaction with the application. Clicking the mouse and pressing a key on the keyboard are examples of events in a JavaFX application.
The following table shows an overview of the whole article:
Table Of Contents
The following examples uses Java SE 7 and JavaFX 2.2.
1. Introduction
An event in JavaFX is represented by an object of the javafx.event.Event
class or any of its subclasses.
Every event in JavaFX has three properties:
- An event source
- An event target
- An event type
When an event occurs in an application, you typically perform some processing by executing a piece of code. The piece of code that is executed in response to an event is known as an event handler or an event filter. When you want to handle an event for a UI element, you need to add event handlers to the UI element, for example, a Window, a Scene, or a Node. When the UI element detects the event, it executes your event handlers.
The UI element that calls event handlers is the source of the event for those event handlers. When an event occurs, it passes through a chain of event dispatchers. The source of an event is the current element in the event dispatcher chain. The event source changes as the event passes through one dispatcher to another in the event dispatcher chain.
The event target is the destination of an event. The event target determines the route through which the event travels during its processing. Suppose a mouse click occurs over a Circle node. In this case, the Circle
node is the event target of the mouse-clicked event.
The event type describes the type of the event that occurs. Event
types are defines in a hierarchical fashion. Each event type has a name and a supertype.
The three properties that are common to all events in JavaFX are represented by objects of three different classes. Specific events define additional event roperties. For example, the event class to represent a mouse event adds properties to describe the location of the mouse cursor, state of the mouse buttons, among others.
2. Event Class Hierarchy
The Event class provides properties and methods that are common to all events. The getSource()
method returns an Object, which is the source of the event. The Event
class inherits this method from the EventObject class. The getTarget()
method returns an instance of the EventTarget interface, which is the target of the event. The getEventType()
method returns an object of the EventType
class, which indicates the type of the event.
The Event
class contains consume()
and isConsumed()
methods. As noted before, an event travels from one element to another in an event-dispatching chain. Calling the consume()
method on an Event
object indicates that the event has been consumed and no further processing is required. After the consume()
method is called, the event does not travel to the next element in the event-processing chain. The isConsumed()
method returns true if the consume()
method has been called, otherwise, it returns false.
Specific Event
subclasses define more properties and methods. For example, the MouseEvent class defines getX()
and getY()
methods that return the x and y coordinates of the mouse cursor relative to the source of the event.
3. Event Targets
An event target is a UI element that can respond to events. Technically, a UI element that wants to respond to events must implement the EventTarget
interface. That is, in JavaFX, implementing the EventTarget
interface makes a UI element eligible to be an event target.
The Window
, Scene
, and Node
classes implement the EventTarget
interface. This means that all nodes, including windows and scenes, can respond to events. The classes for some UI elements, for example, Tab, TreeItem, and MenuItem, do not inherit from the Node
class. They can still respond to events because they implement the EventTarget
interface. If you develop a custom UI element, you will need to implement this interface if you want your UI element to respond to events.
The responsibility of an event target is to build a chain of event dispatchers, which is also called the event route. An event dispatcher is an instance of the EventDispatcher interface. Each dispatcher in the chain can affect the event by handling and consuming. An event dispatcher in the chain can also modify the
event properties, substitute the event with a new event, or chain the event route.
Typically, an event target route consists of dispatchers associated with all UI elements in the container-child hierarchy. Suppose you have a Circle
node placed in an HBox, which is placed in a Scene
. The Scene
is added to a Stage. If the mouse is clicked on the Circle
, the Circle
becomes the event target. The Circle
builds an event dispatcher chain whose route will be, from head to tail, the Stage
, Scene
, HBox
, and Circle
.
4. Event Types
An instance of the EventType class defines an event type. Why do you need a separate class to define event types? Aren’t separate event classes, for example, KeyEvent, MouseEvent, for each event sufficient to define event types? Can’t you distinguish one event from another based on the event class? The EventType
class is used to further classify the events within an event class. For example, the MouseEvent
class only tells us that the user has used the mouse. It does not tell us the details of the mouse use, for example, whether the mouse was pressed, released, dragged, or clicked.
The EventType
class is used to classify these subevent types of an event. The EventType
class is a generic class whose type parameter is defined as follows:
EventType<T extends Event>
Event
types are hierarchical. They are hierarchical by implementation, not by class inheritance. Each event type has a name and a supertype. The getName()
and setSuperType()
methods in the EventType
class return the name and supertype of an event type. The constant Event.ANY
, which is the same as the constant EventType.ROOT
, is the supertype of all events in JavaFX.
5. Event Processing Mechanism
When an event occurs, several steps are performed as part of the event processing:
- Event target selection
- Event route construction
- Event route traversal
5.1 Event Target Selection
The first step in the event processing is the selection of the event target. Recall that an event target is the destination node of an event. The event target is selected based on the event type.
For mouse events, the event target is the Node
at the mouse cursor. Multiple nodes can be available at the mouse cursor. For example, you can have a Circle
placed over a Rectangle. The topmost node at the mouse cursor is selected as the event target.
The event target for key events is the node that has focus. How a node gets the focus depends on the type of the node. For example, a TextField may gain focus by clicking the mouse inside it or using the focus traversal keys such as Tab or Shift + Tab on the Windows format. Shapes such as Circles or Rectangles do not get focus by default.
If you want them to receive key events, you can give them focus by calling the
requestFocus()
method of the Node
class.
JavaFX supports touch and gesture events on touch-enabled devices. A touch event is generated by touching a touch screen. Each touch action has a point of contact called a touch point. It is possible to touch a touch screen with multiple fingers, resulting in multiple touch points. Each state of a touch point, for example, pressed, released, and so forth, generates a touch event. The location of the touch point determines the target of the touch event. For example, if the location of the touch event is a point within a circle, the circle becomes the target of the touch event. In case of multiple nodes at the touch point, the topmost node is selected as the target.
Users can interact with a JavaFX application using gestures. Typically, a gesture on a touch screen and a track pad consists of multiple touch points with touch actions. Examples of gesture events are rotating, scrolling, swiping, and zooming. A rotating gesture is performed by rotating two fingers around each other.
A scrolling gesture is performed by dragging a finger on touch screen. A swiping gesture is performed by dragging a finger on the touch screen in one direction. A zooming gesture is performed to scale a node by dragging two fingers apart or closer.
The target for gesture events are selected depending on the type of gesture. For direct gestures, for example, gestures performed on touch screens, the topmost node at the center point of all touch points at the start of the gesture is selected as the event target. For indirect gestures, for example, gestures performed on a track pad, the topmost node at the mouse cursor is selected as the event target.
5.2 Event Route Construction
An event travels through event dispatchers in an event dispatch chain. The event dispatch chain is the event route. The initial and default routes for an event are determined by the event target. The default event route consists of the container-children path starting at the stage to the event target node.
Suppose you have placed a Circle
and a Rectangle
in an HBox
and the HBox
is the root node of the Scene
of a Stage
. When you click the Circle
, the circle becomes the event target. The Circle
constructs the default event route, which is the path starting at the stage to the event target (the circle).
In fact, an event route consists of event dispatchers that are associated with nodes. However, for all practical and understanding purposes, you can think of the event route as the path comprising the nodes.
Typically, you do not deal with event dispatchers directly.
5.3 Event Route Traversal
An event route traversal consists of two phases:
- Capture phase
- Bubbling phase
An event travels through each node in its route twice: once during the capture phase and once during the bubbling phase. You can register event filters and event handlers to a node for specific events types.
The event filters and event handlers registered to a node are executed as the event passes through the node during the capture phase and the bubbling phase, respectively. The event filters and handlers are passed in the reference of the current node as the source of the event. As the event travels from one node to another, the event source keeps changing. However, the event target remains the same from the start to the finish of the event route traversal.
During the route traversal, a node can consume the event in event filters or handlers, thus completing the processing of the event. Consuming an event is simply calling the consume()
method on the event object.
When an Event
is consumed, the event processing is stopped, even though some of the nodes in the route were not traversed at all.
6. Handling Events
6.1 The Code
FxEventExample1.java
import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.TextArea; import javafx.scene.input.MouseEvent; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.stage.Stage; public class FxEventExample1 extends Application { // Create the LoggingArea private TextArea loggingArea = new TextArea(""); public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { // Create a coral Circle Circle circle = new Circle (150, 150, 50); circle.setFill(Color.CORAL); // Create a MouseEvent filter EventHandler<MouseEvent> mouseEventFilter = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { writelog("Mouse event filter has been called"); } }; // Create a MouseEvent handler EventHandler<MouseEvent> mouseEventHandler = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { writelog("Mouse event handler has been called"); } }; // Register the MouseEvent filter and handler to the Circle for mouse-clicked events circle.addEventFilter(MouseEvent.MOUSE_CLICKED, mouseEventFilter); circle.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEventHandler); // Create the VBox VBox root = new VBox(); // Add the children to the VBox root.getChildren().addAll(circle, loggingArea); // Set the Padding and Border for the VBox root.setStyle("-fx-padding: 10;" + "-fx-border-style: solid inside;" + "-fx-border-width: 2;" + "-fx-border-insets: 5;" + "-fx-border-radius: 5;" + "-fx-border-color: blue;"); // Create the Scene Scene scene = new Scene(root, 400,300); // Add the Scene to the Stage stage.setScene(scene); // Set the Title of the Stage stage.setTitle("An Example about Registering Event Filters and Handlers"); // Display the Stage stage.show(); } // Helper Method for Logging private void writelog(String text) { this.loggingArea.appendText(text + "\n"); } }
FxEventExample2.java
import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.TextArea; import javafx.scene.input.MouseEvent; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.stage.Stage; public class FxEventExample2 extends Application { // Create the LoggingArea private TextArea loggingArea = new TextArea(""); public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { // Create a coral Circle Circle circle = new Circle (150, 150, 50); circle.setFill(Color.CORAL); // Create the VBox VBox root = new VBox(); // Add the children to the VBox root.getChildren().addAll(circle, loggingArea); // Set the Padding and Border for the VBox root.setStyle("-fx-padding: 10;" + "-fx-border-style: solid inside;" + "-fx-border-width: 2;" + "-fx-border-insets: 5;" + "-fx-border-radius: 5;" + "-fx-border-color: blue;"); // Create the Scene Scene scene = new Scene(root); // Register three handlers for the circle that can handle mouse-clicked events // // This will be called last circle.addEventHandler(MouseEvent.ANY, new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleAnyMouseEvent(event); } }); // This will be called first circle.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleMouseClicked("addEventHandler()", event); } }); // This will be called second circle.setOnMouseClicked(new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleMouseClicked("setOnMouseClicked()", event); } }); // Add the Stage to the Scene stage.setScene(scene); // Set the Title of the Stage stage.setTitle("An Example about the Execution Order of Events"); // Display the Stage stage.show(); } public void handleMouseClicked(String registrationMethod, MouseEvent e) { // Print a message for a mouse click this.loggingArea.appendText(registrationMethod + ": MOUSE_CLICKED handler detected a mouse click.\n"); } public void handleAnyMouseEvent(MouseEvent e) { // Print a message only for mouse-clicked events, ignoring // other mouse events such as mouse-pressed, mouse-released, etc. if (e.getEventType() == MouseEvent.MOUSE_CLICKED) { this.loggingArea.appendText("MouseEvent.ANY handler detected a mouse click.\n"); } } }
Handling an event means executing the application logic in response to the occurrence of the event. The application logic is contained in the event filters and handlers, which are objects of the EventHandler interface, as shown in the following code:
public interface EventHandler<T extends Event> extends EventListener { void handle(T event); }
The EventHandler
class is a generic class in the javafx.event
package. It extends the EventListener marker interface, which is in the java.util
package. The handle()
method receives the reference of the event object, for example, the reference of the KeyEvent
, MouseEvent
, among others.
Both event filters and handlers are objects of the same EventHandler
interface. You cannot tell whether an EventHandler
object is an event filter or an event handler by just looking at it. In fact, you can register the same EventHandler
object as event filters as well as handlers at the same time. The distinction between the two is made when they are registered to a node. Nodes provide different methods to register them. Internally, nodes know whether an EventHandler
object was registered as an event filter or a handler.
Another distinction between them is made based on the event traversal phase in which they are called. During the event capture phase, the handle()
method of registered filters is called, whereas the handle()
method of registered handlers is called in the event bubbling phase.
6.2 Creating Event Filters and Handlers
Creating event filters and handlers is as simple as creating objects of the class that implement the EventHandler
interface.
EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { /* Event handling code goes here */ } };
6.3 Registering Event Filters and Handlers
If you want a node to process events of specific types, you need to register event filters and handlers for those event types to the node. When the event occurs, the handle()
method of the registered event filters and handlers for the node are called following the rules discussed in the previous sections. If the node is no longer interested in processing the events, you need to unregister the event filters and handlers from the node.
Registering and unregistering event filters and handlers are also known as adding and removing event filters and handlers, respectively.
JavaFX provides two ways to register and unregister event filters and handlers to nodes:
- Using the addEventFilter(), addEventHandler(), removeEventFilter(), and removeEventHandler() methods
- Using the onXXX convenience properties
6.3.1 Using addXXX() and removeXXX() Methods
You can use the addEventFilter()
and addEventHandler()
methods to register event filters and handlers to nodes, respectively. These methods are defined in the Node
class, Scene
class, and Window
class. Some classes can be event targets. However, they are not inherited from the Node
class. The classes provide only the addEventHandler()
method for event handlers registration, such as:
- <T extends Event> void addEventFilter(EventType<T> eventType, EventHandler<? super T> eventFilter)
- <T extends Event> void addEventHandler(EventType<T> eventType, EventHandler<? super T> eventHandler)
These methods have two parameters. The first parameter is the event type and the second is an object of the EventHandler
interface.
You can handle mouse-clicked events for a Circle
using the following snippet of code:
// Create a coral Circle Circle circle = new Circle (150, 150, 50); circle.setFill(Color.CORAL); // Create a MouseEvent filter EventHandler<MouseEvent> mouseEventFilter = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { writelog("Mouse event filter has been called"); } }; // Create a MouseEvent handler EventHandler<MouseEvent> mouseEventHandler = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { writelog("Mouse event handler has been called"); } }; // Register the MouseEvent filter and handler to the Circle for mouse-clicked events circle.addEventFilter(MouseEvent.MOUSE_CLICKED, mouseEventFilter); circle.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEventHandler);
This code creates two EventHandler
objects, which prints a message on the console. At this stage, they are not event filters or handlers. They are just two EventHandler
objects. Note that giving the reference variables names and printing messages that use the words filter and handler does not make any difference in their status as filters and handlers. The last two statements register one of the EventHandler
objects as an event filter and another as an event handler. Both are registered for the mouse-clicked event.
// Create a MouseEvent handler EventHandler<MouseEvent> mouseEventHandler = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { writelog("Mouse event handler has been called"); } }; // Register the MouseEvent filter and handler to the Circle for mouse-clicked events circle.addEventFilter(MouseEvent.MOUSE_CLICKED, mouseEventFilter); circle.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEventHandler);
Registering the same EventHandler
object as event filters as well as handlers is allowed.
To unregister an event filter and an event handler, you need to call the removeEventFilter()
and removeEventHandler()
methods, respectively:
- <T extends Event> void removeEventFilter(EventType<T> eventType, EventHandler<? super T> eventFilter)
- <T extends Event> void removeEventHandler(EventType<T> eventType, EventHandler<? super T> eventHandler)
6.3.3 Using onXXX Convenience Properties
The Node
, Scene
, and Window
classes contain event properties to store event handlers of some selected event types. The property names use the event type pattern. They are named as onXXX
.
For example, the onMouseClicked
property stores the event handler for the mouse-clicked event type, the onKeyTyped
property stores the event handler for the key-typed event, and so on. You can use the setOnXXX()
methods of these properties to register event handlers for a node.
For example, use the setOnMouseClicked()
method to register an event handler for the mouse-clicked event and use the setOnKeyTyped()
method to register an event handler for the key-typed event, and so on. The setOnXXX()
methods in various classes are known as convenience methods for registering event handlers.
You need to remember some points about the onXXX
convenience properties:
- They only support the registration of event handlers, not event filters. If you need to register event filters, use the addEventFilter() method.
- They only support the registration of one event handler for a node. Multiple event handlers for a node may be registered using the addEventHandler() method.
- These properties exist only for the commonly used events for a node type. For example, the onMouseClicked property exists in the Node and Scene classes, but not the Window class; the onShowing property exists in the Window class, but not in the Node and Scene classes.
The class FxEventExample1 works the same as the FxEventExample2. In the sceond example, you have used the onMouseClicked
property of the Node
class to register the mouse-clicked event handler for the circle.
Notice that to register the event filter, you have to use the addEventFilter()
method as before.
The convenience event properties do not provide a separate method to unregister the event handler.
Setting the property to null unregisters the event handler that has already been registered:
// Register an event handler for the mouse-clicked event circle.setOnMouseClicked(eventHandler); ... // Later, when you are no longer interested in processing the mouse-clicked event, unregister it. circle.setOnMouseClicked(null);
Classes that define the onXXX
event properties also define getOnXXX()
getter methods that return the reference of the registered event handler. If no event handler is set, the getter method returns null.
6.4 The GUI
The following image shows the GUI of the first program:
Run the second program and click inside the circle. You will get the same output you got when running the first program.
7. Execution Order of Event Filters and Handlers
7.1 The Code
FxEventExample3.java
import javafx.application.Application; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import static javafx.scene.input.MouseEvent.MOUSE_CLICKED; import javafx.scene.control.TextArea; public class FxEventExample3 extends Application { // Create the LoggingArea private TextArea loggingArea = new TextArea(""); public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { // Create a Circle Circle circle = new Circle (50, 50, 50); circle.setFill(Color.CORAL); // Create a Rectangle Rectangle rectangle = new Rectangle(100, 100); rectangle.setFill(Color.TAN); // Create the HBox HBox hbox = new HBox(); // Set Padding and Spacing of the HBox hbox.setPadding(new Insets(20)); hbox.setSpacing(20); // Add the children to the HBox hbox.getChildren().addAll(circle, rectangle); // CReate the VBox VBox root = new VBox(); // Set Padding and Spacing of the VBox root.setPadding(new Insets(20)); root.setSpacing(20); // Add the children to the VBox root.getChildren().addAll(hbox, loggingArea); // Create the Scene Scene scene = new Scene(root); // Create two EventHandlders EventHandler<MouseEvent> filter = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleEvent("Capture",event); } }; EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleEvent("Bubbling",event); } }; // Register the Event Filters stage.addEventFilter(MOUSE_CLICKED, filter); scene.addEventFilter(MOUSE_CLICKED, filter); root.addEventFilter(MOUSE_CLICKED, filter); circle.addEventFilter(MOUSE_CLICKED, filter); // Register the Event Handlers stage.addEventHandler(MOUSE_CLICKED, handler); scene.addEventHandler(MOUSE_CLICKED, handler); root.addEventHandler(MOUSE_CLICKED, handler); circle.addEventHandler(MOUSE_CLICKED, handler); // Set the Padding and Border for the VBox root.setStyle("-fx-padding: 10;" + "-fx-border-style: solid inside;" + "-fx-border-width: 2;" + "-fx-border-insets: 5;" + "-fx-border-radius: 5;" + "-fx-border-color: blue;"); // Add the Scene to the Stage stage.setScene(scene); // Set the Title of the Stage stage.setTitle("An Example about Event Capture and Bubbling"); // Display the Stage stage.show(); } // Helper Method for Event-Handling public void handleEvent(String phase, MouseEvent e) { // Get type, source and target of the Event String type = e.getEventType().getName(); String source = e.getSource().getClass().getSimpleName(); String target = e.getTarget().getClass().getSimpleName(); // Get coordinates of the mouse cursor relative to the Event Source double x = e.getX(); double y = e.getY(); // Log the Informations this.loggingArea.appendText(phase + ": Type=" + type + ", Target=" + target + ", Source=" + source + ", location(" + x + ", " + y + ")\n"); } }
There are some execution order rules for event filters and handlers for both similar and different nodes:
Event filters are called before event handlers. Event filters are executed from the
topmost parent to the event target in the parent-child order. Event handlers are executed in the reverse order of the event filters. That is, the execution of the event andlers starts at the event target and moves up in the child-parent order.
For the same node, event filters and handlers for a specific event type are called before the event filters and handlers for generic types. Suppose you have registered event handlers to a node for MouseEvent.ANY
and MouseEvent.MOUSE_CLICKED
. Event handlers for both event types are capable of handling mouse-clicked events. When the mouse is clicked on the node, the event handler for the MouseEvent.MOUSE_CLICKED
event type is called before the event handler for the MouseEvent.ANY
event type. Note that a mouse-pressed event and a mouse-released event occur before a mouse-clicked event occurs. In our example, these events will be handled by the event handler for the MouseEvent.ANY
event type.
The order in which the event filters and handlers for the same event type for a node are executed is not specified. There is one exception to this rule. Event handlers registered to a node using the addEventHandler()
method are executed before the event handlers registered using the setOnXXX()
convenience methods.
7.2 The GUI
The above program demonstrates the execution order of the event filters and handlers for different nodes. The program adds a Circle
and a Rectangle
to an HBox
. An event filter and an event handler are added to the Stage
, Scene
, HBox
, and Circle
for the mouse-clicked event.
Run the program and click anywhere inside the circle. The output shows the order in which filters and handlers are called. The output contains the event phase, type, target, source, and location.
8. Consuming Events
8.1 The Code
FxEventExample4.java
import javafx.application.Application; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.input.MouseEvent; import static javafx.scene.input.MouseEvent.MOUSE_CLICKED; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.scene.control.TextArea; public class FxEventExample4 extends Application { // Create the CheckBox private CheckBox consumeEventCbx = new CheckBox("Consume Mouse Click at Circle"); // Create the LoggingArea private TextArea loggingArea = new TextArea(""); public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { // Create a Circle Circle circle = new Circle (50, 50, 50); circle.setFill(Color.CORAL); // Create a Rectangle Rectangle rectangle = new Rectangle(100, 100); rectangle.setFill(Color.TAN); // Create the HBox HBox hbox = new HBox(); // Set Padding and Spacing of the HBox hbox.setPadding(new Insets(20)); hbox.setSpacing(20); // Add the children to the HBox hbox.getChildren().addAll(circle, rectangle, consumeEventCbx); // CReate the VBox VBox root = new VBox(); // Set Padding and Spacing of the VBox root.setPadding(new Insets(20)); root.setSpacing(20); // Add the children to the VBox root.getChildren().addAll(hbox, loggingArea); // Create the Scene Scene scene = new Scene(root); // Register mouse-clicked event handlers to all nodes, // except the rectangle and CheckBox EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleEvent(event); } }; EventHandler<MouseEvent> circleMeHandler = new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { handleEventforCircle(event); } }; // Add the Event Handler stage.addEventHandler(MOUSE_CLICKED, handler); scene.addEventHandler(MOUSE_CLICKED, handler); root.addEventHandler(MOUSE_CLICKED, handler); circle.addEventHandler(MOUSE_CLICKED, circleMeHandler); // Set the Padding and Border for the VBox root.setStyle("-fx-padding: 10;" + "-fx-border-style: solid inside;" + "-fx-border-width: 2;" + "-fx-border-insets: 5;" + "-fx-border-radius: 5;" + "-fx-border-color: blue;"); // Add the Scene to the Stage stage.setScene(scene); // Set the Title of the Stage stage.setTitle("An Example about Consuming Events"); // Display the Stage stage.show(); } // Helper Method for Event Handling public void handleEvent(MouseEvent e) { print(e); } public void handleEventforCircle(MouseEvent e) { print(e); if (consumeEventCbx.isSelected()) { e.consume(); } } // Helper Method for Logging public void print(MouseEvent e) { // Get type, source and target of the Event String type = e.getEventType().getName(); String source = e.getSource().getClass().getSimpleName(); String target = e.getTarget().getClass().getSimpleName(); // Get coordinates of the mouse cursor relative to the event source double x = e.getX(); double y = e.getY(); // Log the Informations this.loggingArea.appendText("Type=" + type + ", Target=" + target + ", Source=" + source + ", location(" + x + ", " + y + ")\n"); } }
An event is consumed by calling its consume()
method. The event class contains the method and it is inherited by all event classes. Typically, the consume()
method is called inside the handle() method of the event filters and handlers.
Consuming an event indicates to the event dispatcher that the event processing is complete and that the event should not travel any farther in the event dispatch chain.
If an event is consumed in an event filter of a node, the event does not travel to any child node. If an event is consumed in an event handler of a node, the event does not travel to any parent node.
All event filters or handlers for the consuming node are called, irrespective of which filter or handler consumes the event. Suppose you have registered three event handlers for a node and the event handler, which is called first, consumes the event. In this case, the other two event handlers for the node are still called.
If a parent node does not want its child nodes to respond to an event, it can consume the event in its event filter. If a parent node provides a default response to an event in an event handler, a child node can provide a specific response and consume the event, thus suppressing the default response of the parent.
Typically, nodes consume most input events after providing a default response. The rule is that all event filters and handlers of a node are called, even if one of them consumes the event. This makes it possible for developers to execute their event filters and handlers for a node even if the node consumes the event.
8.2 The GUI
The class FxEventExample4 shows how to consume an event. The following image shows the screen when you run the program.
9. Download Source Code
This was an example of javafx.event.Event
You can download the full source code of this example here: JavaFxEventExample.zip
Thanks a lot.Nice Explanation.