GWT 2.1 Activities – nesting? YAGNI ? - an example of where you NEED it !

166 views
Skip to first unread message

zixzigma

unread,
Nov 29, 2010, 5:35:04 PM11/29/10
to Google Web Toolkit
Hello Everyone,

GWT MVP 2.1 has no direct support for complex layout/views and nested/
composite activities.
ActivityManager only AcceptsOneWidget.

To get around this design limitation, it was suggested to have
multiple ActivityManagers, each responsible for a given display
region.

The example given in the article below, talks about 4 Display Regions/
Activity Managers.

http://tbroyer.posterous.com/gwt-21-activities-nesting-yagni

Having carefully read it, and trying to apply this in my application,
came across the limitation of this approach, and where it falls short.

first have a look at this mock-up to get an idea of what i'm going to
talk about:
http://oi52.tinypic.com/zofgic.jpg

lets think about the idea of workspace in UI design.
your application might have a number of workspaces.
each workspace focuses on one aspect of the problem your application
is designed to address.
a workspace, groups together a set of use cases that are closely
related, and work together to collaboratively accomplish the goal of
the workspace.

to put it in concrete terms, lets say your application requires User
Management feature.
creating groups, each group can have sub-groups (tree structure). each
user has certain roles within the group,
and certain access control. you want to CRUD "groups", "users",
"roles", "permissions".
these use cases are closely related. so we encapsulate them in User
Management Workspace.

your application might require other features: Document Management,
Task Management, Calendar,
we put all Task Management use cases in Task Management Workspace. and
so on.

in UI terms, each Workspace can have its own Regions: North, South,
East, West, Center
the number, size and arrangement of these regions might differ from
workspace to workspace.

One Workspace might require the West Region to have 3 sub-regions:
West North, West Center, West South.

Another Workspace might require East Region to have 2 sub-regions:
East North, East Main
and i am not going to talk about cases where you might need 2 West
Regions !

as you can see with , 1 North, 1 West(3 subregions) , 1 Center (2 sub-
regions), 1 East (2 subregions)
1 + 1x3 + 1x2 + 1x2 = 8
we need at least 8 display regions, and in complex cases, this might
get to 14 !
and we have to size these regions explicitly upfront. (what if for one
workspace East Region needs to be X width, and for another it needs to
be Y width ?)

to implement this with GWT MVP, according to the approach suggested in
the article,
we need 8 Activity Managers, 8 Activity Mappers.
even though regions of a workspace are closely related, since you had
to split your layout up front,
instead of grouping related regions/activities in one place, they get
scattered.
NorthRegionActivityMapper, WestNorthActivityMapper,
WestCenterActivityMapper, WestSouthActivityMapper,
CenterNorthActivityMapper, CenterMainActivityMapper,
EastNorthActivityMapper, EastCenterActivityMapper

and for example for our User Management Workspace,
we would have code like this:

WestCenterAcitivtyMapper

if(place instanceof UserManagementWorkspace)
new GroupsTreeActivity() // a tree of groups, each group sub-group,
selection of each updates center region


CenterNorthActivityMapper
if (place instanceof UserManagementWorkspace)
new ToolbarActivity()


since we have 8 ActivityMappers, it is difficult to keep track of
which activity is in what region .

do you think having 8 ActivityManagers/Mappers is a good idea ?!
What if an application needs 10 ?!


zixzigma

unread,
Nov 29, 2010, 5:44:22 PM11/29/10
to Google Web Toolkit
the article also argued, that having the same size/fixed regions leads
to consistent layout.

in the case of Fixed "WIDTH", that is true.

but if your regions have sub-regions, the sizing is no longer the
Width, but rather the HEIGHT.

our WEST region, can have WEST_NORTH, WEST_MAIN, WEST_SOUTH,
and the "HEIGHT" of these sub-regions might required to be different
in different workspaces.


in one workspace, WEST_NORTH height could be 100px, while WEST_SOUTH
height is 300px, in another workspace, different Height size.
having different heights, while maintaining the same width, is STILL
CONSISTENT.

with the approach suggested in the article posted above,
one has to add additional West Regions, to accommodate for the use
case described above,
resulting in ActivityManagers/Mappers/Code size to grow
exponentially !

