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,647 hits

Navigating to a new view with gwt-presenter, part 2

Posted by David Chandler on October 1, 2009

In the previous post, we considered how to switch between views using a DeckPanel. Depending on the situation, one possible disadvantage to a DeckPanel is that it retains each member view widget in memory even when not displayed. If instead you want to remove a view widget from its container when transitioning to another view, you can use gwt-presenter’s WidgetContainerPresenter and WidgetContainerDisplay classes. Here is the same example shown with these classes in which we use a VerticalPanel as a container and navigate from the ManageListsPresenter/View to the AddPrayerListPresenter/View within the VerticalPanel. Note that the ContentContainerPresenter constructor calls showPresenter(). This is very important, as our view’s implementation of showWidget() calls clear() and add() to replace the existing contents of the VerticalPanel with the new widget. If you don’t call showPresenter() in the container constructor, then the default behavior of WidgetContainerPresenter is to add all the member presenters to the view.

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.WidgetContainerDisplay;
import net.customware.gwt.presenter.client.widget.WidgetContainerPresenter;
import net.customware.gwt.presenter.client.widget.WidgetPresenter;

public class ContentContainerPresenter extends WidgetContainerPresenter<ContentContainerPresenter.Display>
{

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

	public interface Display extends WidgetContainerDisplay
	{
	}

	public ContentContainerPresenter(Display display, EventBus eventBus,
			WidgetPresenter<?>[] presenters)
	{
		super(display, eventBus, presenters);
		bind();
		// Show first presenter as default
		showPresenter(presenters[0]);
	}

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

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

}

And here is the matching view that uses a VerticalPanel as the container widget:

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

import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.roa.client.presenter.ContentContainerPresenter.Display;

public class ContentContainerView implements Display
{

	private final VerticalPanel contentPanel = new VerticalPanel();

	public ContentContainerView()
	{
	}

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

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

	@Override
	public void showWidget(Widget widget)
	{
		contentPanel.clear();
		contentPanel.add(widget);
	}

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

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

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

}

These are wired up in AppPresenter and the view change triggered with a PlaceRequestEvent just as shown in the previous post.

Advertisements

13 Responses to “Navigating to a new view with gwt-presenter, part 2”

  1. Dun said

    Hi David,
    i’am also using gwt-presenter on my projects. And I also use a kind of navigation as described here. A NavigationManager is listening for place change, and call a “changeContent(WidgetPresenter)” on my mainPresenter.
    But I just found that the old presenter is not removed from memory. For example if the presenter have an eventBus.addHandler method listening on a special event and showing a Window.alert(“message”);, if you go back and forward on the same presenter twice you will have 2 messageboxes for the same event, back and forward again and you will have 3 …
    Did you experiment the same problem, or am I missing something ?
    Best Regards
    Dun

    • Correct. Presenters are singletons and are not automatically unloaded. So any code you put in the constructor (or bind(), if you’re calling it from the constructor) will be executed only once, whereas any code in onPlaceRequest() will be executed each time you navigate to that place. I use onPlaceRequest() to clear the view and/or preload it with new data based on the parameters in the PlaceRequest.

  2. […] 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 portion of the page, and could […]

  3. mxmtycoder said

    Hi, I’ve been following your posts about gwt-presenter and I found them very useful.
    Thanks for sharing the knowledge.

    I wondered how the placemanager work with history management?

    I played a little bit with apache hupa gwt mail client (which is using gwt-presenter & gwt-dispatch)and I noticed that is not handling history, is this an issue from Hupa implementation or from the gwt-presenter?

    Thanks,
    Pablo

    • Thanks, Pablo, glad to help. PlaceManager essentially synchronizes the browser’s notion of place with gwt-presenter’s. It does this by listening to two events: 1) PlaceManager registers a handler for a ValueChangeEvent from History, such as when the user clicks the back button or replaces the URL in the address bar, and fires a PlaceRequestEvent in response. And 2) PlaceManager registers a handler for PlaceChangedEvents fired manually in your code and calls History.newItem to mark the place in the browser.

      I’m having good success with gwt-presenter keeping track of history, so I suspect the Hupa implementation may not be firing PlaceRequestEvents or PlaceChangedEvents in all the places you would expect. The code must fire one of these events every “place” that it wants GWT to mark for bookmarkability, etc.

  4. Per Wiklander said

    I’m trying to implement this. You say (emphasis mine):

    Note that the ContentContainerPresenter constructor calls showPresenter(). This is very important, as our view’s implementation of showWidget() calls clear() and add() to replace the existing contents of the VerticalPanel with the new widget. If you don’t call showPresenter() in the container constructor, then the default behavior of WidgetContainerPresenter is to add all the member presenters to the view.

    Isn’t that going to happen anyway? The result being that each view is added and then cleared away when you do showPresenter(presenters[0]); to get back to the view you actually wanted. At least this is what it looks like to me when inspecting the onBind() method of net.customware.gwt.presenter.client.widget.WidgetContainerPresenter. Perhaps we should override onBind() to not add all the widgets in the first place? Or just do a noop in addWidget() in ContentContainerView(). Or is that method needed for anything else? One more thing:

    showPresenter(presenters[0]); could be replaced with eventBus.fireEvent(new PresenterRevealedEvent(defaultPresenter)); in AppPresenter, right?

    As you see I’m unsure of things, but that’s why we ask questions πŸ™‚

    • Exactly right on all counts. In my latest code, I do not call showPresenter() within ContentContainerPresenter, and I fire a PresenterRevealedEvent (a PlaceRequestEvent, actually, which in turn fires a PresenterRevealedEvent) within AppPresenter instead.

      I see no problem with overriding WidgetContainerPresenter.onBind() as long as you include the code to register the event handler. It looks you could get away with a noop in addWidget(), as the PresenterRevealedEvent handler calls showWidget() rather than addWidget(). But because it’s defined in the WidgetContainerDisplay interface, there’s always the risk that something in gwt-presenter could call it in a future release. Either way, you’ll just have to be alert to the potential for compatibility problems with future releases.

      Good questions / clarifications.

      • Per Wiklander said

        I’ll have to put those optimizations on the “things to consider” list. Right now I think it’s best to concentrate on getting better at GWT as a whole and stick to what seems to work. I would hate to have to hunt down a bug that is due to me changing something in the framework when I should be producing widgets and getting interesting data from the server πŸ™‚

  5. lost said

    what about revealDisplay ? and what to put in revealDisplay vs onRevealDisplay, and how they are different than showPresenter you used ?

  6. laura said

    Hi, excellent tutorial… I have a question related to the places… Suppose I have a presenter that I can use several time for CRUD scenaries… It is possible to add several places to the same presenter????

    • Thanks, Laura. I think you’d want a Place for each Presenter, but you could add a request param that the one place/presenter could use to distinguish among different CRUD screens.

      • laura said

        Hi David, thanks a lot for your quick reply… I manage to distinguish the different CRUD screens passing the arguments to the presenter through the places…everything works fine until the history get activated…everytime I push the back button is a mess…the history does not send me to the last place, it send me to another place that hold this CRUD presenter, so I think that at the end I have to stick with one presenter per place(wich is a pitty)… of course this presenter will be an extention of my crud presenter, am I right???

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: