GWT 2.1 MVP Multiple activities clarification help

2,158 views
Skip to first unread message

Milan Cvejic

unread,
Dec 15, 2010, 9:24:39 AM12/15/10
to Google Web Toolkit
Helo,
i tried to understand post at http://tbroyer.posterous.com/gwt-21-activities-nesting-yagni
but with no luck :(

I tried following code:

package com.hellomvp.client;


import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.hellomvp.client.mvp.AppPlaceHistoryMapper;
import com.hellomvp.client.mvp.LeftActivityMapper;
import com.hellomvp.client.mvp.RightActivityMapper;
import com.hellomvp.client.place.HelloPlace;
import com.hellomvp.client.ClientFactory;

/**
* Entry point classes define <code>onModuleLoad()</code>.
*/

public class HelloMVP implements EntryPoint {

private Place defaultPlace = new HelloPlace("World!");
private LayoutPanel mainLayout = new LayoutPanel();

SimplePanel leftPanel = new SimplePanel();
SimplePanel rightPanel = new SimplePanel();

// Assumes a LayoutPanel is used for the layout, with a SimplePanel
for each display region
AcceptsOneWidget leftDisplay = new AcceptsOneWidget() {
public void setWidget(IsWidget activityWidget) {
// Window.alert("test");
Widget widget = Widget.asWidgetOrNull(activityWidget);
mainLayout.setWidgetVisible(leftPanel, widget != null);
leftPanel.setWidget(widget);
}
};

// Assumes a LayoutPanel is used for the layout, with a SimplePanel
for each display region
AcceptsOneWidget rightDisplay = new AcceptsOneWidget() {
public void setWidget(IsWidget activityWidget) {
// Window.alert("test");
Widget widget = Widget.asWidgetOrNull(activityWidget);
mainLayout.setWidgetVisible(rightPanel, widget != null);
rightPanel.setWidget(widget);
}
};

/**
* This is the entry point method.
*/
public void onModuleLoad() {

// Create ClientFactory using deferred binding so we can replace
with
// different
// impls in gwt.xml
ClientFactory clientFactory = GWT.create(ClientFactory.class);
EventBus eventBus = clientFactory.getEventBus();
PlaceController placeController =
clientFactory.getPlaceController();

// Start ActivityManager for the left widget with our ActivityMapper
ActivityMapper leftActivityMapper = new LeftActivityMapper(
clientFactory);
ActivityManager leftActivityManager = new ActivityManager(
leftActivityMapper, eventBus);
leftActivityManager.setDisplay(leftDisplay);


// Start ActivityManager for the right widget with our
ActivityMapper
ActivityMapper rightActivityMapper = new RightActivityMapper(
clientFactory);
ActivityManager rightActivityManager = new ActivityManager(
rightActivityMapper, eventBus);
rightActivityManager.setDisplay(rightDisplay);

// Start PlaceHistoryHandler with our PlaceHistoryMapper
AppPlaceHistoryMapper historyMapper = GWT
.create(AppPlaceHistoryMapper.class);

PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(
historyMapper);
historyHandler.register(placeController, eventBus, defaultPlace);

DOM.setStyleAttribute(leftPanel.getElement(), "backgroundColor",
"#3054A1");
DOM.setStyleAttribute(rightPanel.getElement(), "backgroundColor",
"#ff2e80");

// mainLayout.addWest(leftPanel, 15);
// mainLayout.addEast(rightPanel, 15);

mainLayout.add(leftPanel);
mainLayout.add(rightPanel);

mainLayout.setWidgetLeftWidth(leftPanel, 0, Unit.PCT, 50,
Unit.PCT); // Left panel
mainLayout.setWidgetRightWidth(rightPanel, 0, Unit.PCT, 50,
Unit.PCT); // Right panel

RootLayoutPanel.get().add(mainLayout);
// Goes to place represented on URL or default place
historyHandler.handleCurrentHistory();
}

}

But even if rightActivityManager or leftActivityManager return null,
nothing happens with layout, exept that Activity is not run. So the
method in display setWidget is not called, and therefore no action is
happening with widget.

Is there any complete example on this topic?

Thanks.

Thomas Broyer

unread,
Dec 16, 2010, 5:12:01 AM12/16/10
to google-we...@googlegroups.com
I must confess I never actually tested the setWidgetVisible part of the code (in a prototype, I had a DockLayerPanel and used remove/add, without a containing SimplePanel-like widget, for a similar effect).
Étienne Pelletier said in the comments that it indeed doesn't work as expected (and re-reading the Javadoc, he must be right) and you should use setWidgetSize (if you're using a DockLayoutPanel; if you're using a LayoutPanel, I guess calling setWidgetLeftWidget, or similar depending on your needs, should do the trick).

I never took the time to fix the article because I haven't yet tested any alternate code…

HTH

Mauro Bertapelle

unread,
Dec 23, 2010, 11:29:21 AM12/23/10
to Google Web Toolkit
As an exercise I've build a little POC based on the concepts expressed
by Thomas in his article.
If someone is interested, the sources are here: http://95.110.143.4/layoutmvp/layoutmvp.tar.gz
and here you can find a live demo: http://95.110.143.4/layoutmvp/layoutmvp.html

Milan Cvejic

unread,
Dec 24, 2010, 8:37:00 AM12/24/10
to Google Web Toolkit
Great, thanks you for help.
I already managed to create working code, but will take a look at your
example. Probably I will
learn a lot.

Sincerely Milan

On Dec 23, 5:29 pm, Mauro Bertapelle <mauro.bertape...@gmail.com>
wrote:

karthik reddy

unread,
Jan 6, 2011, 5:43:25 PM1/6/11
to Google Web Toolkit, Karthik Reddy
Hi Mauro

Your example is turning out to be very helpful.

I ran into one issue I thought I might communicate to you.

When you click the "Mail activites" button, and then select the first
entry of the mail list (i.e., viv...@seddiamlorem.ca) the details are
populated in "Mail Details". Similary if you select the second entry
of the mail list (i.e., fauc...@sit.com) the corresponding details
are populated in "Mail Details" . The urls for the above two events
are http://95.110.143.4/layoutmvp/layoutmvp.html#mail:1 and
http://95.110.143.4/layoutmvp/layoutmvp.html#mail:2 respectively . So
far so good.

When you hit the back button now , the url is changed from
http://95.110.143.4/layoutmvp/layoutmvp.html#mail:2 to
http://95.110.143.4/layoutmvp/layoutmvp.html#mail:1 and the contents
of "Mail Details" change as well. But, the selected email on the
list(highlighted with blue background) is not changing from the second
entry to the first entry.

Any thoughts on this would be much appreciated.

On Dec 23 2010, 8:29 am, Mauro Bertapelle <mauro.bertape...@gmail.com>
wrote:

Thomas Broyer

unread,
Jan 6, 2011, 7:22:21 PM1/6/11
to google-we...@googlegroups.com, Karthik Reddy
Because of the CachingActivityMapper and FilteredActivityMapper (found in CachingHorizontalMasterActivityMapper), the MailListActivity isn't "restarted" between place changes between MailDetailPlace-s (and MailListPlace-s).
As it doesn't listen to PlaceChangeEvent, its not even aware of the navigation. It should then listen to PlaceChangeEvent-s and adjust the selection accordingly.

Mauro Bertapelle

unread,
Jan 7, 2011, 6:26:25 AM1/7/11
to Google Web Toolkit
karthik,

glad you find my example useful, but please consider it just a basic
demonstration of the concepts expressed by Thomas in his article, far
from being a complete implementation of an app based on the new
Activity/Place model.

As Thomas pointed out, MailListActivity need to be informed of
MailDetailPlace change events to have it syncronized with what's
displayed on the MailDetailActivity's display area.

To implement this, add a PlaceChangeEvent handler to MailListActivity:

public MailListActivity(ClientFactory clientFactory) {
view = clientFactory.getMailListView();
placeController = clientFactory.getPlaceController();

EventBus eventBus = clientFactory.getEventBus();
eventBus.addHandler(PlaceChangeEvent.TYPE, new
PlaceChangeEvent.Handler() {
@Override
public void onPlaceChange(PlaceChangeEvent event) {
Place newPlace = event.getNewPlace();

if (newPlace instanceof MailDetailPlace) {
String mailIdToken = ((MailDetailPlace) newPlace).getMailId();
Mail mail = MAILLIST.getMail(Integer.valueOf(mailIdToken));
view.setSelectedMail(mail);
}
}
});
}

and a new setSelectedMail method to MailListView:

@Override
public void setSelectedMail(Mail newSelectedMail) {
SingleSelectionModel<Mail> selectionModel =
(SingleSelectionModel<Mail>) table.getSelectionModel();
Mail selected = selectionModel.getSelectedObject();
if (selected.getId() != newSelectedMail.getId()) {
selectionModel.setSelected(newSelectedMail, true);
}
}


nacho

unread,
Jan 7, 2011, 8:57:26 AM1/7/11
to google-we...@googlegroups.com
Very nice example Mauro!

Shubhang Mani

unread,
Jan 7, 2011, 10:36:43 AM1/7/11
to google-we...@googlegroups.com
+1 great example !

It's the best working example I've seen thus far that illustrates MVP with activities/places as well as uiBinder.
I was finally able to understand how to control navigation in a content pane from a non-display region.

All it needs now is GIN  :-)

