How to use the GWT EventBus
When you divide the project into logical parts (for example with MVP), then the different parts sometimes need to communicate. Typical this communication is done by sending status changes, e.g.:
- user logged-in / logged-out.
- user navigated directly via URL to a page, so the menu needs to be updated.
Using the event bus is quite logical in those cases.
To use it you instantiate one EventBus
per app which is then used by all other classes. To achieve this use a static field, factory or dependency injection (GIN in case of GWT).
Example with your own event types:
public class AppUtils{
public static EventBus EVENT_BUS = GWT.create(SimpleEventBus.class);
}
Normally you'd also create your own event types and handlers:
public class AuthenticationEvent extends GwtEvent<AuthenticationEventHandler> {
public static Type<AuthenticationEventHandler> TYPE = new Type<AuthenticationEventHandler>();
@Override
public Type<AuthenticationEventHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(AuthenticationEventHandler handler) {
handler.onAuthenticationChanged(this);
}
}
and the handler:
public interface AuthenticationEventHandler extends EventHandler {
void onAuthenticationChanged(AuthenticationEvent authenticationEvent);
}
Then you use it like this:
AppUtils.EVENT_BUS.addHandler(AuthenticationEvent.TYPE, new AuthenticationEventHandler() {
@Override
public void onAuthenticationChanged(AuthenticationEvent authenticationEvent) {
// authentication changed - do something
}
});
and fire the event:
AppUtils.EVENT_BUS.fireEvent(new AuthenticationEvent());
Mark
Updated on July 09, 2022Comments
-
Mark almost 2 years
I wonder how to use the
EventBus
or whether there are some better solutions to send anEvent
through the project.Widget1
has aButton
.Widget2
has aLabel
, that should change when I press the button. These widgets are in aDockLayout
:RootLayoutPanel rootLayoutPanel = RootLayoutPanel.get(); DockLayoutPanel dock = new DockLayoutPanel(Unit.EM); dock.addWest(new Widget1(), 10); dock.add(new Widget2()); rootLayoutPanel.add(dock);
I have declared an
handleClickAlert
inWidget1
:@UiHandler("button") void handleClickAlert(ClickEvent e) { //fireEvent(e); }
-
elvispt over 12 yearsWhen firing the event, how could I send an object? In my case I would need to send an class that contains my users information.
-
Peter Knego over 12 yearsYou can have a field in your custom event and set it via constructor, i.e. 'new AuthenticationEvent(someObject)'
-
Igor Klimer over 9 yearsProtip: use gwteventbinder to minimize the code needed to define a new event. For the AuthenticationEvent above, your event would just have to extend
GenericEvent
. -
baris about 9 yearsBetter to use 'ResettableEventBus' not to have a global event bus which won't be killed after the lifecycle of 'Presenter' and might result multiple identical event handlers for one event.