Monday, July 18, 2011

Everyone on the Bus

When doing UI development, we all know that we have to deal with callbacks. Callbacks when a mouse button is pressed, callbacks when the screen is resized, callbacks when a menu item is selected, callbacks for just about anything that can happen on your screen.

When designing a well structured piece of software, using object oriented techniques, we will end up with a nice hierarchy of classes, each with their own responsibilities and scope. Traditionally, we would build something like a menu class which handles all the menu creation and callbacks. For example, say someone picks the Help menu. This class gets the callback and launches the help system. But lets say that we want to put help buttons all over our application and give the user the option to get help on a variety of things. This would mean that the menu class would have to be passed around to all the other classes so that the various help buttons could trigger different help system displays. Or we could create one big master class that everyone has access to....but this begins to breakdown, means a lot of parameter passing and just starts to become spaghetti code. Not what we want to maintain.

So what is our option? The Event Bus, aka HandlerManager. What does this do you ask?
Quite simply, the event bus lets our client "fire" an event in one piece of code to be caught and handled by any other piece of code that is listening for this specific event.

Let's see some code. First we want to create an event and its handler. Lets use the help example. When fired, we want to create a help event with a string that will represent "what" help data we want to display.

HelpEventHandler.java:

public interface HelpEventHandler extends EventHandler

{
void onSelect(HelpEvent event);
}



HelpEvent.java:

public class HelpEvent extends GwtEvent

{
public static final Type TYPE = new Type();
private final String helpString;

public HelpEvent(final String helpString)
{
this.helpString = helpString;
}

@Override
protected void dispatch(final HelpEventHandler handler)
{
handler.onSelect(this);
}

@Override
public Type getAssociatedType()
{
return TYPE;
}


public String getHelpString()
{
return helpString;
}

}



We now have defined our event and a handler. Now we need someone to listen for this event as follows:

private final HandlerManager  eventBus   = new HandlerManager(null);


eventBus.addHandler(HelpEvent.TYPE, new HelpEventHandler()
{
@Override
public void onSelect(final HelpEvent event)
{
// Someone fired this event, do something with.
new HelpScreen(event.getHelpString()).show();
}
});




Lastly, we need someone to fire this event for the above listener to receive:

private final HandlerManager  eventBus   = new HandlerManager(null);

eventBus.fireEvent(new HelpEvent("my help topic"));


In summary, we built a specific event and handler. This event has a string as the data payload for it, a string that we use to go to a specific help page. This could be an object, data structure or any data that you want the event to get. We then setup a listener to act on this event being fired. Lastly, we fired the event. In practice, you can now implement a single listener and have lots of places in your code "fire" the event. You may have several places in your application where you want to show "help" and can build a single help display class while allowing any of your code to trigger it.

I've used this technique to allow for the editing of my objects from various places in my code. When someone initiates an edit operation, either from a menu pick, a right click, or by selecting on an object, the event is fired and my "edit object" code catches this request and puts up the edit dialog. I can get to this edit dialog from anywhere and never have to change my edit dialog code to do this.

I can now get to the edit dialog from anywhere in my code, just by Getting on the Bus.

Friday, July 1, 2011

Getting Started

As an experienced UI developer and designer, you know that you are going to need views, dialogs, menus, buttons, trees, tables, error dialogs, etc. You also know that you will want a nicely laid out directory structure to hold all your files and to establish a "place" for everything and everything in its "place". But where do you start... being new to GWT?

I started with a book. I chose Essential GWT - Building for the Web with Google Web Toolkit 2. My development platform is a Mac and my editor is the SpringSource Tool Suite (aka Eclipse). Starting with an example from the book, build your initial app and get it running. Spend some time modifying it and trying out different scenarios that the book covers. Learn about MVP (Model, View, Presenter) and adopt it to your liking. Understand how HTML + CSS and Java (compiled into javascript) will all fit together and will be used to make your application.

Make a change in Eclipse, save it and rebuild your app, then just refresh your browser and see how the changes automagically made it to your browser without stopping and restarting....very cool and will be so useful when you really get going.

As part of your initial design work, you will need to figure out what your app will be displaying and if you will need some 3rd party toolkits or if you want to go it natively with just the GWT basics? Native GWT will give you all the building blocks, but things like progress widgets, busy indicators, canvas renderers, etc. will not be there without bringing in some additional widgets. You may also want to bring in some Javascript widgets and integrate them, which is quite easy to do (a blog entry on that forthcoming).

Understand that you are on the web, in a browser, with a certain set of user expectations that are different that an installed application, but that line is blurring all the time.

I will be adding blog entries about GWT from here on out that provide specific small coding examples that answer "how do you do that?".