Thanks for putting this out there !

-shubhang

Mauro Bertapelle

unread,
Jan 24, 2011, 1:26:21 PM1/24/11
to Google Web Toolkit
I've uploaded a new version of layoutmvp, where ClientFactory has been
replaced with GIN based dependency injection.

source: http://95.110.143.4/layoutmvp/layoutmvp-gin.tar.gz
live demo: http://95.110.143.4/layoutmvp/layoutmvp.html

ernesto.reig

unread,
Feb 22, 2011, 8:05:31 AM2/22/11
to Google Web Toolkit
Thank you very much Mauro for the great example and Thomas for his
post.
There´s something I don´t understand:
What´s the purpose of CachingHorizontalMasterActivityMapper and
CachingVerticalMasterActivityMapper? what are their functions? how do
they fit with the rest of the classes/project?

Thank you very much in advance.

Mauro Bertapelle

unread,
Feb 23, 2011, 10:14:36 AM2/23/11
to Google Web Toolkit
Ernesto,

CachingHorizontalMasterActivityMapper is just a wrapper for
CachingActivityMapper and FilterActivityMapper.

The layout of our example requires that both master and detail display
regions are simultaneously visible.
This means that when a user navigate to a detail place, even the
master display region must be advised to ensure that what's displayed
on the master region is in sync with what's on the detail region.
This is the task of FilterActivityMapper, which is used to map detail
place activity to a corresponding master activity:

