4.4. GWT EventBus Example
One of the best widgets to explain the benefits of EventBus
is
Status
widget. Various objects of the application may like to send
messages to Status widget for display, and with the traditional style,
each and every object has to register Status widget as a handler, and
for this, all interested objects has to get a reference to the Status
widget. But EventBus eliminates these unnecessary couplings. Just
register Status widget with EventBus and any object may fire
StatusEvent
and EventBus takes care to pass it on to Status widget.
Add Status.ui.xml
and Status.java
to in.fins.client.widget
package.
in.fins.client.widget/Status.ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel>
<g:HTML styleName="" ui:field="html" />
</g:HTMLPanel>
</ui:UiBinder>
in.fins.client.widget/Status.java
package in.fins.client.widget;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.Widget;
public class Status extends Composite implements HasText {
interface StatusBinder extends UiBinder<Widget, Status> {
}
private static UiBinder<Widget, Status> binder = GWT
.create(StatusBinder.class);
@UiField
HTML html;
public Status() {
initWidget(binder.createAndBindUi(this));
}
public void setText(String text) {
html.setText(text);
}
public String getText() {
return html.getText();
}
}
Status is a simple widget, which is HtmlPanel
with HTML
widget.
Earlier we had separate files for MenuEvent
and MenuHandler
, but we
can improvise this and place Handler interface in the Event file itself,
to reduce the number of files. Add StatusEvent.java
to
in.fins.client.event
package.
in.fins.client.event/StatusEvent.java
package in.fins.client.event;
import in.fins.client.event.StatusEvent.StatusHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.web.bindery.event.shared.Event;
public class StatusEvent extends Event<StatusHandler> {
public interface StatusHandler extends EventHandler {
public void onStatusChange(StatusEvent event);
}
public static final Type<StatusHandler> TYPE = new Type<StatusHandler>();
private String status;
public StatusEvent(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
@Override
public Type<StatusHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(StatusHandler handler) {
handler.onStatusChange(this);
}
}
StatusHandler is inner class of StatusEvent |
Add Status widget to FinsShell.ui.xml
and register FinsShell with
EventBus for StatusEvent
.
in.fins.client.content/FinsShell.ui.xml
....
<g:south size='3'>
<g:LayoutPanel>
<g:layer>
<f:Status ui:field="status" />
</g:layer>
</g:LayoutPanel>
</g:south>
....
in.fins.client.widget/Status.java
....
import in.fins.client.event.EventBus;
import in.fins.client.event.StatusEvent;
import in.fins.client.event.StatusEvent.StatusHandler;
import in.fins.client.widget.Status;
....
public class FinsShell extends ResizeComposite implements StatusHandler {
....
@UiField
Status status;
public FinsShell() {
initWidget(binder.createAndBindUi(this));
EventBus.get().addHandler(StatusEvent.TYPE, this);
EventBus.get().fireEvent(new StatusEvent("message"));
....
@Override
public void onStatusChange(StatusEvent event) {
status.setText(event.getStatus());
}
}
Now any object in the application may fire status message with
EventBus.get().fireEvent(new StatusEvent("Status messageā)
and it is
no longer necessary to register the handler with each and every event
source.
That completes the menu with some simple code. We have placed some
DateBox
composite as placeholders and actual contents have to replace
them. Let’s proceed to design the content pages.
Time to change style.
First four chapters follow tutorial style, which explains each and every step in detail. But as we are comfortable with many concepts by now, remaining chapters trims down the details. Instead of step by step instructions, explanation will be terse that concentrates on important concepts, routines and methods, with the relevant code snippets. But occasionally, we may provide detailed code where they may be necessary to explain some concepts or to present alternative coding.
Sample code contains chapter wise zip archives and even section wise zips for lengthly chapters like Snapshot. Import respective sample code to Eclipse to browse and run the application while going through a chapter or section.
Forward Pointers
ClientBundle - For more information on ClientBundle refer Developer’s Guide - Bundling Image Resources