I had a discussion about this and other propagation issues for non-DOM
events a long time ago when the 1.6 event system was being designed. At the
time, I believe the consensus was that propagation for custom events was a
complex subject and should be left for developers to subclass HandlerManager
and GwtEvent. For example, I had a quite complex use case where I was
implementing synthetic widgets drawn on a Canvas and I needed both capture
and bubbling behavior with totally custom events. Thus, I would subclass
GwtEvent as VirtualEvent and add stopPropagation/preventDefault/etc. I would
also subclass HandlerManager so that it would perform the checks you
outlined above, as well as propagating events between sources.
This was on the old incubator, and it looks like in 1.6, some decisions were
made that makes this more difficult now, as HandlerRegistry is a private
class which cannot be overriden (probably for efficiency), thus
HandlerManager is kind of frozen in stone, so you either have to patch it
(it seems too late for this), or just copy it wholesale. There's no real
harm in creating a totally separate HandlerManager implementation, like a
HandlerManagerWithPropagationModel.

-Ray



On Fri, Aug 28, 2009 at 10:52 AM, Chris <chrish...@gmail.com> wrote:

>
> I realize this is a bit of an old thread; however, I ran across a use
> case where I would like to be able to modify HandlerManager.  In our
> application we would like to be able to "stop" an event from being
> fired further.
>
> One example, we have three event handlers that can be added A, B, C
> (validation, required check, and save rpc).  We add the handlers to a
> button in that order when needed (sub class determine which handlers
> to add).  We want to be able to specify in A or B handler that the
> event should stop propagating to other handlers.
>
> We tried a couple of different things (including starting to add our
> own event handling logic) and we settled on two changes to GWT
> itself.  We added a method to GWTEvent:
>  - public void stop(); /* record that the event should not be passed
> to more handlers */
>  - public void isStopped(); /* is the event stopped for further
> processing */
>  - public void unStop(); /* reset the stop flag to be false - did in
> case event is reused */
>
> In our event handlers we can now call event.stop() to stop further
> propagation.
>
> In HandlerManager.HandlerRegister we modified
>
>    private <H extends EventHandler> void fireEvent(GwtEvent<H> event,
>        boolean isReverseOrder) {
>      Type<H> type = event.getAssociatedType();
>      int count = getHandlerCount(type);
>      if (isReverseOrder) {
>        for (int i = count - 1; i >= 0; i--) {
>          H handler = this.<H> getHandler(type, i);
>          event.dispatch(handler);
>          if(event.isStopped()) { // CUSTOM: event stop processing
>            event.unStop(); // did this in case events are reused
>            break;
>          }
>        }
>      } else {
>        for (int i = 0; i < count; i++) {
>          H handler = this.<H> getHandler(type, i);
>          event.dispatch(handler);
>          if(event.isStopped()) { // CUSTOM: event stop processing
>            event.unStop(); // did this in case events are reused
>            break;
>          }
>        }
>      }
>    }
>
> Just thought I would send a quick note in case future changes are
> being considered for HandlerManager (realizing 2.0 time frame is
> probably off the table).
>
> Chris....
>
> On Aug 7, 12:11 pm, Joel Webber <j...@google.com> wrote:
> > All,
> > There has been a fair amount of discussion about the 1.6 HandlerManager
> and
> > related code, along with a few issues submitted (primarily by Ed), and
> I'm
> > starting this thread to try and reach some kind of consensus on what, if
> > anything, needs to be changed about it. Please note that we need to find
> the
> > simplest things we can do to enable everyone's use cases, without
> creating a
> > new event system from whole cloth, or adding a lot of complexity to
> simple
> > use cases. Please help me to reach convergence so that we can get this
> taken
> > care of reasonably soon.
> >
> > The following are the three issues I'm aware of. I'll work backwards,
> from
> > simplest to most complex.
> >
> > 1. Switching the 'source' of an event object, primarily for composite
> > events.
> > We actually did consider this in the original design. This is the normal
> > pattern for re-firing an event from a composite (the composite has a
> field
> > called 'button' that represents a wrapped widget):
> >
> >     HandlerRegistration addClickHandler(ClickHandler h) {
> >       return button.addClickHandler(new ClickHandler() {
> >         public void onClick(ClickEvent event) {
> >           fireEvent(event);
> >         }
> >       });
> >     }
> >
> > This does require the instantiation of an extra inner class, but the
> design
> > allows the HandlerManager to re-use event objects, even when they're
> fired
> > through multiple layers of widgets and composites.
> >
> > 2. Making the source of a HandlerManager generic (issue 3636).
> > Mark Renouf's comment in this issue was spot on: Doing so would break the
> > delegation described above. I don't see any way around this. Please let
> me
> > know if I've missed something (but please no proposals that would involve
> > redesigning the whole event system).
> >
> > 3. Adding an "interceptor" to the HandlerManager (issue 3628).
> > I'll be honest. I've spent all morning trying to figure out what's being
> > requested here, and I just don't quite get it. I'm sure there's a real
> > problem being described here, but I think I need a very concrete use-case
> > that can't be easily implemented the way things are to fully understand
> it.
> >
> > Thanks for your help,
> > joel.
> >
>

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to