FilteredActivityMapper.Filter filter = new
FilteredActivityMapper.Filter() {
@Override
public Place filter(Place place) {
return place instanceof MailDetailPlace ? new MailListPlace() :
place;
}
};

CachingActivityMapper is useful when you don't want to instantiate a
new Activity every time a place change event occurs. Generally
speaking, Activity are meant to be light disposable object so
instantiating a new one on every place change event shouldn't be an
isssue. In our case, CachingActivityMapper is useful when a user
navigate from one detail to another and the master display region is
always the same and doesn't need to be reinstantiated.

Glenn

unread,
Apr 7, 2011, 12:56:09 PM4/7/11
to Google Web Toolkit
Hi Mauro,

Thank you for the excellent example, it has been a great help to me.

In comparing layoutmvp to layoutmvp-gin, it seems to me that the
latter is
much more complex and much more code; i.e., that GIN is a net loss
here. I can
see how it could be useful in a limited way for swapping views, or
perhaps
eventually for testing, but the ActivityProviders and the rather odd
ActivityManagerInitializer class strike me as too much of a good
thing.

Does anyone have an opinion about this?

Thanks,
Glenn

karthik reddy

unread,
May 19, 2011, 4:17:20 PM5/19/11
to google-we...@googlegroups.com
I have ran into a interesting situation using Mauro's example[A hit tip to Mauro in helping the community to navigate the waters of Activities and Places]:

