complex example GWT Activity and Place

1,143 views
Skip to first unread message

Kayode Odeyemi

unread,
Mar 24, 2011, 10:18:20 AM3/24/11
to google-web-toolkit
Hello,

Is there any complex example on how to nest Views when using the GWT Activity and Place. For example, I have a MainWidget which acts as a parent View for all other Views that have got a Place. My question is, how can I place other Views in the MainWidget? If this is not possible, does this mean every View can outrightly be its own widget? My reason for wanting the MainWidget to house other Views is because I want the MainWidget to control the entire layout of the application, so that other Views (URL based widgets) can just go ahead and do their own specific things.

From the HelloMVP, there's this line:

private Place defaultPlace = new HelloPlace("World!");
private SimplePanel appWidget = new SimplePanel();

// Start ActivityManager for the main widget with our ActivityMapper
ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
activityManager.setDisplay(appWidget);

Taking this one level up, does this mean that the GoodbyeView and HelloView Views are attached to appWidget and are both visible at Place "World"? What about if I have widgets and not Views, can these widgets be attached to for example appWidget? Also, assuming I have another Place at "Heaven", with its own Views, how can I discard the widgets already showing in appWidget? Is this something the ActivityManager takes care of automatically?

One other question, I have an Hyperlink that's got a #profile token. From my understanding of Place, if I click on the Hyperlink which appends #profile to the URL, the ActivityManager should call the corresponding Place which is set at "profile". Right now this is not working for me. I have this:

registerHandler(display.showAgentProfileView().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                //eventBus.fireEvent(new MainSignupEvent());
                getAgentProfileActivity();
            }

public void getAgentProfileActivity() {
            Window.alert("getAgentProfileActivity Request is called");

            History.newItem("profile");
            History.addValueChangeHandler(this);
            History.fireCurrentHistoryState();
            
            // Start ActivityManager for the main widget with our ActivityMapper
            ActivityMapper activityMapper = new AppActivityMapper(mainp);
            ActivityManager activityManager = new ActivityManager(activityMapper, geventBus);
            activityManager.setDisplay((AcceptsOneWidget)mainp.getDisplay().getAgentProfileView().asWidget());

            Place agentprofile = new AgentProfilePlace("profile");
            PlaceController agentprofilePlaceController = mainp.getPlaceController();
            AgentProfilePlaceHistoryMapper agentprofilehistoryMapper= GWT.create(AgentProfilePlaceHistoryMapper.class);
            PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(agentprofilehistoryMapper);
            historyHandler.register(placecontroller, geventBus, agentprofile);

        }


I will also like to know, can the ActivityManager be called anywhere else other than in onModuleLoad. My reason is because, since the issue of decoupling is a big factor in MVP, I tend to have my events handled in the Presenter implementing class. Please correct me if I'm wrong with the interpretation.

--
Odeyemi 'Kayode O.

B.Sc(Hons) Econs, Application Developer & Systems Engineer (Sun Certified Professional),
Oracle Certified Associate, Solaris Systems Administrator, Drupal Developer

Website: http://sinati.com
Socialize with me: http://profile.to/charyorde, http://twitter.com/charyorde,
http://www.google.com/profiles/dreyemi
Skype:drecute

Juan Pablo Gardella

unread,
Mar 24, 2011, 10:21:12 AM3/24/11
to google-we...@googlegroups.com
See this http://tbroyer.posterous.com/gwt-21-activities-nesting-yagni

2011/3/24 Kayode Odeyemi <dre...@gmail.com>
--
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.

Kayode Odeyemi

unread,
Mar 24, 2011, 10:33:49 AM3/24/11
to google-we...@googlegroups.com
I have seen that Juan thanks. It addresses on nesting. But I have other questions such as can the ActivityManager be called anywhere else other than in onModuleLoad? Also, the concept of Place itself, as described above.

David Chandler

unread,
Mar 24, 2011, 12:38:45 PM3/24/11
to google-we...@googlegroups.com
Hi Odeyemi,

See slides 32-47 here: http://www.slideshare.net/turbomanage/whats-new-in-gwt-22

Also, this sample project has two ActivityManagers showing how the same Place can be mapped in both (albeit one is null).
http://code.google.com/p/listwidget/

Inline comments below...

HTH,
/dmc

On Thu, Mar 24, 2011 at 10:18 AM, Kayode Odeyemi <dre...@gmail.com> wrote:
Hello,

Is there any complex example on how to nest Views when using the GWT Activity and Place. For example, I have a MainWidget which acts as a parent View for all other Views that have got a Place. My question is, how can I place other Views in the MainWidget? If this is not possible, does this mean every View can outrightly be its own widget? My reason for wanting the MainWidget to house other Views is because I want the MainWidget to control the entire layout of the application, so that other Views (URL based widgets) can just go ahead and do their own specific things.

From the HelloMVP, there's this line:

private Place defaultPlace = new HelloPlace("World!");
private SimplePanel appWidget = new SimplePanel();