Ashton Thomas

unread,
Nov 30, 2010, 12:05:24 AM11/30/10
to Google Web Toolkit
Do you need to think of each area on the left and right as independent
activities? can you, instead, create just one area for the left and
have it be made of multiple widgets. So instead of having a full
activity, you create each box area as it's own widget?

So you would have one main activity for each major area with one view
and could have multiple widgets that accomplish what your individual
activities could?

or maybe, and this may just retarded of me to think, create an
activity that kinda wraps many other activities:

LeftWorkspaceActivity
private act1
private act2
private act3
private WorkspaceWidget wsw
...

wsw.add(act1, eventBus)
wsw.add(act2, eventBus)


WorkSpaceWiget

add(WorspaceChildActivity act, EventBus){
//get the correct view area to add this activity into
//do all the necessary things to correctly wrap this widget
//do we allow resize width? do we allow rezise total height
// if so are there certain activities that we want to flag as not
resizable
act.start(viewArea, eventBus);


and have a WorspaceChildActivity extends AbstractActivity that other
activities that you want to wrap extend this class, abstract class


This probably doesn't make any sense and probably violates many
things, it is basically making an activity act as an awkward activity
manager bundled together with too much control over the UI

zixzigma

unread,
Nov 30, 2010, 12:28:52 AM11/30/10
to Google Web Toolkit
Thank you for your comments.

>>So you would have one main activity for each major area with one view
>>and could have multiple widgets that accomplish what your individual
>>activities could?

I had thought about this, but my concern is by doing so, we lose the
navigation/history/bookmarking.

in the case of West Region having West North, West Main and West
South,
lets say we place three widgets in the West Region, and treat the
entire region as a single activity,

when we click an item in one of the regions (West Main for example),
selection of an item fires an event on eventBus,
the widget in West South is listening for this event, and upon
receiving,
populates itself with contextual data related to item selected in West
Main, however
since we are not using activities and places, the history token doesnt
get updated,
and we lose the history which results in poor/broken navigation.

more over, since we are not using Activities/Places for these sub-
regions (west_north, west_main, west_south),
we can not use placeController.go(new place), for communicating
events, and have to resort to manually creating event handling
(GwtEvent, etc)

what is your view on this ? can we get the history working if we use
widgets ( old style Presenter/Views) and not activities ?

>>or maybe create an
>>activity that kinda wraps many other activities:

i think it should be possible and is what is referred to as Composite
Activity in google's documentation.
However I am not sure whether it is considered a good practice.
This concept is briefly mentioned in Google's MVP tutorial
http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html#How_to_navigate

in the very last paragraph, the most important part, which is sadly
left out causing confusiong:

"What about apps with multiple panels in the same window whose state
should all be saved together in a single URL? GWT 2.1 does not attempt
to provide a generic implementation of a composite Place; however,
your app could create a CompositePlace, CompositeActivity, and
CompositePlace.Tokenizer classes that delegate to the constituent
members. In this case, only the composite objects would need to be
registered with your app's ActivityMapper and PlaceHistoryMapper."

do you have any idea on CompositePlace , its relation to Composite
Activity, and how we can map a Composite Place to its corresponding
Activities ?

thank you

Baloe

unread,
Nov 30, 2010, 4:53:56 AM11/30/10
to Google Web Toolkit
You can get the history working if you use widgets, as long as you let
everything react on a Place somehow. As far as I know, when a place is
shown, it is recorded in the history properly. We had an
implementation which didn't listen to the place but handled the
drawing ourselves, and that didn't work properly (always full a redraw
of the screen, etc).

This might help. We have places like below. Our left panel looks to
the instanceof, and our middle panel looks at the instanceof _and_ to
the getToken() of the place. That works pretty well. So, for example
for our PlaceContact we have a ContactsLeft (-activity and -view)
which always shows when a PlaceContact is chosen. For the middle in
our screen, we have several activity-view combinations that react on
PlaceContact, depending on which getToken() is called.

[ We might even extend our places to include references to specific
entities, now our URL looks like #contact:edit but we might extend it
to #contact:edit:3342 . Unfortunately there is no standarised aproach
for this. ]