Lets say, I first access


As expected, it shows me the Inbox.

Then, lets say, I access


As expected, it shows me the contacts.

Then, lets say, I change the url to 


(XYZ is a deliberately typed in bad token)

As expected, it does a redirect(client-side redirect)  to http://95.110.143.4/layoutmvp/layoutmvp.html#contacts:list  and shows me the contacts again.

So, far so good.

Now, as I hit the back button once, twice, thrice and so on I am just stuck at the Contacts. I can never go back to the Inbox. 

Is this expected behavior. Any thoughts or  even brief pointers as to might be going on would appreciated.

thanks a lot.

ustad

unread,
Jun 15, 2011, 2:29:28 PM6/15/11
to google-we...@googlegroups.com
Hi all, I'm new to GWT (and more of an advanced beginner with java at that too) and I just worked through the stockwatcher example as posted on the official google page using the latest gwt 2.3 sdk and plugin using eclipse.  So far so good.   However, when trying to incorporate an MVP design pattern I am at a loss.    I understand the basic concept that the idea is a separation of concerns leading to a loosely coupled architecture that facilitates easily testable and extensible code.    But when looking through whatever examples I could find via search, I still haven't wrapped my head around the actual CONCRETE implementation.     I guess what confuses me in the examples I've come across, is all the nested interfaces, nested object instantiations within method invocations and basic nomenclature.... I see 'Display' being used with 'View' and 'Presenter' and I get more confused.    Should  I not worry about all that and just try and learn the new Activities/Places implementation?  Or without the fundamentals of MVP I won't understand the latter?

I was wondering if someone could provide me with a very, very basic concrete example of converting the rudimentary stockwatcher example into that of an MVP adopted one?     I hope this is not too much of a request... but this humble chap who's trying to jump on the bandwagon would be forever indebted!

My humble thanks!
ustad

Juan Pablo Gardella

unread,
Jun 15, 2011, 9:46:21 PM6/15/11
to google-we...@googlegroups.com
Check this sample

2011/6/15 ustad <ustad...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/YIjzGq2uA4gJ.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

tanteanni

unread,
Jun 16, 2011, 1:22:09 AM6/16/11
to google-we...@googlegroups.com
i didn't read all post, but i ran into similar problems. now i got something that's working for me:

i decoupled activities/places and MVP (what thomas suggested in many places). in my case the VP-pairs are controlling/filling display areas and one activity is "start"ing/ controlling them. starting means composing the screen with a DockLayoutPanel and add the presenter's asWidgets to it's parts. controlling means hiding showing one shared content area for example. that is exactly the same what i did before without places/activities. the difference is now i can control/handle the leaving of such a set of presenters and i can easily safe some state (the presenters that want to save something need appropriate setters or constructors) / recover the state and bookmark it. imho that is the exact use for activities and places - to use an activity as presenter is imho a special case suitable in some (not so complex?) apps.

