When a user does something, such as clicks a button or selects an item, the application needs to know about it. Many Java-based user interface frameworks follow the Observer design pattern to communicate user input to the application logic. So does IT Mill Toolkit. The design pattern involves two kinds of elements: an object and a number of observers that listen for events regarding the object. When an event related to the object occurs, the observers receive a notification regarding the event. In most cases there is only one observer, defined in the application logic, but the pattern allows for multiple observers. As in the event-listener framework of Java SE, we call the observing objects listeners.
In the ancient times of C programming, callback functions filled largely the same need as listeners do now. In object-oriented languages, we have only classes and methods, not functions, so the application has to give a class interface instead of a callback function pointer to the framework. However, IT Mill Toolkit supports defining a method as a listener as well.
Events can serve many kinds of purposes. In IT Mill Toolkit, the usual purpose of events is handling user interaction in a user interface. Session management can require special events, such as time-out, in which case the event is actually the lack of user interaction. Time-out is a special case of timed or scheduled events, where an event occurs at a specific date and time or when a set time has passed. Database and other asynchronous communications can cause events too.
To receive events of a particular type, an application must include a
class that implements the corresponding listener interface. In small
applications, the application class itself could implement the needed
listener interfaces. Listeners are managed by the
AbstractComponent class, the base class of all
user interface components. This means that events regarding any
component can listened to. The listeners are registered in the
components with addListener() method.
Most components that have related events define their own
event class and corresponding listener classes. For example, the
Button has
Button.ClickEvent events, which can be
listened to through the Button.ClickListener
interface. This allows an application to listen to many different
kinds of events and to distinguish between them at class level. This
is usually not enough, as applications usually have many components
of the same class and need to distinguish between the particular
components too. We will look into that more closely below. The
purpose of this sort of class level separation is to avoid having to
make type conversions in the handlers.
Notice that many listener interfaces inherit the
java.util.EventListener superinterface, but it
is not generally necessary to inherit it.
Figure 3.3, “Class Diagram of a Button Click Listener” illustrates an example
where an application-specific class inherits the
Button.ClickListener interface to be able to
listen for button click events. The application must instantiate the
listener class and register it with
addListener(). When an event occurs, an
event object is instantiated, in this case a
ClickEvent. The event object knows the related
UI component, in this case the Button.
Section 4.4, “Handling Events with Listeners” goes into details of handling events in practice.