public class PlaceContact extends Place {
public final static String LIST = "list";
public final static String ADD = "add";
public final static String EDIT = "edit";

public final static String DEFAULT = LIST;

private String token;

public PlaceContact() {
this.token = DEFAULT;
}

public PlaceContact(String token) {
this.token = token;
}

public String getToken() {
return token;
}

@Prefix("contact")
public static class Tokenizer implements PlaceTokenizer<PlaceContact>
{

@Override
public String getToken(PlaceContact place) {
return place.getToken();
}

@Override
public PlaceContact getPlace(String token) {
return new PlaceContact(token);
}

}

}


our ActivityMapper left:

if (place instanceof PlaceContact) {
return activityContactLeft.get();
} else if (place instanceof .....
.....


our ActivityMapper middle:

if (place instanceof PlaceContact) {
PlaceContact placeContact = (PlaceContact) place;
if (placeContact.getToken().equals(PlaceContact.LIST)) {
return activityContactList.get();
} else if (placeContact.getToken().equals(PlaceContact.ADD)) {
.......

Best,
Niels
> This concept is briefly mentioned in Google's MVP tutorialhttp://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAnd...

Thomas Broyer

unread,
Nov 30, 2010, 6:50:07 AM11/30/10
to Google Web Toolkit


On 30 nov, 06:28, zixzigma <zixzi...@gmail.com> wrote:
navigation != business event.

If you want navigation, then use places, and in your activitymapper
for the "west" display region, then return a new activity (with the
same 3 widgets, just different data on them).
Or if you think it could be too resource-consuming (e.g. could lead to
many RPC requests just to show the very same information as before, in
the sub-regions that didn't change) then you could keep a reference on
the "current" activity (in the activitymapper) and "update" it with
the new place.

But for "side" regions, I wonder why you want it to be part of
navigation... when there's a "main region", navigation generally is
tied to this region, and the rest is either contextual to the main
region (i.e. determined by the place) or tied by business events
exchanged between the components (or a mix of both).

> "What about apps with multiple panels in the same window whose state
> should all be saved together in a single URL? GWT 2.1 does not attempt
> to provide a generic implementation of a composite Place; however,
> your app could create a CompositePlace, CompositeActivity, and
> CompositePlace.Tokenizer classes that delegate to the constituent
> members. In this case, only the composite objects would need to be
> registered with your app's ActivityMapper and PlaceHistoryMapper."
>
> do you have any idea on CompositePlace , its relation to Composite
> Activity, and how we can map a Composite Place to its corresponding
> Activities ?

Having briefly talked about it with Ray Ryan, the idea is to split the
history token in several parts that you then detokenize as if they
were inidividual places. The CompositePlace would then (to be generic,
adapt to your own needs) model an array of places.
I for one don't buy this idea; I haven't yet met an app where I'm not
"doing something" or "looking at something", and that's the definition
of a place. I'm not "looking at something on the left and doing
something totally unrelated on the right" (that's what a 'composite
place' would model).

That being said, I'm not working at Google, and I'm not a UX expert;
so please consider that as my very own opinion. Yours might of course
be different.

(and activities and places don't aim at addressing every use case,
only the ones that make 90% or more of web apps)

Thomas Broyer

unread,
Nov 30, 2010, 6:57:03 AM11/30/10
to Google Web Toolkit
Your "regions" are not required to have a fixed size, you're not
required to use layout panels either. How about using SimplePanel
widgets inside a FlowPanel, without specifying explicit sizes? That
would work too.

In your case though, I'd probably go with either:
- Ashton's proposal
- make each "workspace" it's own GWT app (if they're sufficiently
different to deserve it)

Or:
- do not use activities (you can still use places if you like)
- use activities but make your own activity manager (or whatever) to
break the limitations and og beyond what's possible with the stock
implementations; maybe try to use a main activitymanager to switch
between workspaces, and then a set of activitymanager/mapper/regions
within each workspace.

There are many possibilities, and there are no one-size-fits-all.

Brian Reilly

unread,
Nov 30, 2010, 10:15:49 AM11/30/10
to google-we...@googlegroups.com
Another option would be to look at a 3rd party framework. As Thomas pointed out, the GWT team isn't trying to address every use case, and that's where pulling in other frameworks can help. There's no shame in recognizing that you have a complex use case and using any tools available to help. I haven't tried them, but people often speak favorably about gwt-platform (http://code.google.com/p/gwt-platform/).

Finally, I want to point out that you may not want to affect the history for every interaction in sub-views. It's nice for bookmarking, but would make use of the browser history buttons very frustrating. You may only want to change the history token when the main subject of the activity (the thing typically in the center display) changes. You could always provide a feature to create a reliable link from the current view (like the Google maps "Link" feature). That might have the same complexity in terms of implementing your view state management, but it's still something to consider for usability.

-Brian


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


Ashton Thomas

unread,
Nov 30, 2010, 10:17:10 AM11/30/10
to Google Web Toolkit
I think in the case of the composite activity / composite place, you
need to define how closely realted each workspace will be. will there
be any overlap between sub/areas of one workspace and a different
workspace?

You can be careful about how you craft your composite place and how
you tokenize it into sections. one section for each area that holds
the state. then each sub area widget/activty can cache it's current
state and do a really quick check to see if the new section of the
composite place for it's area is different from its current state.

It would probably take a good deal of organizing a pattern and
wrapping your objects in the right way

massimo malvestio

unread,
Nov 30, 2010, 10:30:10 AM11/30/10
to google-we...@googlegroups.com
In my opionion if you release a functionality and tell people "it's better if you use it", you have to be aware of impacts this new functionality can have on existing code.
In my opinion use of DockLayout or TabLayout / Panes is not a rare use case, think about a mail reader.
MVP approach is very good, and I think that GWT team did a great job about it, but, given implementation does not consider complex web gui.
What I find inacceptable is documentation, the last paragraph, where GWT team says:
 
"What about apps with multiple panels in the same window whose state should all be saved together in a single URL? GWT 2.1 does not attempt to provide a generic implementation of a composite Place; however, your app could create a CompositePlace, CompositeActivity, and CompositePlace.Tokenizer classes that delegate to the constituent members. In this case, only the composite objects would need to be registered with your app's ActivityMapper and PlaceHistoryMapper."
 
In my opinion if you speak about CompositePlace you should describe what you are talking about, too easy to say "yes, you could create a CompositeActivity, but do it by your own"
 
Anyway, I repeat, GWTeam did a great work about MVP and it's very useful having directly inside GWT an pattern implementation for organizing classes about guis, but in my opionion there are a lot of complex gui that difficultly can be migrated to this approach with actual solution

 

zixzigma

unread,
Nov 30, 2010, 2:34:28 PM11/30/10
to Google Web Toolkit
Thank you everyone for your wonderful insights.
You provided very helpful suggestions and invaluable solutions to deal
with the problem i described.

I was going to implement some of the solutions offered, but this
comment by Ray Ryan,
got me very worried and kind of put me off.

"The activity and place packages in GWT 2.1 are pretty minimal first
stabs,
kind of rushed out the door. One focus of GWT 2.2 will be improving
their
flexibility and reducing the boilerplate they require. "

http://groups.google.com/group/google-web-toolkit/browse_thread/thread/2173bd71a6289c84

I am going to start working on a new project, and I'm afraid based on
Ray Ryan's comment, GWT 2.1 MVP is too experimental,
and there is a very high risk that GWT 2.2 would be dramatically
different than 2.1, leaving me with
a lot of boilerplate code to maintain !

I am leaning toward using GWTP, as Brian Reilly suggested.
GWTP is more stable and mature than GWT 2.1 MVP,
and it comes with many added features.

I will keep you updated on this, as I continue with my project.

Sincerely,
zixzigma


Brian Reilly

unread,
Nov 30, 2010, 3:19:00 PM11/30/10
to google-we...@googlegroups.com
There's a difference between "experimental" and "immature". I don't think Activities and Places are experimental. They are building blocks upon which more functionality can be built. While there may be bigger plans for future versions of GWT, I'm glad that we have this much to work with sooner rather than have to wait longer for a complete out-of-the-box solution.

I wouldn't  take Ray's comments (from http://groups.google.com/group/google-web-toolkit/browse_thread/thread/2173bd71a6289c84) to mean that these features are experimental. More likely, you'll be able to rip out a bunch of code when newer versions are released rather than have to maintain boilerplate.

That said, have a look at the options, including other MVP frameworks, and then choose what's going to work best for your situation.

-Brian

David Chandler

unread,
Nov 30, 2010, 3:48:58 PM11/30/10
to google-we...@googlegroups.com
Spot on, Brian.

The kinds of changes to Activities and Places we're contemplating for
future versions of GWT are primarily along the lines of using
annotations and generators to automate the creation of PlaceTokenizers
and ActivityMappers, for example. We're not talking about wholesale
replacement, as we strive for API backward compatibility with each
release.

Also, we're thankful for a thriving community of 3rd party frameworks
around GWT and you're always welcome to look "outside the box" it that
suits your needs better.

/dmc

--
David Chandler
Developer Programs Engineer, Google Web Toolkit
http://googlewebtoolkit.blogspot.com/

metalhammer29a

unread,
Dec 1, 2010, 2:27:54 PM12/1/10
to Google Web Toolkit
I am in the similar situation as zixzigma.

one of Thomas Broyer ideas,

>> make each "workspace" it's own GWT app (if they're sufficiently
>>different to deserve it)

could you please explain how this would be possible ?
by breaking the project into modules and use multiple entry points ?
and what if data from one workspace is used in another ?

massimo malvestio

unread,
Dec 2, 2010, 4:22:41 AM12/2/10
to google-we...@googlegroups.com
and what if data from one workspace is used in another ?
 
In my opionion for this point you could fire a specific event, because, if data inside a workspace is needed by another one, this means user did something or a generic condition about displayed data happened. Am I wrong?

PhilBeaudoin

unread,
Dec 2, 2010, 12:04:28 PM12/2/10
to Google Web Toolkit
For anybody considering GWTP (http://gwtplatform.com) as an
alternative to GWT MVP, I want to stress out the fact that, despite
the differences, there are a lot of similarity in the spirit of these
two libraries. For example, gwtplatform's proxies are very similar to
GWT's Activities. The place systems are quite similar too.

One of the difference is that GWTP already offers mechanisms to reduce
boilerplate via annotations and generators. You can hook (lazy) events
to your presenters, define their place, etc. all with simple
annotations right in your presenter. I'm sure GWT will evolve towards
that at some point, but if you need it right away GWTP might not be a
bad choice.

Another difference is that GWTP fully embraces the concept of
presenters, whereas in GWT MVP you need to create them using the
provided building blocks. As you start nesting presenters it is useful
to have mechanisms to maintain a hierarchy and propagate lifecycle
notifications within that hierarchy. In GWT you will likely have to
build some scaffolding for that.

GWTP also has more bells and whistles such as hierarchical places
(useful for breadcrumbs), support for tabbed presenters, etc.

Where GWT shines is in the level of decoupling of the various
components. And the GWTP developers appreciate this a lot. In fact, we
plan to migrate the backend of GWTP towards the core GWT MVP classes
(as they stabilize). Our goal is to let users of the current API
benefit from any improvement provided by the GWT team. In time, we
want GWTP apps to be interoperable with standard GWT MVP apps.

A closing remark: GWTP offers other components that can be used
independently of its MVP framework. If you want to use GWT MVP but
need a good dispatch solution, take a look at GWTP dispatcher.

Cheers,

Philippe

On Dec 2, 1:22 am, massimo malvestio <massimo.malves...@gmail.com>
wrote:

Brian Reilly

unread,
Dec 3, 2010, 8:44:47 AM12/3/10
to google-we...@googlegroups.com
Looks like I'm going to have to eat my hat on this one:


It's a proposal to change Activity from an interface to an abstract class... basically removing the Activity interface and renaming the existing AbstractActivity to Activity.

It sounds like there are other breaking changes coming in 2.1.1. I'm curious to know what they are...

-Brian

On Tue, Nov 30, 2010 at 3:19 PM, Brian Reilly <br...@ireilly.com> wrote:
Reply all
Reply to author
Forward
0 new messages