Using Events with Components
Events used with the event bus should extend ComponentEvent
. The base type is parameterized with the type of the component firing the event, so that getSource()
can automatically return the right component type.
The second constructor parameter is used to let the user know whether the event has been triggered by a DOM event in the browser or through the component’s server-side API.
Java
Event listeners are of the generic type ComponentEventListener<EventType>
, so you don’t need to create a separate interface for your event type.
You don’t need to implement a separate method for removing an event listener. Instead, the method for adding a listener returns a handle that can be used for removing the listener.
Java
@Tag("input")
public class TextField extends Component {
public Registration addChangeListener(
ComponentEventListener<ChangeEvent> listener) {
return addListener(ChangeEvent.class, listener);
}
// Other component methods omitted
}
The user can then add and remove listeners like this.
Java
TextField textField = new TextField();
Registration registration = textField
.addChangeListener(e -> System.out.println("Event fired"));
// In some other part of the code
registration.remove();
Java
You can connect a component event to a DOM event that will be fired by the element in the browser. To do this, you only need to tell the framework the name of the DOM event to listen to by adding a @DomEvent
annotation to your event class. The framework will automatically add a DOM listener to the element when a component event listener is added.
Java
@DomEvent("change")
public class ChangeEvent extends ComponentEvent<TextField> {
public ChangeEvent(TextField source, boolean fromClient) {
super(source, fromClient);
}
An event can also include additional information about what has happened, e.g. which mouse button was used for a click event. If you use @DomEvent
, any additional constructor parameters should have an @EventData
annotation that tells the framework what data to send from the browser.
Java
@DomEvent("click")
public class ClickEvent extends ComponentEvent<NativeButton> {
public ClickEvent(NativeButton source, boolean fromClient,
@EventData("event.button") int button) {
super(source, fromClient);
this.button = button;
}
public int getButton() {
return button;
}
}
The @EventData
definition is run as JavaScript in the browser with the DOM event available as event
and the element to which the listener was added available as element
. See the javadocs for DomListenerRegistration.addEventData
for more information about how event data is collected and sent to the server.
It is sometimes not appropriate to send all DOM events to the server, but instead determine whether to send an event based on something related to the event. To achieve this, you can add define a filter
in the @DomEvent
annotation.
Java
Some kinds of events are fired very frequently while the user is doing something, like text input events while the user is typing. The rate of sending events to the server can be configured using different debounce
settings in the @DomEvent
annotation. Debouncing always requires a timeout
in milliseconds and one or several phases of a burst for which an event should be sent to the server.
Listening for the
LEADING
phase means that an event will be sent to the server at the beginning of a burst, but subsequent events will be dropped until one timeout period has passed without any new events. This may be useful for things like button clicks if you want to prevent accidental double submissions.With the
INTERMEDIATE
phase, there will be periodical events to the server while a burst is ongoing. Another event will not be sent to the server until the timeout period has passed since the last event was sent. This may be useful for tings like text input if you want to react continuously while the user is typing.The
TRAILING
phase is triggered at the end of a burst, when the timeout period has passed without any further events. This may be useful for things like text input if you want to react only when the user stops typing.
In this example, an input
event will be sent to the server when the user has been typing, but there has been half a second since the last time some input was made.
Java
@DomEvent(value = "input",
debounce = @DebounceSettings(
timeout = 250,
phases = DebouncePhase.TRAILING))
public class InputEvent extends ComponentEvent<TextField> {
@EventData("element.value") String value) {
super(source, fromClient);
this.value = value;
}
public String getValue() {
return value;
}
}
You can configure your event to be active for several phases at once, e.g. to both receive an event for the LEADING
phase immediately when a burst starts but also INTERMEDIATE
events while the burst goes on.
Java
@DomEvent(value = "input",
debounce = @DebounceSettings(
timeout = 500,
phases = {DebouncePhase.LEADING,
DebouncePhase.INTERMEDIATE }))
public class ContiniousInputEvent extends ComponentEvent<TextField> {
private String value;
public ContiniousInputEvent(TextField source, boolean fromClient,
@EventData("element.value") String value) {
super(source, fromClient);
this.value = value;
}
public String getValue() {
return value;
}
Note | If both filter and are configured at once, only events that pass the filter are considered when determining whether a burst has ended. |