Chapter 15
Key Code
The KeyEvent class encapsulates information about key events. Every key event has an associated code that is returned by the getCode() method in KeyEvent. The key codes are constants defined in KeyCode. Table 15.2 lists some constants. KeyCode is an enum type. For use of enum types, see Appendix I. For the key-pressed and key-released events, getCode() returns the value as defined in the table, getText() returns a string that describes the key code, and getCharacter() returns an empty string. For the key-typed event, getCode() returns UNDEFINED and getCharacter() returns the Unicode character or a sequence of characters associated with the key-typed event.
Animation Class
The abstract Animation class provides the core functionalities for animations in JavaFX. PathTransition, FadeTransition, and Timeline are specialized classes for implementing animations.
Key Event
A KeyEvent is fired whenever a key is pressed, released, or typed on a node or a scene. The getCode() method can be used to return the code value for the key.
Mouse event
A Mouse Event is fired when ever a mouse button is pressed, released, clicked, moved, or dragged on a node or a scene. The getButton() method can be used to detect which mouse button is pressed for the event
Functional Interface
A functional interface is an interface with exactly one abstract method. This is also known as a single abstract method (SAM) interface.
Anonymous Inner Class
An anonymous inner class can be used to shorten the code for event handling. Further- more, a lambda expression can be used to greatly simplify the event-handling code for functional interface handlers.
anonymous inner class
An anonymous inner class is an inner class without a name. It combines defining an inner class and creating an instance of the class into one step. Inner-class handlers can be shortened using anonymous inner classes. An anonymous inner class must always extend a superclass or implement an inter- face, but it cannot have an explicit extends or implements clause. An anonymous inner class must implement all the abstract methods in the superclass or in the interface. An anonymous inner class always uses the no-arg constructor from its superclass to create an instance. If an anonymous inner class implements an interface, the con- structor is Object(). An anonymous inner class is compiled into a class named OuterClassName$n. class. For example, if the outer class Test has two anonymous inner classes, they are compiled into Test$1.class and Test$2.class.
event
An event can be defined as a signal to the program that something has happened. Events are triggered by external user actions, such as mouse movements, mouse clicks, and keystrokes. The program can choose to respond to or ignore an event.
event object
An event object contains whatever properties are pertinent to the event. You can identify the source object of an event using the getSource() instance method in the EventObject class. The subclasses of EventObject deal with specific types of events, such as action events, window events, mouse events, and key events. The first three columns in Table 15.1 list some external user actions, source objects, and event types fired. For example, when click- ing a button, the button creates and fires an ActionEvent, as indicated in the first line of this table. Here, the button is an event source object, and an ActionEvent is the event object fired by the source object, as shown in Figure 15.3.
Inner Class or Nested Class
An inner class, or nested class, is defined within the scope of another class. An inner class can reference the data and methods defined in the outer class in which it nests, so you need not pass the reference of the outer class to the constructor of the inner class.
Instance of Observable
An instance of Observable is known as an observable object, which contains the addListener(InvalidationListener listener) method for adding a listener. Once the value is changed in the property, a listener is notified. The listener class should implement the InvalidationListener interface, which uses the invalidated method to handle the property value change.
Inner Class
Inner classes are defined inside another class.
Lambda
Lambda expressions can be used to greatly simplify coding for event handling. Lambda expression is a new feature in Java 8. Lambda expressions can be viewed as an anonymous class with a concise syntax. The data type for a parameter may be explicitly declared or implicitly inferred by the com- piler. The parentheses can be omitted if there is only one parameter without an explicit data type. In the preceding example, the lambda expression is as follows e -> { // Code for processing event e }
Functional Interface
The compiler treats a lambda expression as if it is an object created from an anonymous inner class. In this case, the compiler understands that the object must be an instance of EventHandler<ActionEvent>. Since the EventHandler interface defines the handle method with a parameter of the ActionEvent type, the compiler automatically recognizes that e is a parameter of the ActionEvent type, and the statements are for the body of the handle method. The EventHandler interface contains just one method. The statements in the lambda expression are all for that method. If it contains multiple methods, the com- piler will not be able to compile the lambda expression. So, for the compiler to understand lambda expressions, the interface must contain exactly one abstract method. Such an interface is known as a functional interface or a Single Abstract Method (SAM) interface. Listing 15.4 can be simplified using lambda expressions as shown in Listing 15.5.
event source object
The component that creates an event and fires it is called the event source object, or simply source object or source component. For example, a button is the source object for a button- clicking action event. An event is an instance of an event class. The root class of the Java event classes is java.util.EventObject. The root class of the JavaFX event classes is javafx.event.Event.
Event Handler
The handler object must be an instance of the corresponding event-handler interface to ensure that the handler has the correct method for processing the event. JavaFX defines a unified handler interface EventHandler<T extends Event> for an event T. The handler interface contains the handle(T e) method for processing the event. For example, the handler interface for ActionEvent is EventHandler<ActionEvent>; each handler for ActionEvent should implement the handle(ActionEvent e) method for processing an ActionEvent.
Register handler
The handler object must be registered by the source object. Registration methods depend on the event type. For ActionEvent, the method is setOnAction. For a mouse pressed event, the method is setOnMousePressed. For a key pressed event, the method is setOnKeyPressed.
Handler Object
The handler object must be registered by the source object. Registration methods depend on the event type. For an action event, the method is setOnAction. For a mouse-pressed event, the method is setOnMousePressed. For a key-pressed event, the method is setOnKeyPressed.
Handler Class
The handler object's class must implement the corresponding event-handler interface. JavaFX provides a handler interface EventHandler<T extends Event> for every event class T. The handler interface contains the handle(T e) method for handling event e.
Root Class for Java FX
The root class of the JavaFX event classes is javafx.event.Event, which is a sub- class of java.util.EventObject. The subclasses of Event deal with special types of events, such as action events, window events, mouse events, and key events. If a node can fire an event, any subclass of the node can fire the same type of event.
event-driven programming
When you run a Java GUI program, the program interacts with the user, and the events drive its execution. This is called event-driven programming.
observable object
You can add a listener to process a value change in an observable object. An instance of Observable is known as an observable object, which contains the addListener(InvalidationListener listener) method for adding a listener. The listener class must implement the InvalidationListener interface to override the invalidated(Observable o) method for handling the value change. Once the value is changed in the Observable object, the listener is notified by invoking its invalidated(Observable o) method. Every binding property is an instance of Observable. Listing 15.10 gives an example of observing and handling a change in a DoubleProperty object balance.