what do you think about this approach? (this approach is my interpretation of answers i got for similar questions here https://groups.google.com/forum/#!topic/google-web-toolkit/0sM8aWWt27g, https://groups.google.com/forum/#!topic/google-web-toolkit/f20FbM04usU - in meantime i understand the - especially thomas' "Activities however are in no way related to MVP: you can use activities without doing MVP, and you can (and you probably will if your UI is complex) do MVP outside activities.")

Mauro Bertapelle

unread,
Jun 24, 2011, 8:58:30 AM6/24/11
to Google Web Toolkit
There are a couple of bugs in my example related to the filtering/
caching of horizontal/vertical master activities:

1) the order between caching and filtering activity in
CachingHorizontalMasterActivityMapper and
CachingVerticalActivityMapper is wrong:

public class CachingHorizontalMasterActivityMapper implements
ActivityMapper {
...
public
CachingHorizontalMasterActivityMapper(HorizontalMasterActivityMapper
horizontalMasterActivityMapper) {
...
ActivityMapper filteredMapper = new FilteredActivityMapper(filter,
horizontalMasterActivityMapper);
cachingActivityMapper = new CachingActivityMapper(filteredMapper);
}
...
}

This way, we are caching the activity associated with MailDetailPlace,
not with MailListPlace as intended.

The right filtering order is:
public class CachingHorizontalMasterActivityMapper implements
ActivityMapper {
...
public
CachingHorizontalMasterActivityMapper(HorizontalMasterActivityMapper
horizontalMasterActivityMapper) {
...
CachingActivityMapper cachingActivityMapper = new
CachingActivityMapper(horizontalMasterActivityMapper);
filteredActivityMapper = new FilteredActivityMapper(filter,
cachingActivityMapper);
}
...
}

2) moreover, to let CachingActivityMapper successfully detect
instances of the same Place type, we need to ovverride equals method
on our Places:

public class MailListPlace extends MailPlace {
@Override
public boolean equals(Object otherPlace) {
return this == otherPlace || (otherPlace != null && getClass() ==
otherPlace.getClass());
}
...
}

I've uploaded fixed versions of both non-gin and gin version of the
example code at the usual url:
http://95.110.143.4/layoutmvp/layoutmvp.tar.gz
http://95.110.143.4/layoutmvp/layoutmvp-gin.tar.gz

Ustad

unread,
Jun 24, 2011, 9:45:09 AM6/24/11
to google-we...@googlegroups.com
Thanks so much for the update Mauro.    I'm still struggling to wrap my head around MVP and activities & places.    I'm going to start very small and use your code as my baseline.   Just some clarification Mauro, the idea of the MVP pattern is used to decouple the view from the presenter with the intent to make the view as 'dumb' as possible to facilitate a seamless swap out to its mock counterpart during testing, and the activities and places is the underlying framework Google has provided to help essentially manage user history but at the same time activities can be thought of as the presenter and used synonymously ?    Do I have it totally wrong?  I guess as a beginner, I'm seeing so many different implementations where views implement interfaces in presenters and presenters implementing interfaces in views that I can't get a concrete grasp of how I should approach a simple design?    The idea of the presenter defining the contract for the view and the view providing that implementation makes sense to me.... sorry I probably have not made any sense....   thanks for your help and your guidance to the community at large!

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.




--
-------------------------------------------------------------------------------
"Wait till you look within yourself and see what you find.....
Oh Seeker, one leaf in that Garden is worth more that all of Paradise!"

Rumi
-------------------------------------------------------------------------------
"Those of us who have taken this peep through the door of our own Being are dumbfounded.  We draw back, surprised, at the inscrutable possibilities of the Inner Self.  Man as a spiritual being possesses a capacity for wisdom which is infinite, a resource of happiness which is startling.  He contains a divine infinitude within himself, yet he is content to go on and potter about a petty stretch of life as though he were a mere human insect..."
Dr. Paul Brunton
-------------------------------------------------------------------------------
I have learned silence from the talkative,
toleration from the intolerant, and kindness from the unkind.

Kahlil Gibran

Thomas Broyer

unread,
Jun 24, 2011, 10:16:05 AM6/24/11
to google-we...@googlegroups.com