// Start ActivityManager for the main widget with our ActivityMapper
ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
activityManager.setDisplay(appWidget);

Taking this one level up, does this mean that the GoodbyeView and HelloView Views are attached to appWidget and are both visible at Place "World"?

Each ActivityManager is responsible for its own area of the screen. Each ActivityManager has its own ActivityMapper, and each can map the same Place to a different Activity.
 
What about if I have widgets and not Views, can these widgets be attached to for example appWidget? Also, assuming I have another Place at "Heaven", with its own Views, how can I discard the widgets already showing in appWidget? Is this something the ActivityManager takes care of automatically?

When you change Place, the new Activity(ies) start() method(s) should call panel.setWidget() to replace the current contents of the panel. ActivityManager does not discard widgets automatically unless the new Activity is null.
 

One other question, I have an Hyperlink that's got a #profile token. From my understanding of Place, if I click on the Hyperlink which appends #profile to the URL, the ActivityManager should call the corresponding Place which is set at "profile". Right now this is not working for me. I have this:

registerHandler(display.showAgentProfileView().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                //eventBus.fireEvent(new MainSignupEvent());
                getAgentProfileActivity();
            }

public void getAgentProfileActivity() {
            Window.alert("getAgentProfileActivity Request is called");

            History.newItem("profile");
            History.addValueChangeHandler(this);
            History.fireCurrentHistoryState();
            
            // Start ActivityManager for the main widget with our ActivityMapper
            ActivityMapper activityMapper = new AppActivityMapper(mainp);
            ActivityManager activityManager = new ActivityManager(activityMapper, geventBus);
            activityManager.setDisplay((AcceptsOneWidget)mainp.getDisplay().getAgentProfileView().asWidget());

            Place agentprofile = new AgentProfilePlace("profile");
            PlaceController agentprofilePlaceController = mainp.getPlaceController();
            AgentProfilePlaceHistoryMapper agentprofilehistoryMapper= GWT.create(AgentProfilePlaceHistoryMapper.class);
            PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(agentprofilehistoryMapper);
            historyHandler.register(placecontroller, geventBus, agentprofile);

        }

When using Activities & Places, you don't need to call any methods on History directly. Instead use historyHandler.handleCurrentHistory(). The rest of the code in your getAgentProfileActivity() method should be run during application setup (called from onModuleLoad, not a ClickHandler as shown here). Finally, the ClickHandler should call placeController.goTo(new AgentProfilePlace());
 


I will also like to know, can the ActivityManager be called anywhere else other than in onModuleLoad. My reason is because, since the issue of decoupling is a big factor in MVP, I tend to have my events handled in the Presenter implementing class. Please correct me if I'm wrong with the interpretation.

--
Odeyemi 'Kayode O.

B.Sc(Hons) Econs, Application Developer & Systems Engineer (Sun Certified Professional),
Oracle Certified Associate, Solaris Systems Administrator, Drupal Developer

Website: http://sinati.com
Socialize with me: http://profile.to/charyorde, http://twitter.com/charyorde,
http://www.google.com/profiles/dreyemi
Skype:drecute

--
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.



--
David Chandler
Developer Programs Engineer, Google Web Toolkit
w: http://code.google.com/
b: http://googlewebtoolkit.blogspot.com/
t: @googledevtools

Kayode Odeyemi

unread,
Mar 26, 2011, 2:16:48 PM3/26/11
to google-we...@googlegroups.com
Thanks Dave. That was really helpful as it allows me to do some more
digging. One more thing, I still don't understand why my profile
activity is not responding to it's Place controller. The Place token
is gotten but it doesn't trigger its activity which will call its
corresponding Place. Here's what I mean in code:

public class ListingsEntryPoint implements EntryPoint {

Place home = new HomePlace();
ClientFactory clientFactory = GWT.create(ClientFactory.class);
Place profile = new AgentProfilePlace("profile");

@Override
public void onModuleLoad() {

EventBus eventBus = clientFactory.getEventBus();
final PlaceController placeController = clientFactory.getPlaceController();
MainWidget mainwidget = clientFactory.getApp();

AppPlaceHistoryMapper apphistoryMapper= GWT.create(AppPlaceHistoryMapper.class);
PlaceHistoryHandler historyHandler = new
PlaceHistoryHandler(apphistoryMapper);
historyHandler.register(placeController, eventBus, home);


RootPanel.get().add(mainwidget);
// Goes to place represented on URL or default place
historyHandler.handleCurrentHistory();

mainwidget.showAgentProfileView().addClickHandler(new ClickHandler() {

@Override
public void onClick(ClickEvent ce) {
String historyToken =
clientFactory.getHistoryMapper().getToken(profile);
placeController.goTo(profile);
}
});
}
}

/* HomeView */
public interface HomeView extends IsWidget {

HasClickHandlers showAgentProfileView();

interface Presenter {
}

void setPresenter(Presenter p);
}


/* MainWidget */

