Writing GUI applications requires that program control be driven by the user’s interaction with the GUI. When the user moves the mouse, clicks on a button, or selects an item from a menu an “event” occurs.
The javafx.event
package provides the basic framework for FX events. The
Event
class serves as the base class for JavaFX events. Associated with each
event is an event source, an event target, and an event type.
Button
object) which generate an ActionEvent (e.g., when the button is clicked). The source implements the EventTarget
interface.EventHandler
or InvalidationListener
.MouseEvent
has the following types: ANY
, MOUSE_CLICKED
, MOUSE_PRESSED
, MOUSE_RELEASED
, MOUSE_MOVED
, MOUSE_DRAGGED
, MOUSE_ENTERED
, MOUSE_EXITED
, MOUSE_ENTERED_TARGET
, MOUSE_EXITED_TARGET
, and DRAG_DETECTED
.The operating system or windowing system captures generated events and notifies the listener objects when a type of event they are listening for has occurred. The operating system notifies the listener object by sending a message to (calling) the event handling method. If no listener object is subscribed to listen for the event that occurred, the event is ignored.
There are many subclasses of the Event
class:
ActionEvent
— widely used to indicate things like when a button is pressed.MouseEvent
— indicates mouse activity.DragEvent
— indicates a drag-and-drop gesture.KeyEvent
— indicates that a keystroke has occurred.ScrollEvent
— indicates scrolling by mouse wheel, track pad, touch screen, etc…TouchEvent
— indicates a touch screen actionHere we will just consider ActionEvent
s. Other types of events are handled
in a similar way. When a Button
is pressed, it generates an ActionEvent
.
If I want my program to respond to a button click, I need to tell the button
what code should run.
We need to pass an object to setOnAction()
that implements the EventHandler
interface. The EventHandler
interface is a functional interface with one method:
void handle(T event)
.
It seems silly to need a separate class for ever event we want to handle. Also, if we want to access private attributes of the GUI, we can’t do that if we are in a different class. Solution: implement the interface as an inner class.
Implement a class, Question
that contains a start(Stage stage)
method.
In the start()
method, you must create a Button
object and set the
onAction event to an object from an inner class of the Question
class.
The inner class must implement the EventHandler<ActionEvent>
interface
causing "clicked" to be printed to the console whenever the event is triggered.
Since we will only create one instance of this handler class, we could declare it as an anonymous inner class.
Create an EventHandler<ActionEvent>
reference called handler
and
assign it an object from an anonymous inner class that implements the
EventHandler<ActionEvent>
interface. The handler must display
"clicked" to the console whenever triggered.
Functional interfaces can be implemented with a lambda expression which have a more concise syntax.
Create an EventHandler<ActionEvent>
reference called handler
and
assign it to a lambda expression that causes the handler
to
display "clicked" to the console whenever triggered.
Method references provide even more concise syntax. Here we pass a
method reference to setOnAction()
.
Need more practice? Head over to the practice page.