Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the GWT sinkEvent functionality works?

Tags:

java

events

gwt

I have a simple GWT setup for testing:

<g:HTMLPanel ui:field="container" width="500px" height="300px">
    <g:Label ui:field="inner" text="hello"></g:Label>
</g:HTMLPanel>

With handlers added:

container.addDomHandler(new ClickHandler()
{
    @Override
    public void onClick(ClickEvent event)
    {
        Window.alert("click on container");
    }
}, ClickEvent.getType());

inner.addDomHandler(new ClickHandler()
{
    @Override
    public void onClick(ClickEvent event)
    {
        Window.alert("click on inner");
    }
}, ClickEvent.getType());

Each of these addHandler calls, as we know from the sources,

DOM.sinkEvents(Element elem, int eventBits)

inside, and the latter, according to docs, "Sets the current set of events sunk by a given element. These events will be fired to the nearest {@link EventListener} specified on any of the element's parents."

But in fact, if you click on inner div the click will be fired to its parent div in any of the 3 ways:

  • if I have not set any ClickHandlers on child

  • if I have set handlers on child

  • if I have set the handlers, but cleared the sinking of ClickEvent with

DOM.sinkEvents(inner.getElement(), DOM.getEventsSunk(getElement()) & ~Event.getTypeInt(ClickEvent.getType().getName()));

Why this happens and what is the true role of sinking the events? Why adding a Handler is related to sinking events, i.e. to firing the same event to parent of the given element? Is it possible to prevent all handlers, added to the given widget from calling without removing them explicitely? I.e. is there a way to stop processing all events on some widget?

like image 793
KutaBeach Avatar asked Nov 15 '13 15:11

KutaBeach


1 Answers

First, sinkEvent is about adding the native event handler on the element, as explained in the GWT wiki.

What you're seeing is event bubbling, which is how events work in browsers: there are 2 phases when dispatching an event: the capture phase (not implemented in old IEs) allows any ancestor element to catch the event before it reaches its target, then in the bubbling phase the event bubbles up the DOM hierarchy. So if you listen for clicks on the HTMLPanel, you'll also receive the bubbling click events from the Label.

You can prevent that by listening to the event at the Label level and calling stopPropagation() so it doesn't bubble up to the HTMLPanel.

like image 127
Thomas Broyer Avatar answered Oct 07 '22 07:10

Thomas Broyer