GWT architecture MVP/EventBus (mentioned at Google I/O)

2,570 views
Skip to first unread message

Benju

unread,
Jun 11, 2009, 3:34:07 PM6/11/09
to Google Web Toolkit
I did not attend Google I/O but as soon as the video "Google I/O 2009
- Best Practices for Architecting GWT App" (http://www.youtube.com/
watch?v=PDuhR18-EdM) was posted I reviewed it and was a bit confused
by the idea of an EventBus.

From what I can tell the idea is that UI widgets requiring data from
the server are able to fire off requests for some form of data like
"void getTransactionsForAccount(Account acct)" then at some unknown
later time (ms to seconds ussually) when a response comes in from the
RPC call the eventbus is what actually directly recives the data and
then it is dispatched


Client UI: "Hey call some RPC method with these parameters, my
AsyncCallback is this EventBus thing"

...some unknown time passes while the server does magic...

Client Event Bus: "A response came in of type X/Y/Z I should fire an
event to all interested parties"

Client UI: "According to this event I just recieved some of my UI code
needs to change"


A few things are still very hazy for me...


1- What is missing here is when would the Client UI typically
subscribe/unsubscribe from the event bus. If this were a desktop
application I would simply use weak reference so I would not have to
unsubscribe my UI manually to prevent a memory leak.

2- Is there some EventBus code I should be using that already exists
in the GWT SDK? Is this the same code that is used for handling
widget events like clicking a button?

3- Would you typically have one eventbus code for everything?

4- How does this tie in with the MVP pattern?

If anybody else watched the video I would be curious what they have to
say. Also Ray Ryan mentioned he was going to be creating a new demo
application for GWT developers to see this sort of thing in action.
That would be awesome, does anybody have any thoughts on this as well?

Thanks in advance for your comments.

Thomas Broyer

unread,
Jun 12, 2009, 9:39:33 AM6/12/09
to Google Web Toolkit

On 11 juin, 21:34, Benju <b...@fastcastmedia.com> wrote:
> I did not attend Google I/O but as soon as the video "Google I/O 2009
> - Best Practices for Architecting GWT App" (http://www.youtube.com/
> watch?v=PDuhR18-EdM) was posted I reviewed it and was a bit confused
> by the idea of an EventBus.

For my part, I was pleased to see it as a best practice, as that's
what I'm thinking about for nearly a year (would require a huuuuuuge
refactoring of our app, so it's still "just an idea floating in the
air")
(I didn't watch the video, just looked at the slides)

> From what I can tell the idea is that UI widgets requiring data from
> the server are able to fire off requests for some form of data like
> "void getTransactionsForAccount(Account acct)" then at some unknown
> later time (ms to seconds ussually) when a response comes in from the
> RPC call the eventbus is what actually directly recives the data and
> then it is dispatched

Well, not necessarily, though yes, that's what they said at Google I/
O. One of the reasons is that there are probably more than a single
place where you use that same data in your app (in GMail it could be
the list of mails, the unread count for the "box" and/or label(s), and
the conversation view of course). That way, all places are informed,
wherever the initial request came from.

> Client UI: "Hey call some RPC method with these parameters, my
> AsyncCallback is this EventBus thing"
>
> ...some unknown time passes while the server does magic...
>
> Client Event Bus: "A response came in of type X/Y/Z I should fire an
> event to all interested parties"
>
> Client UI: "According to this event I just recieved some of my UI code
> needs to change"
>
> A few things are still very hazy for me...
>
> 1- What is missing here is when would the Client UI typically
> subscribe/unsubscribe from the event bus.  If this were a desktop
> application I would simply use weak reference so I would not have to
> unsubscribe my UI manually to prevent a memory leak.

As with any event, I'd subscribe in the onLoad and unsubscribe in the
onUnload (would be even better if there was a destructor, so that even
when not attached to the DOM, your widget could receive events and
enter a "dirty" state, so that when it is attached again to the DOM it
knows if it has to refresh or not)

> 2- Is there some EventBus code I should be using that already exists
> in the GWT SDK?  Is this the same code that is used for handling
> widget events like clicking a button?

Wasn't the code shown in the slides? (page #73 in the PDF, the event
bus is just a HandlerManager (GWT 1.6 and upwards))

> 3- Would you typically have one eventbus code for everything?

If your event bus is just a HandleManager as in the presentation's
sample code, then yes.

You would probably have one event bus (instance) for the whole app,
but you could also use some kind of HMVC (HMVP?) with "component-wide"
event buses.
(I'd rather have a single event bus though, and just use "component-
specific" events)

> 4- How does this tie in with the MVP pattern?

slide #73, he seems to be injecting the event bus into the presenter
(I'm not used to MVP but it seems pretty logical to me).

Benju

unread,
Jun 12, 2009, 1:19:18 PM6/12/09
to Google Web Toolkit
Thanks for the reply I have some further thoughts...

Looking at the source code for the event handling in GWT 1.6 it seems
the fundamental difference is as follows...

Old way with listeners

"I am adding this event listener to this component, when the listener
is triggered I know the source must be this component as it is the
only one added to the listener list"

New way with listeners

"I am adding this handler to this component, when something happens to
the component firing and event I will receive a notification, the
event itself will contain enough information such as the source or
custom properties which let me determine how to do something."

The more I think about the architecture outlined by the tech talk the
smarter it seems. For example by using this event driven application
you can swap out the UI much easier. Instead of having a button run
an RPC which on result runs code that that one component you have a
button trigger an RPC request which fires back to a central event
handler which then notifies all interested parties regardless of which
component initiated the request. When swapping out the UI for
browsers to an iPhone specific version it would be much much easier
to just have the exact same handlers and events but swap out the
components which render things to the display.

In my readings last night I discovered another term for what is
outlined in the "EventBus" idea was coined by Martin Fowler as "Event
Collaboration" http://martinfowler.com/eaaDev/EventCollaboration.html.

In the video at 27:3# Ray Ryan shows some MVP code which seems to tie
in with this it uses methods like "HasClickHandlers" to define the
interface for the UI. Does anybody know if this is typical of MVP or
a flavour cooked up by Google? I am having a hard time finding
quality resources describing MVP in the sort of context appropriate to
GWT.

Sumit Chandel

unread,
Jun 16, 2009, 1:22:59 PM6/16/09
to Google-We...@googlegroups.com
Hi Benju,

The use of the HasClickHandlers interface (and other Handler interfaces) is actually just a piece of event-driven architecture that  GWT subscribes to in the 1.6 event handler architecture. Basically, anything that implements the HasClickHandlers interface must provide an implementation for the methods that manage ClickHandlers added to it.

You can apply this principle more generally to your own components. For example, a component that sends EmergencyEvacEvents or wraps a widget that does so might also implement a HasEmergencyEvacHandlers. Whenever the EmergencyEvacEvent occurs, components implementing HasEmergencyEvacHandlers will be responsible for notifying each of the handlers to handle the emergency event.

The following article also explains the same concept through a more complete example (though the article is outdated as it pertains to GWT 1.4).

"Developing Web 2.0 Apps with the Google Web Toolkit" (see section Wiring Event Listeners):

Regarding resources that explain how the MVP pattern relates to GWT, I think the following article on testing methodologies using GWT will help.

"Testing Methodologies Using Google Web Toolkit":

Although the article focuses on testing methodologies, the MVP pattern is explained in code as it helps make it easy to isolate components that we want to test and mock out any other components that it might interact with.

Hope that helps,
-Sumit Chandel

cristian.vrabie

unread,
Jun 17, 2009, 8:08:44 AM6/17/09
to Google Web Toolkit
EventBus(es) work incredible well. I got the chance to test the
pattern in a GWT 1.5 app and it proved to be "magical" :) However,
using a GWT 1.6 handler manager as a application wide event bus, as it
is stated at Google I/O 2009, seems to have some limitations. One of
the biggest I could spot is that the event source would always be some
top level component that instantiated the HandlerManager, not the
actual component that emited the event.
For the moment I'm sticking to my home brewed EventBus. What do you
think?

Thomas Broyer

unread,
Jun 17, 2009, 8:59:24 AM6/17/09
to Google Web Toolkit


On 17 juin, 14:08, "cristian.vrabie" <cristian.vra...@gmail.com>
wrote:
> EventBus(es) work incredible well. I got the chance to test the
> pattern in a GWT 1.5 app and it proved to be "magical" :) However,
> using a GWT 1.6 handler manager as a application wide event bus, as it
> is stated at Google I/O 2009, seems to have some limitations. One of
> the biggest I could spot is that the event source would always be some
> top level component that instantiated the HandlerManager,

