TurboManage

David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler


    Web app developer since 1994 and former Developer Advocate with Google now residing in Colorado. Besides tech, I enjoy landscape photography and share my work at ColoradoPhoto.gallery.

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 241 other followers

  • Sleepless Nights…

    October 2009
    S M T W T F S
    « Sep   Nov »
     123
    45678910
    11121314151617
    18192021222324
    25262728293031
  • Blog Stats

    • 865,597 hits

Navigating to a new view with gwt-presenter

Posted by David Chandler on October 1, 2009

How can you move to a new “view” with gwt-presenter? In GWT, you wouldn’t ordinarily replace the entire page as in a server-side Web app. Suppose you have one area of the screen, say, a VerticalPanel, in which you want to show any number of functional views (i.e, manage lists, edit list properties, etc.). One way to do this is using a DeckPanel, which is the base class behind GWT’s TabPanel widget. DeckPanel has no visible UI controls, but lets you programatically swap out one widget for another just as if you were clicking tabs. Gwt-presenter provides DeckPresenter and DeckDisplay to help with just that. Here’s a sample DeckPresenter class.

package com.roa.client.presenter;

import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceRequest;
import net.customware.gwt.presenter.client.widget.DeckDisplay;
import net.customware.gwt.presenter.client.widget.DeckPresenter;
import net.customware.gwt.presenter.client.widget.WidgetContainerDisplay;
import net.customware.gwt.presenter.client.widget.WidgetPresenter;

public class ContentContainerPresenter extends DeckPresenter
{

	private static final Place PLACE = new Place("content");

	public interface Display extends WidgetContainerDisplay
	{
	}

	public ContentContainerPresenter(DeckDisplay display, EventBus eventBus,
			WidgetPresenter<?>[] presenters)
	{
		super(display, eventBus, presenters);
		bind();
		// One way to show default presenter--see also AppPresenter below for another way
		// showPresenter(presenters[0]);
	}

	@Override
	public Place getPlace()
	{
		return PLACE;
	}

	@Override
	protected void onPlaceRequest(PlaceRequest request)
	{
		// TODO Auto-generated method stub
	}

}

And here’s the corresponding view:

package com.roa.client.ui.web.content;

import net.customware.gwt.presenter.client.widget.DeckDisplay;

import com.google.gwt.user.client.ui.Widget;

public class ContentContainerView extends DeckDisplay
{

	public ContentContainerView()
	{
	}

	@Override
	public void addWidget(Widget widget)
	{
		super.add(widget);
	}

	@Override
	public void removeWidget(Widget widget)
	{
		super.remove(widget);
	}

	@Override
	public void showWidget(Widget widget)
	{
		// Refer up to DeckPanel
		super.showWidget(widget);
	}

	@Override
	public Widget asWidget()
	{
		return this;
	}

	@Override
	public void startProcessing()
	{
		// TODO Auto-generated method stub

	}

	@Override
	public void stopProcessing()
	{
		// TODO Auto-generated method stub

	}

}

Gwt-presenter’s DeckDisplay, unlike the other gwt-presenter interfaces named “Display”, is actually a concrete class that extends GWT’s DeckPanel. As such, we can use it as our view implementation directly. Now let’s wire them up. Because DeckPresenter’s constructor takes an array of presenters as an argument, there’s no way (that I know of, at least) to instantiate it with GIN using @Inject. So in our AppPresenter, we manually construct the needed classes like this:

	@Inject
	private EventBus eventBus;
	@Inject
	private ManageListsPresenter listsPresenter;
	@Inject
	private AddPrayerListPresenter addPresenter;
...
		// Instantiate container presenter manually as its constructor
		// prevent GIN binding
		WidgetPresenter<?>[] presenters = new WidgetPresenter<?>[]
		{ listsPresenter, addPresenter };
		ContentContainerView contentContainerView = new ContentContainerView();
		ContentContainerPresenter contentContainerPresenter = new ContentContainerPresenter(
				contentContainerView, eventBus, presenters);
		// Fire event to reveal only default presenter
		eventBus.fireEvent(new PresenterRevealedEvent(listsPresenter));

In order to show the default presenter (in this case, Manage Lists), we fire a PresenterRevealedEvent after constructing the ContentContainerPresenter. Without it, however, the default behavior of GWT presenter is to show the widgets associated with all presenters that have been added to the container.

Finally, we need to fire an event to transition from one view to another. We could use a PresenterRevealedEvent; however, the PlaceRequestEvent does much more. Gwt-presenter’s BasicPresenter class (from which WidgetContainerPresenter and DeckPresenter are derived) listens for PlaceRequestEvents, marks the Place in History, calls onPlaceRequest() for the requested presenter, and finally calls the requested presenter’s revealDisplay() method, which in turn fires a PresenterRevealedEvent.

The code below will trigger a transition from the ManageListsPresenter to the AddPrayerListPresenter when the add button is clicked. The easiest way to get a reference to the presenter we’re going to is simply to make its PLACE constant public so we can use it in PlaceRequests from other classes.

public class ManageListsPresenter extends
		WidgetPresenter<ManageListsPresenter.Display>
{
		display.getAddButton().addClickHandler(new ClickHandler()
		{
			@Override
			public void onClick(ClickEvent event)
			{
				PlaceRequest placeRequest = new PlaceRequest(AddPrayerListPresenter.PLACE);
				eventBus.fireEvent(new PlaceRequestEvent(placeRequest));
			}
		});
...
}
Advertisements

3 Responses to “Navigating to a new view with gwt-presenter”

  1. […] Chandler on October 21, 2009 I have previously written about navigation in gwt-presenter using the DeckPresenter or WidgetContainerPresenter approaches. Those techniques work well for swapping out views in one […]

  2. brakebg said

    Good post but the last example where you use PlaceRequest to trigger transition has one disadvantages according to me, it does not change the token in the url.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: