GWT EventBus Example


April 22, 2014 Maithilish

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 {               1
                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);
	}

}

1

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