Or 'null' actually (from the code in the slides)

> not the
> actual component that emited the event.
> For the moment I'm sticking to my home brewed EventBus. What do you
> think?

Well, why would you need to know the source of the event? Wouldn't
that somehow defeat the use of an event bus in the beginning?

I mean, whether you clicked on a datagrid row or a dataviz plot (drill
down) or a "go up" link (drill up) or the browser's "back" or
"forward" button, you still mean "show X". Does it really matter where
the event comes from?
(as I'm not yet using an event bus, this is a real question; I might
be wrong assuming the actual event source isn't that important)

Ian Bambury

unread,
Jun 18, 2009, 12:01:31 PM6/18/09
to Google-We...@googlegroups.com
2009/6/12 Thomas Broyer <t.br...@gmail.com>


> 1- What is missing here is when would the Client UI typically
> subscribe/unsubscribe from the event bus.  If this were a desktop
> application I would simply use weak reference so I would not have to
> unsubscribe my UI manually to prevent a memory leak.

As with any event, I'd subscribe in the onLoad and unsubscribe in the
onUnload (would be even better if there was a destructor, so that even
when not attached to the DOM, your widget could receive events and
enter a "dirty" state, so that when it is attached again to the DOM it
knows if it has to refresh or not)

I didn't understand that bit.

The presenter needs to subscribe but is just a class and doesn't have an onUnload method. Even if you make it a widget, having subscribed, since the eventbus has a reference to it, you won't get an unload.

Or am I missing something obvious here.

Ian


Thomas Broyer

unread,
Jun 18, 2009, 5:52:06 PM6/18/09
to Google Web Toolkit


On 18 juin, 18:01, Ian Bambury <ianbamb...@gmail.com> wrote:
> 2009/6/12 Thomas Broyer <t.bro...@gmail.com>
>
> > > 1- What is missing here is when would the Client UI typically
> > > subscribe/unsubscribe from the event bus.  If this were a desktop
> > > application I would simply use weak reference so I would not have to
> > > unsubscribe my UI manually to prevent a memory leak.
>
> > As with any event, I'd subscribe in the onLoad and unsubscribe in the
> > onUnload (would be even better if there was a destructor, so that even
> > when not attached to the DOM, your widget could receive events and
> > enter a "dirty" state, so that when it is attached again to the DOM it
> > knows if it has to refresh or not)
>
> I didn't understand that bit.
>
> The presenter needs to subscribe but is just a class and doesn't have an
> onUnload method.

Right!
(couldn't we make the presenters all have onLoad/onUnload methods to
be called by other components when they make use of a presenter; in
the Google I/O slides, the presenter as a method go(Widget) which is
almost equivalent to Widget::onLoad, what happens when you don't need
the component any more, it must have some other method that would be
similar to Widget::onUnload, no? of course, it would mean that
developers have to make sure they call that onUnload method when they
no longer need a component; some asserts in a window.onunload could
make it easier to discover those leaks: the eventbus shouldn't have
any subscriber left. Did I say I'm not really used to MVC/MVP?)

> Even if you make it a widget, having subscribed, since the
> eventbus has a reference to it, you won't get an unload.

This I don't understand, onUnload is called by the parent widget
(through onDetach) when you remove its child (and it thus is detached
from the DOM). Whether the eventbus has a reference to the widget is
orthogonal.

> Or am I missing something obvious here.

I'd rather say it's probably me ;-)

Ian Bambury

unread,
Jun 18, 2009, 6:56:50 PM6/18/09
to Google-We...@googlegroups.com
2009/6/18 Thomas Broyer <t.br...@gmail.com>



On 18 juin, 18:01, Ian Bambury <
ianbamb...@gmail.com> wrote:
> 2009/6/12 Thomas Broyer <
t.bro...@gmail.com>
>

> > As with any event, I'd subscribe in the onLoad and unsubscribe in the
> > onUnload (would be even better if there was a destructor, so that even
> > when not attached to the DOM, your widget could receive events and
> > enter a "dirty" state, so that when it is attached again to the DOM it
> > knows if it has to refresh or not)
>
> I didn't understand that bit.
>
> The presenter needs to subscribe but is just a class and doesn't have an
> onUnload method.

Right!
(couldn't we make the presenters all have onLoad/onUnload methods to
be called by other components when they make use of a presenter; in
the Google I/O slides, the presenter as a method go(Widget) which is
almost equivalent to Widget::onLoad, what happens when you don't need
the component any more, it must have some other method that would be
similar to Widget::onUnload, no? of course, it would mean that
developers have to make sure they call that onUnload method when they
no longer need a component; some asserts in a window.onunload could
make it easier to discover those leaks: the eventbus shouldn't have
any subscriber left. Did I say I'm not really used to MVC/MVP?)

That was my point, really, that there is no method you can just shove the unsubscribe into and have it just happen. You have to create one (calling it what you will, unload(), teardown(), destroy(), etc) and hope the developers will remember to call it. 

> Even if you make it a widget, having subscribed, since the
> eventbus has a reference to it, you won't get an unload.

This I don't understand, onUnload is called by the parent widget
(through onDetach) when you remove its child (and it thus is detached
from the DOM). Whether the eventbus has a reference to the widget is
orthogonal.

I didn't realise that widgets were bird-watchers! :-)

Maybe an example would help explain the problem (either the problem in general, or my problem).

There's an eventbus which is just a singleton for a HandlerManager with some methods for it for requesting data and for registering handlers. The requests might be batched and/or the data might be cached or retrieved from the server, it doesn't matter. If getTemperature() is called, some time later the data will arrive and all the TemperatureUpdateHandlers will get the onTemperatureUpdate(TemperatureUpdateEvent event) methods called.

Anything anywhere requests a current temperature, then everything interested gets told when the news arrives.

The TemperatureAsTextView class extends Composite and is just a label with the temperature in text

The TemperatureAsText class is the presenter. It extends nothing.

To use all this, you need to create a TemperatureAsTextView object, passing it the panel it is to add itself to.

TemperatureAsTextView view = new TemperatureAsTextView (panel);

The view adds itself to the panel.

In some way or another, the view is bound to an instance of the presenter. The view might create the presenter for example. Let's stick with that.

So we have a view on a panel being controlled by a presenter. And we have a bus which lets us register TemperatureUpdateHandlers and also request the temperature.

The presenter registers itself with the bus.

This is my problem, I can't see a way to automatically unregister the presenter. You have to hope the programmer remembers to do it (via whatever name you chose - unload/destroy/zap...) You can't easily make it safe.

You can't register the view or any part of it because the whole idea is that the logic is in the presenter, and you can't have the presenter be part of the view because that is against the principles of MVP

So you have to hope the programmer knows to and remembers to call the method to remove the handlers.

And that is not ideal in my book.

Ian

Ian Petersen

unread,
Jun 18, 2009, 7:46:04 PM6/18/09
to Google-We...@googlegroups.com
On Thu, Jun 18, 2009 at 3:56 PM, Ian Bambury<ianba...@gmail.com> wrote:
> 2009/6/18 Thomas Broyer <t.br...@gmail.com>

>> This I don't understand, onUnload is called by the parent widget
>> (through onDetach) when you remove its child (and it thus is detached
>> from the DOM). Whether the eventbus has a reference to the widget is
>> orthogonal.
>
> I didn't realise that widgets were bird-watchers! :-)

Do you mean ornithologists?

Anyway, I think Thomas is talking about the presenter either being a
widget or wrapping a widget. Widgets are notified when their elements
are removed from the DOM, so you could conceivable make the presenter
aware of the DOM detachment and use that as a convenient time to "get
off the bus". As someone mentioned, though, if the widget is detached
from the DOM but still "alive" then it might get reattached at some
future time. If there was a real destructor then detached widgets
could continue to track state until destruction so they'd be up to
date when reattached. Of course, if wishes were horses....

Ian

Ian Bambury

unread,
Jun 18, 2009, 8:38:45 PM6/18/09
to Google-We...@googlegroups.com
2009/6/19 Ian Petersen <ispe...@gmail.com>

On Thu, Jun 18, 2009 at 3:56 PM, Ian Bambury<ianba...@gmail.com> wrote:
> 2009/6/18 Thomas Broyer <t.br...@gmail.com>
>> Whether the eventbus has a reference to the widget is
>> orthogonal.
>
> I didn't realise that widgets were bird-watchers! :-)

Do you mean ornithologists?

Aren't they eye-doctors? 


Anyway, I think Thomas is talking about the presenter either being a
widget or wrapping a widget.  Widgets are notified when their elements
are removed from the DOM, so you could conceivable make the presenter
aware of the DOM detachment and use that as a convenient time to "get
off the bus".

My (limited) understanding of what Ray Ryan was saying (and what I understand of MVP) is that the presenter is completely separated from the DOM elements (in order to facilitate testing, and because the view is solely responsible for the view so you can swap views in and out as you please). E.g. the example of a presenter would be something like this:

class PhoneEditor
{
    Display display;

    void bindDisplay(Display display)
    {
        this.display = display;
        display.getSaveButton().addClickHandler(new ClickHandler()
        {
            @Override
            public void onClick(ClickEvent event)
            {
                // doSave();
            }
        });
        display.getCancelButton().addClickHandler(new ClickHandler()
        {
            public void onClick(ClickEvent event)
            {
                // doCancel();
            }
        });
    }

    interface Display
    {
        HasClickHandlers getCancelButton();
        HasValue<String> getLabelPicker();
        HasValue<String> getNumberField();
        HasClickHandlers getSaveButton();
    }
}


The presenter isn't (or shouldn't be) a widget. It doesn't get notified of any attachment or detachment because it has no way to know. It might be swapping between two different views (?) and in any case, even if the view is detached from the DOM, you may want it to be updated in case the user switches back to it.

Ian

Thomas Broyer

unread,
Jun 19, 2009, 6:56:41 AM6/19/09
to Google Web Toolkit

On 19 juin, 00:56, Ian Bambury <ianbamb...@gmail.com> wrote:
> 2009/6/18 Thomas Broyer <t.bro...@gmail.com>
>
> That was my point, really, that there is no method you can just shove the
> unsubscribe into and have it just happen. You have to create one (calling it
> what you will, unload(), teardown(), destroy(), etc) and hope the developers
> will remember to call it.
>
[...]
> The presenter registers itself with the bus.
>
> This is my problem, I can't see a way to automatically unregister the
> presenter. You have to hope the programmer remembers to do it (via whatever
> name you chose - unload/destroy/zap...) You can't easily make it safe.

As I said, you can at least tell the programmer he didn't "dispose"
the presenter before the page unloads. That's better than nothing...

> You can't register the view or any part of it because the whole idea is that
> the logic is in the presenter, and you can't have the presenter be part of
> the view because that is against the principles of MVP
>
> So you have to hope the programmer knows to and remembers to call the method
> to remove the handlers.
>
> And that is not ideal in my book.

That's the way it is in a world without destructors and weak
references... that's why onLoad/onUnload is baked into Widget and you
have to call RootPanel.detachNow or RootPanel.detachOnWindowClose
(baked into RootPanel and the widget's wrap(), but if write a wrap()
method yourself, don't forget to call detachOnWindowClose or you'll
have memory leaks).

I personally have no problem with having a MVP micro-framework and
having to extend a Presenter class with those onLoad/onUnload and
detachOnWindowClose (as a last resort when you don't explicitly
dispose the component when you no longer need it); moreover if you can
spot missing disposals at dev/testing time.

Ian Petersen

unread,
Jun 19, 2009, 11:33:29 AM6/19/09
to Google-We...@googlegroups.com
On Thu, Jun 18, 2009 at 5:38 PM, Ian Bambury<ianba...@gmail.com> wrote:
> 2009/6/19 Ian Petersen <ispe...@gmail.com>
>>
>> On Thu, Jun 18, 2009 at 3:56 PM, Ian Bambury<ianba...@gmail.com> wrote:
>> > 2009/6/18 Thomas Broyer <t.br...@gmail.com>
>> >> Whether the eventbus has a reference to the widget is
>> >> orthogonal.
>> >
>> > I didn't realise that widgets were bird-watchers! :-)
>>
>> Do you mean ornithologists?
>
> Aren't they eye-doctors?

Oh! You mean opthamologists! :D

>> Anyway, I think Thomas is talking about the presenter either being a
>> widget or wrapping a widget.  Widgets are notified when their elements
>> are removed from the DOM, so you could conceivable make the presenter
>> aware of the DOM detachment and use that as a convenient time to "get
>> off the bus".
>
> My (limited) understanding of what Ray Ryan was saying (and what I
> understand of MVP) is that the presenter is completely separated from the
> DOM elements (in order to facilitate testing, and because the view is solely
> responsible for the view so you can swap views in and out as you please).

Your understanding of MVP is probably less limited than mine--I
assumed it was a riff on MVC. Anyway, couldn't you design an MVP
framework to include "I'm done paying attention to changes" events,
and use onUnload to trigger them when the presenter is using a widget
and use some other means when it's using something besides a widget?
Maybe we've drifted off into the weeds...

Ian

Ben

unread,
Jun 19, 2009, 5:14:01 PM6/19/09
to Google Web Toolkit
Finally found a thread talking about this presentation. It is very
interesting for me as well.

Thomas, you mentioned slide #73, actually I have some question about
this. In this slide, from my point of view, both PhoneEditWidget and
ContactWidget are just Views in MVP. Phone Editor is Presenter in MVP.
So is ContactViewer a presenter as well? If so, I understand that it
passes Event Bus into Contact Viewer, why it doesn't pass the same
Event Bus into PhoneEditor?

For me, I am still not very clear about how this event bus works.

Thanks,

Ian Bambury

unread,
Jun 19, 2009, 6:21:30 PM6/19/09
to Google-We...@googlegroups.com
The PhoneEditor doesn't need the event bus since it doesn't respond to any events.

The ContactWidget needs the event bus in case the details change in real time, then it can update itself.

If you (the user) want to change the phone number while you are looking at the contact details (the ContactWidget is the view) then you use the PhoneEditor (which shows the PhoneEditWidget).

Basically, you're looking at a phone number display which will update if the phone number changes. If you want to change it, you get a popup editor that lets you do that.

The phone number display subscribes to updates so it will be up-to-date. The popup editor gets populated and then you edit it. You don't want the popup to update while you are putting the new number in so it doesn't do the update thing.

So you are displaying the actual phone number, you decide to update it and get the popup. You put the new number in the popup and submit it (the PhoneEditor knows how to update, it was passed the rpcService).

The data (i.e. the model) gets updated and feeds the change back. This feedback is to the event bus which fires an event to tell every interested widget that the phone number for contact nnn has changed. Including the display you were just looking at.

The way they have done it in the presentation is 'optimistic'. I.e. they update the screen immediately, without waiting for the data to do the round trip. If the update fails and the resulting error doesn't get back, then your screen is showing different data to the model. Ideally, you should change the phone number label to 'updating' and let the feedback put the new number in there. That way the screen has more of a chance of showing the right information (there's still a chance that the update works and the data doesn't get fed back, but at least then the label shows 'updating' rather than out-of-sync information.

I rather suspect that hasn't clarified anything :-)

mabogie

unread,
Jun 20, 2009, 3:53:22 PM6/20/09
to Google Web Toolkit
As I myself didn't understand it completely either, I build a little
testapp for it.
And it was at the same time, my first blog post :)