On Friday, June 24, 2011 3:45:09 PM UTC+2, ustad wrote:
Thanks so much for the update Mauro.    I'm still struggling to wrap my head around MVP and activities & places.    I'm going to start very small and use your code as my baseline.   Just some clarification Mauro, the idea of the MVP pattern is used to decouple the view from the presenter with the intent to make the view as 'dumb' as possible to facilitate a seamless swap out to its mock counterpart during testing, and the activities and places is the underlying framework Google has provided to help essentially manage user history but at the same time activities can be thought of as the presenter and used synonymously ?    Do I have it totally wrong?

You're right.

(note that the fact that activities are presenters is an implementation choice: nothing and nobody forces you to do so; you can choose that your activity will make use of a presenter as a distinct class, or that your activity is the view, or even that you don't use MVP at all for your activity –it can make sense for very small things with few to no interaction at all–)
 
  I guess as a beginner, I'm seeing so many different implementations where views implement interfaces in presenters and presenters implementing interfaces in views that I can't get a concrete grasp of how I should approach a simple design?    The idea of the presenter defining the contract for the view and the view providing that implementation makes sense to me.... sorry I probably have not made any sense....

It doesn't matter where your interfaces live (nested in the presenter, nested in the view, in their own files: it doesn't matter; you decide what you prefer). The fact is that if you want to decouple your presenter from your view, to be able to mock the latter when unit-testing the former, they should be talking to each other through interfaces (depending on your mocking tool, it might not be strictly necessary, but I believe it helps understanding the big picture anyway). If your view needs to talk back to your presenter, then it's a good idea to define an interface to formalize the contract for the presenter, in the same way you defined an interface to describe the contract for the view.
 

chillyspoon

unread,
Jun 9, 2012, 6:52:26 AM6/9/12
to google-we...@googlegroups.com
Another +1 for Mauro's example. Definitely the cleanest sample implementation that I've seen to date and demonstrates further Thomas' good work in his article.

Thanks guys!

Ronan Quillevere

unread,
Jan 1, 2014, 10:07:06 AM1/1/14
to google-we...@googlegroups.com
I know it might be an old topic, but I have tried to implenent thomas idea (http://tbroyer.posterous.com/gwt-21-activities-nesting-yagni ) in this github project. I will be happy to have some comments/suggestions.


Regards

Mansi Shah

unread,
Feb 21, 2014, 5:21:27 AM2/21/14
to google-we...@googlegroups.com
Hello,

I am new to GWT.
I am developing sample app on GWT using activity & places concept.

It is giving an error in view file button click event..
Please guide me.

package com.wa.WebpageSample.client.view;

import com.google.gwt.place.shared.Place;
import com.google.gwt.user.client.ui.IsWidget;

public interface LeftLayoutView extends IsWidget {
void setPresenter(Presenter presenter);
public interface Presenter{
void goTo(Place place);
}

}


package com.wa.WebpageSample.client.view;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.sun.security.sasl.ClientFactoryImpl;
import com.wa.WebpageSample.client.ClientFactory;
import com.wa.WebpageSample.client.place.AboutUsPlace;
import com.wa.WebpageSample.client.place.LeftLayoutPlace;

public class LeftLayoutViewImpl extends Composite implements LeftLayoutView {

private static LeftLayoutViewImplUiBinder uiBinder = GWT.create(LeftLayoutViewImplUiBinder.class);

interface LeftLayoutViewImplUiBinder extends
UiBinder<Widget, LeftLayoutViewImpl> {
}
@UiField
Button btnabout,btncontact;
private Presenter presenter;
ClientFactory clientFactory;
public LeftLayoutViewImpl() {
}

public LeftLayoutViewImpl(ClientFactory clientFactory) {
initWidget(uiBinder.createAndBindUi(this));
this.clientFactory = clientFactory;
}

@Override
public void setPresenter(Presenter presenter) {
this.presenter = presenter;
}
@UiHandler("btnabout")
public void onClick(ClickEvent event){
//this.clientFactory.getPlaceController().goTo(new LeftLayoutPlace("LeftView"));
//this.clientFactory.getPlaceController().goTo(new AboutUsPlace("AboutUsView"));
presenter.goTo(new LeftLayoutPlace("AboutUs"));
//Window.alert("Hello");
}
@UiHandler("btncontact")
public void onClick1(ClickEvent event) {
Window.alert("World");
}

}

package com.wa.WebpageSample.client.activity;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.wa.WebpageSample.client.ClientFactory;
import com.wa.WebpageSample.client.place.LeftLayoutPlace;
import com.wa.WebpageSample.client.view.LeftLayoutView;

public class LeftLayoutActivity extends AbstractActivity implements LeftLayoutView.Presenter {
private ClientFactory clientFactory;

public LeftLayoutActivity(LeftLayoutPlace leftPlace,ClientFactory clientFactory) {
this.clientFactory = clientFactory;
}
public LeftLayoutActivity(ClientFactory clientFactory2) {
this.clientFactory = clientFactory2;
}

@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
LeftLayoutView leftView = clientFactory.getLayoutView();
panel.setWidget(leftView.asWidget());
}

@Override
public void goTo(Place place) {
clientFactory.getPlaceController().goTo(place);
}

}