public class MainWidget extends Composite implements HomeView {

private final VerticalPanel panel;
private Widget content;
private AgentProfileView agentProfileView = new AgentProfileViewImpl();
private Anchor agentProfilelink = new Anchor("View Profile");
private HeaderWidget headerWidget = new HeaderWidget();

private Presenter presenter;

private Place place;

public MainWidget() {

panel = new VerticalPanel();
panel.setStyleName("gwt-innerContainer");
//panel.setStyleName("main");
panel.add(agentProfilelink);
panel.add(headerWidget);
initWidget(panel);
setStyleName("main-wrapper");
}

@Override
public HasClickHandlers showAgentProfileView() {
return agentProfilelink;
}

@Override
public void setPresenter(Presenter p) {
this.presenter = p;
}
}

/* AgentProfileActivity */

public class AgentProfileActivity extends AbstractActivity implements
AgentProfileView.Presenter {

private Logger logger =
Logger.getLogger(AgentProfileActivity.class.getName());

private MainPresenter presenter;
private ClientFactory clientFactory;
private EventBus eventBus;
//Place place = GWT.create(Place.class);

private String agentprofileplace;

@Inject
public AgentProfileActivity(AgentProfilePlace place, ClientFactory
clientFactory) {
this.clientFactory = clientFactory;
this.agentprofileplace = place.getAgentprofileplace();
}

@Override
public void start(AcceptsOneWidget aow, EventBus eb) {
logger.info("starting AgentProfileActivity");
AgentProfileView agentProfileView = clientFactory.getAgentProfileView();
this.eventBus = eb;
agentProfileView.setPresenter(this);
aow.setWidget(agentProfileView.asWidget());
}

@Override
public String mayStop() {
return "Please hold on. This activity is stopping.";
}

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

/* AgentProfilePlace */
public class AgentProfilePlace extends Place {

private String agentprofileplace;

public AgentProfilePlace() {
}

public AgentProfilePlace(String token) {
this.agentprofileplace = token;
}

public String getAgentprofileplace() {
return agentprofileplace;
}

public static class AgentProfileTokenizer implements
PlaceTokenizer<AgentProfilePlace> {

@Override
public AgentProfilePlace getPlace(String place) {
return new AgentProfilePlace(place);
}

@Override
public String getToken(AgentProfilePlace p) {
return p.getAgentprofileplace();
}

}
}

/* AppActivityMapper */
public class AppActivityMapper implements ActivityMapper {

private ClientFactory clientFactory;

public AppActivityMapper(ClientFactory clientFactory) {
super();
this.clientFactory = clientFactory;
}

@Override
public Activity getActivity(Place place) {
if(place instanceof HomePlace)
return new HomeActivity((HomePlace) place, clientFactory);
if (place instanceof AgentProfilePlace)
return new AgentProfileActivity((AgentProfilePlace) place, clientFactory);
else
return null;
}
}

I believe it is not necessary to have an activity for the MainWidget,
so I have it initialized right from the application EntryPoint. I was
expecting the AgentProfilePlace to display its widget, but that is not
working. I think my case is similar to that of Aodhagán on this
thread: https://groups.google.com/d/topic/google-web-toolkit/LtGZpCxQAVY/discussion.
I appreciate your suggestion.

Regards

>> Website: http://sinati.com <http://www.sinati.com>


--
Odeyemi 'Kayode O.

Website: http://sinati.com <http://www.sinati.com>

Kayode Odeyemi

unread,
Mar 27, 2011, 9:57:00 AM3/27/11
to google-we...@googlegroups.com
I finally figured this out in my MainWidget with this:

private Hyperlink agentProfilelink = new Hyperlink("View Profile",
clientFactory.getHistoryMapper().getToken(agentprofileplace));

public MainWidget() {
initWidget(panel);


panel.setStyleName("gwt-innerContainer");
//panel.setStyleName("main");
panel.add(agentProfilelink);
panel.add(headerWidget);

setStyleName("main-wrapper");
showAgentProfileView().addClickHandler(new ClickHandler() {

@Override
public void onClick(ClickEvent ce) {

Window.alert("clicked");

logger.info(clientFactory.getHistoryMapper().getToken(agentprofileplace));
String historyToken =
clientFactory.getHistoryMapper().getToken(agentprofileplace);

clientFactory.getPlaceController().goTo(new
AgentProfilePlace(historyToken));
}

});
}

This paragraph bailed me out: "Rather than using
PlaceController.goTo(), you can also create a Hyperlink containing the
history token for the new Place obtained by calling your
PlaceHistoryMapper.getToken(). When the user navigates to a new URL
(via hyperlink, back button, or bookmark), PlaceHistoryHandler catches
the ValueChangeEvent from the History object and calls your app's
PlaceHistoryMapper to turn the history token into its corresponding
Place. It then calls PlaceController.goTo() with the new Place."

Reference: http://code.google.com/webtoolkit/doc/trunk/DevGuideMvpActivitiesAndPlaces.html

Regards

Reply all
Reply to author
Forward
0 new messages