summaryrefslogtreecommitdiffstats
path: root/documentation/architecture/architecture-events.asciidoc
blob: e273a28e972e60c2253fab1fb68c0903708942f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
---
title: Events and Listeners
order: 4
layout: page
---

[[architecture.events]]
= Events and Listeners

Vaadin offers an event-driven programming model for handling user interaction.
When a user does something in the user interface, such as clicks a button or
selects an item, the application needs to know about it. Many Java-based user
interface frameworks follow the __Event-Listener pattern__ (also known as the
Observer design pattern) to communicate user input to the application logic. So
does Vaadin. The design pattern involves two kinds of elements: an object that
generates ("fires" or "emits") events and a number of listeners that listen for
the events. When such an event occurs, the object sends a notification about it
to all the listeners. In a typical case, there is only one listener.

Events can serve many kinds of purposes. In Vaadin, 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 would actually be 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.

To receive events of a particular type, an application must register a listener
object with the event source. The listeners are registered in the components
with an [methodname]#add*Listener()# method (with a method name specific to the
listener).

Most components that have related events define their own event class and the
corresponding listener class. For example, the [classname]#Button# has
[classname]#Button.ClickEvent# events, which can be listened to through the
[classname]#Button.ClickListener# interface.

In the following, we handle button clicks with a listener implemented as an
anonymous class:

[source, java]
----
final Button button = new Button("Push it!");

button.addClickListener(new Button.ClickListener() {
    public void buttonClick(ClickEvent event) {
        button.setCaption("You pushed it!");
    }
});
----

<<figure.eventlistenerdiagram>> illustrates the case where an
application-specific class inherits the [classname]#Button.ClickListener#
interface to be able to listen for button click events. The application must
instantiate the listener class and register it with
[methodname]#addClickListener()#. It can be an anonymous class, such as the one
above. When an event occurs, an event object is instantiated, in this case a
[classname]#Button.ClickEvent#. The event object knows the related UI component,
in this case the [classname]#Button#.

[[figure.eventlistenerdiagram]]
.Class Diagram of a Button Click Listener
image::img/events-classdiagram-hi.png[width=50%, scaledwidth=75%]

In Java 8, you can implement such functional interfaces with a lambda expression:

[source, java]
----
Button button = new Button("Push it!");

button.addClickListener(event ->
  button.setCaption("You pushed it!"));
----

In the ancient times of C programming, __callback functions__ filled largely the
same need as listeners do now. In object-oriented languages, we usually only
have classes and methods, not functions, so the application has to give a class
interface instead of a callback function pointer to the framework.

<<dummy/../../../framework/application/application-events#application.events,"Handling Events with Listeners">> goes into details of handling events in practice.