Event-driven Programming

Learning Outcomes

In this round you will learn to implement graphical user interfaces with the JavaFX library. The round also revises the principles of event driven programming and you will learn to utilize events in Java programs.

Events vs control structures

Implementing event-driven programs has been a topic also on the earlier courses. On Programming 1 the basics were covered with Python’s Tkinter library. On Programming 2 the signal and slot mechanism of Qt was used to implement the same functionality. On Programming 3 the JavaFX library is used. Let’s first take a short look at event driven programming in general.

Event

So far we have implemented our programs as sequestial where the execution of the program is defined by its control structures. Event driven programming differs from the traditional in that there the program goes forward controlled by different types of internal and external events. This means that the program execution can no longer be followed as a clear sequence. An event is a notification on something happening in the program that might be interesting to the execution of the program. Events are for example generated by the user of the program (mouse clicks and key presses, touch screen gestures) and internal timers in the program. Also the operating system, some software component or another program can produce an event that the program needs to react to. As events can be generated from a variety of sources and on very different sides of the program, the program no longer has a straighforward execution. Testing event-driven programs can thus also be trickier. Code handling the events is also such that it is not executed unless an event it handles occurs.

For managing event the program uses an event loop (or main loop). The event loop listens to the events and when one occurs, the event starts handler function or functions matching it.

Event loop

The events are handled through a queue. As the event occurs, it is placed into the queue and the loop processes the events from it to the handlers.

Event in JavaFX

Even though the basic principles are the same, each development framework and library has its own approach to handling events. In Qt event handling was done through signals and slots. JavaFX also has its own structured way to catch an event, match it with the correct target and make it possible for the program to handle it if necessary. The basic idea in still very similar: events possible interesting to program functionality get raised and the program reacts to them with handlers registered to handle them.

In JavaFX an event is an instance of javafx.event.Event or some of its derived classes. JavaFX offers several event types such as KeyEvent for keyboard key presses and MouseEvent and ScrollEvent for events produces by mouse gestures. Own events can be implemented by deriving them from Event. Each event has:

  • Target, which indicates the node on the user interface on which the action occurred

  • Source, which indicates the source from which the event is generated. For example the mouse or the keyboard.

  • Type, which indicates the type of event. For example key pressed or mouse clicked.

Handling the event needs to take into account the general structure of a JavaFX user interface. When an event occurs it is handled with the following stages:

  1. Target selection. JavaFX deducts which node i.e. a UI element is the target for the event. This is meaningful for the future handling of the event. For example, the target for a mouse click event is the node on which the mouse cursor was located. or in case of continuous gesture events for example on a touch screen, the target is the node at the center point of all touches at the beginning of the gesture.

  2. Route construction. An Event Dispatch chain is constructed for the initial route of the event. The route is the path from the stage (the top level JavaFX container) to the source node (the target element).

  3. Event capture. The event travels from the root node to all nodes in the dispatch chain (from top to bottom). If there is a filter registered for the event in any of these nodes, it will be executed. Even if there are no filters registered, finally the target node is reached and it processes the event.

  4. Event bubbling. The event travels from the target node back to the stage node (from bottom to top). If there is a handler registered for the event, it will be executed. If none of these nodes have handlers to handle the event, once the event reaches the top, the process is completed.

The event is handled in the bubbling phase. More than one element can react to the event. The event is processed by filters and handlers that implement the EventHandler interface and are registered to a specific event. The difference between a filter and a handler is the phase when they are executed. A filter is executed during event capture and the handler in the bubbling phase. Filters give the parent node a way to provide common processing for its children or to intercept the event so that the children won’t act on it.

You can read more on the processing of events from the JavaFX-tutorial. The best picture of everything is gotten by implementing a JavaFX program. Let’s do that next.

Event-driven programming (duration 18:47)

It holds for event-driven programming