check it out:
http://www.webspin.be/2009/06/learning-gwt-managing-events-with-eventbus/
> 2009/6/19 Ben <benzhe...@gmail.com>

David Peterson

unread,
Jun 21, 2009, 12:33:27 PM6/21/09
to Google Web Toolkit
On Jun 20, 1:33 am, Ian Petersen <ispet...@gmail.com> wrote:
> > My (limited) understanding of what Ray Ryan was saying (and what I
> > understand of MVP) is that the presenter is completely separated from the
> > DOM elements (in order to facilitate testing, and because the view is solely
> > responsible for the view so you can swap views in and out as you please).
>
> Your understanding of MVP is probably less limited than mine--I
> assumed it was a riff on MVC.  Anyway, couldn't you design an MVP
> framework to include "I'm done paying attention to changes" events,
> and use onUnload to trigger them when the presenter is using a widget
> and use some other means when it's using something besides a widget?
> Maybe we've drifted off into the weeds...

I'm also still wrapping my head around the presentation, but I agree-
Presenter objects are separate from the Widget hierarchy - the just
connect via the Widgets/interfaces exposed in the Display interface.

I think the way to have Presenter objects clean up after themselves
would be to have a Presenter superclass that registers itself with the
event bus to listen for 'Window Closing' events, and cleans itself up.
The main app would have an event listener for 'document.onUnload'
events that notifies the event bus and any Presenters can then tidy
up.