package com.wa.WebpageSample.client;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.wa.WebpageSample.client.activity.LeftLayoutActivityMapper;
import com.wa.WebpageSample.client.activity.RightLayoutActivityMapper;
import com.wa.WebpageSample.client.place.AppPlaceMapper;
import com.wa.WebpageSample.client.place.LeftLayoutPlace;
import com.wa.WebpageSample.client.place.RightLayoutPlace;
import com.wa.WebpageSample.client.view.LeftLayoutViewImpl;
import com.wa.WebpageSample.client.view.RightLayoutViewImpl;
import com.wa.WebpageSample.client.view.TopLayoutViewImpl;

public class WebpageSample implements EntryPoint {

//private static WebpageSampleUiBinder uiBinder = GWT.create(WebpageSampleUiBinder.class);

//interface WebpageSampleUiBinder extends UiBinder<Widget, WebpageSample> {}
@UiTemplate("WebpageSample.ui.xml")
interface Binder extends UiBinder <DockLayoutPanel,WebpageSample>{}

private static final Binder binder = GWT.create(Binder.class);

private Place defaultPlace = new LeftLayoutPlace("LeftView");

@UiField
SimpleLayoutPanel topPanel,leftPanel,rightPanel;
@Override
public void onModuleLoad() {
DockLayoutPanel outer = binder.createAndBindUi(this);
ClientFactory clientFactory = GWT.create(ClientFactory.class);
EventBus eventBus = clientFactory.getEventBus();
        PlaceController placeController = clientFactory.getPlaceController();
        
        

        ActivityMapper leftPanelActivityMapper = new LeftLayoutActivityMapper(clientFactory);
        ActivityManager leftPanelActivityManager = new ActivityManager(leftPanelActivityMapper, eventBus);
        leftPanelActivityManager.setDisplay(leftPanel);

        ActivityMapper rightPanelActivityMapper = new RightLayoutActivityMapper(clientFactory);
        ActivityManager rightPanelActivityManager = new ActivityManager(rightPanelActivityMapper, eventBus);
        rightPanelActivityManager.setDisplay(rightPanel);
      
        AppPlaceMapper historyMapper= GWT.create(AppPlaceMapper.class);
        PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
        historyHandler.register(placeController, eventBus,defaultPlace);

        RootLayoutPanel.get().add(outer);
        historyHandler.handleCurrentHistory();
}
}

How to change center view on button click on left side of webpage?
How to switch between multiple activities?
Thanks
Reply all
Reply to author
Forward
0 new messages