I'd love to see some code for the PlaceManager though...

David

Ed

unread,
Jun 22, 2009, 6:43:54 AM6/22/09
to Google Web Toolkit
I am currious what whould be the performance impact of removing
listeners in the onUnload method instead of leaving them there
(assuming we don't create memory leaks).
I mean: in my case I have a left menu that shows screens on the right
side. These screens are a bit complex and contains much logic that is
contained in the presenter following the MVP pattern. Once the display
is created I leave it created and the user merely swiches screens when
going to another screen.
I don't remove any (local) listeners when switching screens, but could
do that and I am currious if removing (deactivating) about 10
listeners would result in a better performance. I mean: suppose I have
20 menu items, with about 10 listeners, I would have 200 listeners
(own and direct gwt listeners). But when I remove them, I would never
have more then around 10 listeners active as the others are removed
when the screen isn't visible.

The only thing is that, like mentioned above, I have to inform my
presenter about the onUnload event, and often more fine-grained
components that contain the listener (that are connected to the
presenter). This isn't always very elegant I think.


Talking about the event bus. I use a MVC implementation which is
similar to the one used by mygwt (when it was still called mygwt), for
the course grain events, like start app, load app data, init app, etc.
And use the MVP for the fine (local) grain events. This seems to work
fine in my case.

Example: I have about 10 course grain controllers like ControllerMenu,
ControllerHeader, etc... These will contain their own child
controllers that are well controlled by their parent. The controllers
are connected through a super Controller class to an event dispatcher
(the event bus). The controller will register the interested events
and get informed when the event happens (example: app init, load app
data). The dispatcher will wait dispatching events when needed like
when data is loaded from the server (kind of the Handler Manager has
an intern queue to overcome concurrent access problems).
The controller always has at least one View implementation class that
is responsible of creating the screen. The controller will forward his
event to his View when needed.

Just a brief overview how I use the "event bus" system.
I am not so crazy about a global handlermanager as event bus as it's
very sensitive to memory leaks as we don't have weak references in
javascript.
I also have a global model that contains some global data, like member/
partner name, etc... But I don't permit any listener subscription to
this data. I had this in the past, but it's too tricky and if a
developer forget to clean up his listener you have a memory leak (like
mentioned above).
I "solved" this by pushing a Global data change event on my event bus
to the controller that are interested in this event. The controller
will push it to the view and then the view can do whatever he want and
have his own listeners if he wants.
This works in my case, as: I have a fixed number of controllers so the
number of "global listeners" can't grow. Note that memory leaks can
still exists, but then only in a local view, such that the damage is
much less severe. Also because I am planning to remove the complete
view in the future when too many views exists I won't the problem at
all. I mean: the view will automatically be created if it doesn't
exist.

Just sharing my experience.....
Ed

Jason A. Beranek

unread,
Jun 22, 2009, 6:51:17 PM6/22/09
to Google Web Toolkit
Ed,

I may be missing something from the original presentation, but your
description of a limited number of Controllers interacting with your
event bus seems identical in principle to a limited number of
presenters interacting with the event bus (as in Ray Ryan's talk).
Your limit on the number of controllers could be made as a similar
limit on Presenters, and the concepts wouldn't really change (other
than the location of where the event bus lives).

My take away on the event bus is that its still up to the programmer
to exercise rigor in cleaning up references. With regard to the MVP
design pattern and an event bus, there would seem to be a few ways to
handle cleaning up Handlers on unload or navigation: your application
could put all event bus handlers in the Presenter and use a
Windows.ClosingHandler to place the Windows.Closing event on the event
bus for all interested Presenters to handle, or you could supply an
event between your Custom Widget/View to transfer the unload/detach
event to the Presenter (note, this seems to follow the practice of
passing events from View to Presenter as described in the talk.

I do not claim to completely understand all aspects, but I like the
concept of decoupling that actually seems a bit more logical, and the
separation and testing capabilities afford by the MVP design pattern
and Event Bus.

V/r,

Jason

Ed

unread,
Jun 23, 2009, 2:59:35 AM6/23/09
to Google Web Toolkit
He Jason,

Yep, you are right, it's just with my MVC setup you can't just
subscribe to the bus in with a global event handler you can.

For me, it would be ur second option as the Windows.Close event is way
to course grain for me as the application is too complex and there
happens too much for a long time, such that memory leaks can already
have caused big problems before this event occurs.


mabogie

unread,
Jun 25, 2009, 7:02:02 AM6/25/09
to Google Web Toolkit
I'm having trouble with one other thing in that presentation.
In the end of the MVP part, Ray concludes with
contactViewer.go(RootPanel.get());

But, since phoneEditor is a presenter, and display a interface, to
bind the widget to the rootpanel one needs to cast it:

rootPanel.add((Widget)phoneEditor.display);

I want to avoid casting this, how should I do that?

mabogie

unread,
Jun 25, 2009, 7:05:17 AM6/25/09
to Google Web Toolkit
Now I look at this, I realize that for this example, the phoneEditor
is a pop-up.
But the case is still valid in general terms.
The widget implements a widgetInterface, and to bind that widget to
the rootpanel, a cast is necessary in the go() function. How do I
avoid the cast or if I don't, is this best practice?

On 25 jun, 13:02, mabogie <mabo...@gmail.com> wrote:
> I'm having trouble with one other thing in that presentation.
> In the end of theMVPpart, Ray concludes with

asianCoolz

unread,
Jun 26, 2009, 12:57:16 AM6/26/09
to Google Web Toolkit
May i know will the sample app(using MVP + command pattern+ EventBus)
for the talk will be uploaded any sooner? I think many are asking the
same questions.

Daniel Jue

unread,
Jun 29, 2009, 5:13:02 PM6/29/09
to Google-We...@googlegroups.com
Does anyone have a working MVP/Eventbus sample of something simple
like the PhoneEditor?
I don't think I'm doing it right. The code from the IO presentation
leaves out enough details so that I'm not sure what to do.
For instance, in my Presenter.class,

I have something like this:
public class Presenter {
...
private Display display;
interface Display {
HasClickHandlers getSaveButton();
HasClickHandlers getCancelButton();
HasClickHandlers getNumberField();
HasClickHandlers getLabelPicker();
}
void editPhone(Phone phone) {
this.phone = Phone.from(phone);
display.getNumberField().setValue(phone.getNumber());
display.getLabelPicker().setValue(phone.getLabel());
}
...
}
Obviously, a HasClickHandlers object doesn't have a setValue method.
It doesn't feel like I should be casting to the widget here, since we
went through all the trouble of using the Display interface.


I started looking at Mvp4g, but it seems to go off on a tangent with a
code generation class to wire up presenters and views via xml.
http://code.google.com/p/mvp4g/
It's also intertwined with some mvc4g classes.

I just want something basic that works, so I can seed my project from
there. A minimalist, working command style RPC example would be nice
too.
Anyone? If you're in the DC area, I'll buy you a drink!

mabogie

unread,
Jun 29, 2009, 5:19:09 PM6/29/09
to Google Web Toolkit
check this out:

http://www.webspin.be/

I left out the model (Phone class here) and the command pattern, since
I'm not using it yet.

For your comment on the casting: I'm having trouble with that too.
When I want to attach the widgets to the root panel or whatever other
panel, I can't do anything but cast them. But nobody seems to have a
good solution...

On 29 jun, 23:13, Daniel Jue <teamp...@gmail.com> wrote:
> Does anyone have a working MVP/Eventbus sample of something simple
> like the PhoneEditor?
> I don't think I'm doing it right.  The code from the IO presentation
> leaves out enough details so that I'm not sure what to do.
> For instance, in my Presenter.class,
>
> I have something like this:
> public class Presenter {
> ...
> private Display display;
>         interface Display {
>                 HasClickHandlers getSaveButton();
>                 HasClickHandlers getCancelButton();
>                 HasClickHandlers getNumberField();
>                 HasClickHandlers getLabelPicker();
>         }
>         void editPhone(Phone phone) {
>                 this.phone = Phone.from(phone);
>                 display.getNumberField().setValue(phone.getNumber());
>                 display.getLabelPicker().setValue(phone.getLabel());
>         }
> ...}
>
> Obviously, a HasClickHandlers object doesn't have a setValue method.
> It doesn't feel like I should be casting to the widget here, since we
> went through all the trouble of using the Display interface.
>
> I started looking at Mvp4g, but it seems to go off on a tangent with a
> code generation class to wire up presenters and views via xml.http://code.google.com/p/mvp4g/

Thomas Broyer

unread,
Jun 29, 2009, 6:43:03 PM6/29/09
to Google Web Toolkit


On 29 juin, 23:13, Daniel Jue <teamp...@gmail.com> wrote:
> Does anyone have a working MVP/Eventbus sample of something simple
> like the PhoneEditor?
> I don't think I'm doing it right.  The code from the IO presentation
> leaves out enough details so that I'm not sure what to do.
> For instance, in my Presenter.class,
>
> I have something like this:
> public class Presenter {
> ...
> private Display display;
>         interface Display {
>                 HasClickHandlers getSaveButton();
>                 HasClickHandlers getCancelButton();
>                 HasClickHandlers getNumberField();
>                 HasClickHandlers getLabelPicker();
>         }

Slide 59 shows getNumberField and getLabelPicker as HasValue<String>,
not HasClickHandler (and Ray says that ListBox doesn't actually
implement HasValue<String> but it's quite easy to make a
HasValue<String> for a ListBox).

>         void editPhone(Phone phone) {
>                 this.phone = Phone.from(phone);
>                 display.getNumberField().setValue(phone.getNumber());
>                 display.getLabelPicker().setValue(phone.getLabel());
>         }
> ...}
>
> Obviously, a HasClickHandlers object doesn't have a setValue method.
> It doesn't feel like I should be casting to the widget here, since we
> went through all the trouble of using the Display interface.

http://code.google.com/intl/fr-FR/events/io/sessions/GoogleWebToolkitBestPractices.html

ClusterCougar

unread,
Jun 30, 2009, 6:17:46 AM6/30/09
to Google Web Toolkit
In my Display interface, I included a method like

Widget getWidgetView();

which (interestingly enough) returns a widget view of the display
object. this eliminates your casting problem, while still maintaining
a degree of anonymity for the Display interface.

On the command pattern thing, I created a project to work through what
I thought I was seeing. You can see it at

http://code.google.com/p/gwt-command-pattern/

Let me know if you have some suggestions on how to fix the issues I
describe there.

Thanks,
> http://code.google.com/intl/fr-FR/events/io/sessions/GoogleWebToolkit...

gscholt

unread,
Jun 30, 2009, 6:54:28 AM6/30/09
to Google Web Toolkit
On Jun 29, 11:13 pm, Daniel Jue <teamp...@gmail.com> wrote:
> Does anyone have a working MVP/Eventbus sample of something simple
> like the PhoneEditor?
> I don't think I'm doing it right.  The code from the IO presentation
> leaves out enough details so that I'm not sure what to do.
> For instance, in my Presenter.class,
>
> I have something like this:
> public class Presenter {
> ...
> private Display display;
>         interface Display {
>                 HasClickHandlers getSaveButton();
>                 HasClickHandlers getCancelButton();
>                 HasClickHandlers getNumberField();
>                 HasClickHandlers getLabelPicker();
>         }
>         void editPhone(Phone phone) {
>                 this.phone = Phone.from(phone);
>                 display.getNumberField().setValue(phone.getNumber());
>                 display.getLabelPicker().setValue(phone.getLabel());
>         }
> ...}
>
> Obviously, a HasClickHandlers object doesn't have a setValue method.
> It doesn't feel like I should be casting to the widget here, since we
> went through all the trouble of using the Display interface.
>
> I started looking at Mvp4g, but it seems to go off on a tangent with a
> code generation class to wire up presenters and views via xml.http://code.google.com/p/mvp4g/
> It's also intertwined with some mvc4g classes.
>
> I just want something basic that works, so I can seed my project from
> there.  A minimalist, working command style RPC example would be nice
> too.
> Anyone?  If you're in the DC area, I'll buy you a drink!

interface Display {
HasClickHandlers getSaveButton();
HasClickHandlers getCancelButton();
HasValue<String> getNumberField();
HasValue<String> getLabelPicker();
}

This will work for this example at least. If you want to bind events
AND set a value to those fields you'd need to combine the two
interfaces in a new one, or perhaps have two accessor methods.

Gert

Zheren

unread,
Jun 30, 2009, 4:12:17 PM6/30/09
to Google Web Toolkit
So if for a TextBox I need to bind both FocusHandler and BlurHandler,
I need to have two interfaces and combine them?

How does that work?

Jason A. Beranek

unread,
Jun 30, 2009, 4:12:21 PM6/30/09
to Google Web Toolkit
I've struggled with the go(RootPanel.get()) function as well, but
discounted the idea of casting my Presenter.Display interface to a
Widget as it removes an amount of type safety from the presenter and
somewhat defeats the purpose of having a nice generic Display
interface for the Presenter to interact with. One solution I've tried,
which I think is promising, is to add a method to the Display
interface that accepts the Panel object presented to the go function.
For example,

class ContactViewer{
interface Display {
...
void showDisplay( Panel panel );
}
...
public void go( Panel panel ) {
this.display.showDisplay(panel);
}
}

Using this method, a Widget based ContactViewer.Display can add itself
to the supplied Panel object and Mocks can ignore the parameter for
testing purposes. As showing the Display object would be part of UI
testing anyway, this shouldn't effect test cases for the Presenter.

Cheers,

Jason

Miroslav Genov

unread,
Jul 1, 2009, 5:23:21 AM7/1/09
to Google-We...@googlegroups.com
Using of http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/user/client/ui/HasWidgets.html is a better idea. If HasWidgets interface is used then you can use the presenter in a simple unit test without the extension of GWTTestCase cause the Widget is provided to the HasWidgets's add method as an argument.

Regards,
  Miroslav

Gert

unread,
Jul 1, 2009, 6:30:42 AM7/1/09
to Google Web Toolkit
I'm only making guesses here as well... but perhaps either:

interface Display {
HasFocusHandlers getEntryFocus();
HasBlurHandlers getEntryBlur();
}

or something like:

interface FocusableTextEntry extends HasValue<String>,
HasFocusHandlers, HasBlurHandlers {}
interface Display {
FocusableTextEntry getLoginEntry();
}

Not sure what is preferable... to many methods is messay, but a
wildgrowth of interface is also not good - but I suppose you could
combine them to a few basic ones, perhaps something like.

Another thing is, is focus management supposed to be in the Presenter?
I'd guess it's supposed to go in the View... the blur event handlers
come from com.google.gwt.event.dom.client, which implies to me the
need for a GwtTestcase, and the whole idea is to be able to test your
presenter _without_ the need for any displayable widgets and related
code.

Daniel Jue

unread,
Jul 1, 2009, 8:56:51 PM7/1/09
to Google-We...@googlegroups.com
(BTW- Thanks for the corrections on my previous email.)

I'm looking on slide 47, with this code:

    public void execute(final UpdateContact update,
            final AsyncCallback<GetContactsResponse> cb) {
        realService.execute(update, new AsyncCallback<UpdateContactResponse>() {
            public void onFailure(Throwable caught) {
                cb.onFailure(caught);
            }

            public void onSuccess(UpdateContactResponse result) {
                recache(update.getContact());
                cb.onSuccess(result);
                ContactChangeEvent e = new ContactChangeEvent(update
                        .getContact());
                eventBus.fireEvent(e);
            }
        });
    }

The icon in the upper right seems to indicate this is either in your RPC implementation or in the class that calls it.

I can't watch the video right now, but I don't see the significance of having "realService" or the "UpdateContactResponse"

Also in the cb.onSuccess(result), result is of the wrong type.  What exactly is going on here?

I've been creating a skeleton project using all I can from several online examples.  So far it's using the MVP with presenters bound to interfaces, a singleton HandlerManager eventbus using custom Events, and a simple RPC using the command pattern, i.e.:

public interface NumberServiceAsync {
    public static NumberServiceAsync RPC = GWT.create(NumberService.class);

    <T extends Response> void execute(Action<T> action,
            AsyncCallback<T> callback);

}

All I want it to do is given a maximum integer you input, display a random integer up to that value. (for a proof of the concepts)
So far I'm up to 27 classes, not quite done yet.  I'm not using inline/anonymous interfaces or callbacks.

Thomas Broyer

unread,
Jul 2, 2009, 6:56:54 AM7/2/09
to Google Web Toolkit


On 2 juil, 02:56, Daniel Jue <teamp...@gmail.com> wrote:
> (BTW- Thanks for the corrections on my previous email.)
>
> I'm looking on slide 47, with this code:
>
>     public void execute(final UpdateContact update,
>             final AsyncCallback<GetContactsResponse> cb) {
>         realService.execute(update, new
> AsyncCallback<UpdateContactResponse>() {
>             public void onFailure(Throwable caught) {
>                 cb.onFailure(caught);
>             }
>
>             public void onSuccess(UpdateContactResponse result) {
>                 recache(update.getContact());
>                 cb.onSuccess(result);
>                 ContactChangeEvent e = new ContactChangeEvent(update
>                         .getContact());
>                 eventBus.fireEvent(e);
>             }
>         });
>     }
>
> The icon in the upper right seems to indicate this is either in your RPC
> implementation or in the class that calls it.

It's supposed to be a client-side implementation of the service's
*Async that does something more than just sending the request to the
server (as does the implementation created by the generator when you
"instantiate the interface" with GWT.create()); here, the "something
more" is caching the response (in an HashMap or Gears/HTML5 storage)
and broadcasting an event through the event bus.

> I can't watch the video right now, but I don't see the significance of
> having "realService" or the "UpdateContactResponse"

realService is the stub generated at compile time and returned by the
GWT.create() call on the service interface. The code shown above is a
wrapper/proxy around the service to "do something more" (see above).

> Also in the cb.onSuccess(result), result is of the wrong type.  What exactly
> is going on here?

I guess it's actually the "cb" argument, declared as
AsyncCallback<GetContentResponse> instead of
AsyncCallback<UpdateContactResponse>.


Daniel Jue

unread,
Jul 2, 2009, 3:57:23 PM7/2/09
to Google-We...@googlegroups.com
Thanks Thomas!

I feel like my spaghetti-in-a-bowl code is slowly becoming spaghetti-in-a-box. ;-)

I found what appears to be a nice sized app that uses MVP+Eventbus+IOC+Command Patterned RPC+Place all in one spot.  It looks to be property of berkeley.edu.  It also uses AppEngine if that floats your boat.

svn access here:

http://mvz.googlecode.com/svn/trunk/

I'm using the BioSound portion to learn the concepts.


So far I haven't seen anyone using GWT's HandlerManager as their eventBus implementation.  Is this just because it's a new 1.6 feature?  Or is it still adviseable to wrap your own?

Arthur Kalmenson

unread,
Jul 9, 2009, 10:04:58 AM7/9/09
to Google-We...@googlegroups.com
The HandlerManager is indeed new in GWT 1.6, that might be why. If you
wrap your own you can always add new functionality, that might also be
why. Thanks for the link to the MVZ project, it'll be good to see some
example implementations of the concepts.

--
Arthur Kalmenson

Eduardo Nunes

unread,
Jul 9, 2009, 6:47:57 PM7/9/09
to Google-We...@googlegroups.com
Hello guys,

I had a little difficulty to define how establish a communication
between the Presenters. When you deal with just one Presenter, the MVP
pattern is very simple to understand. After a while I found my
solution and I decided to share it with you all. I created a simple
application that contains just four Presenters. It's a small piece of
a briefing issue tracker - well the application domain itself doesn't
matter.

Please, take a look on it and gimme some feedbacks, the idea is to
discuss about it to improve the pattern knowledge at all. In the main
page of the project you will find a brief description of it, the
screens shots, svn access and a simple download.

http://gwt-mvp-sample.googlecode.com

I'm looking forward to your replies.

Best regards,
--
Eduardo S. Nunes
http://e-nunes.com.br

Gert

unread,
Jul 10, 2009, 2:40:38 AM7/10/09
to Google Web Toolkit
On Jul 10, 12:47 am, Eduardo Nunes <esnu...@gmail.com> wrote:
> Hello guys,
>
> I had a little difficulty to define how establish a communication
> between the Presenters. When you deal with just one Presenter, the MVP
> pattern is very simple to understand. After a while I found my
> solution and I decided to share it with you all. I created a simple
> application that contains just four Presenters. It's a small piece of
> a briefing issue tracker - well the application domain itself doesn't
> matter.
>
> Please, take a look on it and gimme some feedbacks, the idea is to
> discuss about it to improve the pattern knowledge at all. In the main
> page of the project you will find a brief description of it, the
> screens shots, svn access and a simple download.
>
> http://gwt-mvp-sample.googlecode.com
>
> I'm looking forward to your replies.

Without looking into the inter-presenter communication, I think you
missed a pretty important point made in the google IO vid (25m1s into
it, http://www.youtube.com/watch?v=PDuhR18-EdM#t=25m1): Your
presenters and their views should not deal with widgets, but with
abstracts like HasValue.

Gert

Thomas Broyer

unread,
Jul 10, 2009, 6:10:26 AM7/10/09
to Google Web Toolkit


On 10 juil, 08:40, Gert <gsch...@gmail.com> wrote:
> On Jul 10, 12:47 am, Eduardo Nunes <esnu...@gmail.com> wrote:
>
> > Hello guys,
>
> > I had a little difficulty to define how establish a communication
> > between the Presenters. When you deal with just one Presenter, the MVP
> > pattern is very simple to understand. After a while I found my
> > solution and I decided to share it with you all. I created a simple
> > application that contains just four Presenters. It's a small piece of
> > a briefing issue tracker - well the application domain itself doesn't
> > matter.
>
> > Please, take a look on it and gimme some feedbacks, the idea is to
> > discuss about it to improve the pattern knowledge at all. In the main
> > page of the project you will find a brief description of it, the
> > screens shots, svn access and a simple download.
>
> >http://gwt-mvp-sample.googlecode.com
>
> > I'm looking forward to your replies.

I wouldn't have used an addClickHandler on the View, but rather a
"HasClickHandlers getAddIssueButton()". Also, I would have named the
EditIssuePresenter method showIssue(Issue issue) instead of go(Issue
issue).

> Without looking into the inter-presenter communication, I think you
> missed a pretty important point made in the google IO vid (25m1s into
> it,http://www.youtube.com/watch?v=PDuhR18-EdM#t=25m1):Your
> presenters and their views should not deal with widgets, but with
> abstracts like HasValue.

I guess it's the crux of Eduardo's experiment: instantiating a new
presenter is easy, as well as registering event handlers and getting/
setting view "values" from the presenter (all of this was explained by
Ray during his I/O session). Putting a component within a RootPanel
isn't that difficult (the .go() method used by Ray) but you introduce
a depending from your presenter on HasWidgets (this has been discussed
already, with no real solution).
Actually, the problem is not really about *communicating* between
presenters (this is the event bus' role) but adding presenters to your
"views": the .go(HasWidget) method is a bit too restrictive: you want
to show/hide (call it activate/deactivate if you prefer) components (I
don't need the ContactDetails when the user is looking at the
ContactList, and I therefore want the ContactDetails to disappear from
screen), you want to add them to complex panels (a Grid or FlexTable,
a DockPanel, a TabPanel, an AbsolutePanel, etc.) where HasWidgets and
a single .add(Widget) isn't enough; and you probably don't want to
wrap your components into SimplePanel's just for the sake of having a
simple .add(Widget).
I do think it's the View's responsibility to attach a "child View" at
the correct "location", maybe along with setting its size and other
"presentation" properties, but yet the parent View still have to cast
the child View into a Widget, or each View has to provide a getWidget
() method just like Eduardo did (the fact that the Presenter also has
a getWidget() is a different thing, but it would at least have to have
a getView() method so you can instantiate a "child Presenter" and pass
it's view to your view to add the view's widget into your own view's
widgets...)

Eduardo Nunes

unread,
Jul 10, 2009, 9:15:27 AM7/10/09
to Google-We...@googlegroups.com
I didn't realize how to implement what you described. Please, if you
have time for it, modify my sample application to follow the things
you pointed out, our if you want to I can add you to the project, so
you can create a branch with this modification.

What do you think?

Thomas Broyer

unread,
Jul 10, 2009, 11:11:59 AM7/10/09
to Google Web Toolkit


On 10 juil, 15:15, Eduardo Nunes <esnu...@gmail.com> wrote:
> On Fri, Jul 10, 2009 at 7:10 AM, Thomas Broyer<t.bro...@gmail.com> wrote:
>
>
> > I wouldn't have used an addClickHandler on the View, but rather a
> > "HasClickHandlers getAddIssueButton()". Also, I would have named the
> > EditIssuePresenter method showIssue(Issue issue) instead of go(Issue
> > issue).
[...]
> > I do think it's the View's responsibility to attach a "child View" at
> > the correct "location", maybe along with setting its size and other
> > "presentation" properties, but yet the parent View still have to cast
> > the child View into a Widget, or each View has to provide a getWidget
> > () method just like Eduardo did (the fact that the Presenter also has
> > a getWidget() is a different thing, but it would at least have to have
> > a getView() method so you can instantiate a "child Presenter" and pass
> > it's view to your view to add the view's widget into your own view's
> > widgets...)
>
> I didn't realize how to implement what you described.

Pretty easy:
- first, replace "Widget getWidget()" in your presenters with "View
getView()" and simply implement it as "return view" (instead of
"return view.getWidget()"); eventually introduce a generic View
interface with a single getWidget() method, and a generic Presenter
interface with a single getView() method.
- next, introduce a MainPresenter.View interface, and move all the
code in MainPresenter dealing Widgets into an implementation of
MainPresenter.View; the MainPresenter.View will have methods taking
views in argument, and the implementation of MainPresenter.View will
get their respective widgets using their getWidget() method.

...and instead of your "Widget go(Issue)" method, I'd have two
methods: getView() as above (with the view having a getWidget()
method) and showIssue(issue).
(In Ray Ryan's I/O presentation, see slide #62 which shows an editPhone
(Phone) method's implementation)

Zheren

unread,
Jul 10, 2009, 2:51:22 PM7/10/09
to Google Web Toolkit
How does this architecture work if I do not have RPC calls? Instead,
mostly I use RequestBuilder to make REST service calls and update/
change View depends on onError or onRespondeReceived callback.

Thanks,

Gert

unread,
Jul 10, 2009, 3:51:01 PM7/10/09
to Google Web Toolkit
Exactly the same, only your implement your service yourself, instead
of relying on the GWTrpc.
You should end up with something similar to (assuming "traditional"
RPC, not the command patten displayed in the Google-IO video):

interface MyService {
void myMethod(..., AsyncCallback<Result>);
}
class MyServiceAsRESTThroughRequestBuilderImplWithALongName implements
MyService {
void myMethod(..., AsyncCallback<Result> cb) {
requestBuilder.sendRequest(..., new RequestCallback() {
void onError(..., Throwable t) {
cb.onError(t);
}
void onResponseReceived(...) {
ok ? cb.onSucces(parsedResult) : cb.onError(parsedError);
}
}
}
}

Pass around a MyService, or a MockMyservice for testing etc...

Eduardo Nunes

unread,
Jul 13, 2009, 1:14:36 AM7/13/09
to Google-We...@googlegroups.com
Hi Mr. Broyer,

I've updated gwt-mvp-sample following your tips. Do you have any other tip?

Thanks at all and I hope it could help someone. If someone else have
any other tip or want to discuss about it, please just reply this
e-mail.

Best Regards

Kwhit

unread,
Jul 13, 2009, 5:18:01 AM7/13/09
to Google Web Toolkit
I'm following your work with interest Eduardo, I'm in the process of
building a 'dream-team reference application' myself including RPC,
EasyMock, GIN, Guice, ... so I can unit test and hack end-to-end
without deploying on a server.

Here's question / comment...

I don't understand the go() method on the presenter impl classes. Take
for example mainPresenter.go(): it does a bit of widget composition
adding the menu and returns the view which is the job of getView().
Then in go() you call menuPresenter.showMenu() which doesn't actually
show the menu but instead it returns the view which is again the job
of MenuPresenterImpl.getView().

My guess is you are (like me) having some problems in the last metre
of the 100m just glueing the application together. I don't have a nice
answer for that yet...

Duong BaTien

unread,
Jul 13, 2009, 11:16:09 AM7/13/09
to Google-We...@googlegroups.com
Hi:
Talking about a dream-team, has any one start to work on JSONP request
and REST response to completely separate client and server services with
Command pattern at client side and workflow at server side?

BaTien
DBGROUPS and BudhNet

Eduardo Nunes

unread,
Jul 13, 2009, 1:17:41 PM7/13/09
to Google-We...@googlegroups.com
On Mon, Jul 13, 2009 at 6:18 AM, Kwhit<kwhitt...@gmail.com> wrote:
>
> I'm following your work with interest Eduardo, I'm in the process of
> building a 'dream-team reference application' myself including RPC,
> EasyMock, GIN, Guice, ... so I can unit test and hack end-to-end
> without deploying on a server.
>
Good, my idea is the same as yours, we will surely share knowledge and
experiences there.

> Here's question / comment...
>
> I don't understand the go() method on the presenter impl classes. Take
> for example mainPresenter.go(): it does a bit of widget composition
> adding the menu and returns the view which is the job of getView().
> Then in go() you call menuPresenter.showMenu() which doesn't actually
> show the menu but instead it returns the view which is again the job
> of MenuPresenterImpl.getView().

My idea with the "go" method is to be an entry point, a place to
initialize something else that shouldn't or couldn't be initialized in
the constructor. Considering the MainPresenter the implementation is
very simple, the composition could be defined in the constructor, but
I felt more comfortable to define it in the "go" method. It returns
the view just for convenience.

Actually I'm thinking about the needed of the "getView" method, that's
something I would talk with you guys. If I will have an entry point
like the method "go" returning the View, is it really necessary to
create a getView method?

Please, take a look in the presenter "IssueEditPresenter". There you
will find two entry points, one for new issues (View createIssue())
and another one to edit already-created issue (View editIssue(Issue
issue).

Yesterday I updated the source code, so please, consider the latest version.

Thanks at all, let's discuss about it and together let's find a good solution ;)

>
> My guess is you are (like me) having some problems in the last metre
> of the 100m just glueing the application together. I don't have a nice
> answer for that yet...

Yes, that's the meaning of this application, try to define a bootstrap
to integrate all of these frameworks using MVP, DI, Command Pattern (I
didn't include it yet because I think it's better to fit the MVP
integration early.

Thomas Broyer

unread,
Jul 15, 2009, 3:43:48 AM7/15/09
to Google Web Toolkit
Just a thought: how about building *some of* the "view hierarchy" via
DI too and inject the very same views (widgets) in both their parent
widget (for "view compositing") and presenter? (only in the case of
singletons of course, and use providers and/or these getView/getWidget
methods we've talked about otherwise).

E.g. in Eduardo's sample: inject a MenuWidget instance into both the
MainWidget constructor and the MenuPresenterImpl (MenuWidget is laid
out by MainWidget and controlled by MenuPresenterImpl); and in the
case of the IssueDisplayXXX and IssueEditXXX, use providers as of
today for lazy-init (inject Provider<IssueDisplayWidget> and
Provider<IssueEditWidget> into MainWidget), but use singletons though,
so that the view and presenter are correctly associated while still
using two distinct, unrelated providers.

And only in those cases where you need several instances of a
component (presenter/view) you'd have to use the getView/getWidget
methods so that you get/create a presenter instance from the Ginjector
which gets injected its own view.

It's just an idea, feel free to reject it with whichever argument
comes to your mind ;-)

Eduardo Nunes

unread,
Jul 19, 2009, 6:28:32 PM7/19/09
to Google-We...@googlegroups.com
For everyone following this thread, I would recommend to take a look
in the presenter's implementation created by David
http://gwt-presenter.googlecode.com

I'm taking a look on it too, and it seems to be very interesting. I
will port my little application as a proof concept. As soon as
possible I will post here a feedback.

Best regards,
Eduardo S. Nunes

Norman Maurer

unread,
Jul 20, 2009, 1:39:04 AM7/20/09
to Google-We...@googlegroups.com
I already ported my app to use gwt-presenter. So far it really work out :)

Bye,
Norman

2009/7/20 Eduardo Nunes <esn...@gmail.com>:

plcoirier

unread,
Aug 11, 2009, 6:26:50 PM8/11/09
to Google Web Toolkit
Hi,

I created a framework, Mvp4g, to easily build gwt application using
Mvp + event bus + DI thanks to an xml file.

A new version is now available (mvp4g-0.13-beta). You can:
-Set an event bus without creating extra classes.
-Configure which presenter handles an event.
-Inject a view and one to many services into the presenter.

I also added the Pure Mvc example (that you can see here:
http://employeeadm.appspot.com/) but implemented with the Mvp4g
framework in order to easily compare the two implementations.

To ensure quality, the framework is covered by JUnit tests.

It's still a beta version because I'd like to add a Place service
before a version 1.0 (I'd actually like people ideas and remarks about
the best way to manage history before starting,
http://groups.google.com/group/mvp4g/browse_thread/thread/3d3e1753c43f1270)

The framework and examples can be downloaded here: http://code.google.com/p/mvp4g/.

I would like people opinions on it.

Thanks :)


On Jul 20, 7:39 am, Norman Maurer <nor...@apache.org> wrote:
> I already ported my app to use gwt-presenter. So far it really work out :)
>
> Bye,
> Norman
>
> 2009/7/20 Eduardo Nunes <esnu...@gmail.com>:
>
>
>
>
>
> > For everyone following this thread, I would recommend to take a look
> > in the presenter's implementation created by David
> >http://gwt-presenter.googlecode.com
>
> > I'm taking a look on it too, and it seems to be very interesting. I
> > will port my little application as a proof concept. As soon as
> > possible I will post here a feedback.
>
> > Best regards,
> > Eduardo S. Nunes
>
> >http://e-nunes.com.br- Hide quoted text -
>
> - Show quoted text -

Yanick

unread,
Aug 13, 2009, 11:39:39 AM8/13/09
to Google Web Toolkit
I'm really much interested into that project. I've been studying MVP
since I saw the famous Google IO video on the subject. I read talks
about it in many places, but nothing solid still, nor any good
tutorial explaining the topic in a clear way (all abstract and good-
practice theories). Since I have more experience with Java than GWT
(meaning that I have coded more Java applications than GWT
applications), I'm focusing mainly on server side components, but
would like to tie that up with a good MVP framework before starting to
write any demo app or any concrete projects.

One question though:

"The first line creates a Java class thanks to the configuration file
and a Generator."
"For example, with the following configuration file:"

How is that class generated from the configuration file? (Sorry to ask
if it's obvious.)
Will the argument of the generated Command always be named "form"? Can
it be changed?

"<event type="displayMessage" calledMethod="onDisplayMessage"
handlers="rootPresenter" eventObjectClass="java.lang.String" />"

Isn't "displayMessage" and "onDisplayMessage" redundant? I, for one,
wouldn't mind simply:

"<event type="displayMessage" handlers="rootPresenter"
eventObjectClass="java.lang.String" />"

and expect "onDisplayMessage" to be called automatically (ie. event
"click" fires onClick())

Other than that, +1! It sure got my attention.

plcoirier

unread,
Aug 14, 2009, 4:34:15 PM8/14/09
to Google Web Toolkit
> One question though:
>
> "The first line creates a Java class thanks to the configuration file
> and a Generator."
> "For example, with the following configuration file:"
>
> How is that class generated from the configuration file? (Sorry to ask
> if it's obvious.)
> Will the argument of the generated Command always be named "form"? Can
> it be changed?
I answered these questions here (http://groups.google.com/group/mvp4g/
browse_thread/thread/d8ee207598bf02fa)

>
> "<event type="displayMessage" calledMethod="onDisplayMessage"
> handlers="rootPresenter" eventObjectClass="java.lang.String" />"
>
> Isn't "displayMessage" and "onDisplayMessage" redundant? I, for one,
> wouldn't mind simply:
>
> "<event type="displayMessage" handlers="rootPresenter"
> eventObjectClass="java.lang.String" />"
>
> and expect "onDisplayMessage" to be called automatically (ie. event
> "click" fires onClick())
Good idea, I created an issue to make the calledMethod optional.

>
> Other than that, +1! It sure got my attention.
Thanks

Zheren

unread,
Aug 19, 2009, 12:46:25 PM8/19/09
to Google Web Toolkit
Hi, Everyone

I start to work on my app which has requirement to have some kind of
action buffer in the client side. All the actions will push to this
buffer and make request to server every 2 or 3 seconds. Basically it
is doing batching. So it should be a good use case to use command
pattern to achieve this. My question is if I am not using RPC but
RequestBuilder, what should I achieve this? And for batching, there
are different ways: 1) I can communicate with the server every 5
actions, for example 2) or I can communicate with server every 2
seconds. Can I do both with the command pattern?

Thanks!
Reply all
Reply to author
Forward
0 new messages