tags:

views:

2308

answers:

4

I would like to listen for the mouse over event in GWT 1.6. Since GWT 1.6 has introduced handlers and deprecated listeners I'm unsure as to how I can accomplish this with what little information exists.

Note: I have an Element object. That's what I need to add the mouse handler to. I apologize for my lack of clarity.

Thanks!

+2  A: 

You'd want to implement these interfaces in your class:

  • HasMouseOverHandlers
  • HasMouseOutHandlers
  • MouseOverHandler
  • MouseOutHandler

MouseOverEvent is fired when the mouse enters the element, and MouseOutEvent is fired when it's no longer over.

HasMouseOverHandler is implemented like this:

public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
    return addDomHandler(handler, MouseOverEvent.getType());
}

HasMouseOutHandler is implemented like this:

public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
    return addDomHandler(handler, MouseOutEvent.getType());
}

After that you just handle the events with a MouseOverHandler and MouseOutHandler, should be pretty straightforward after that.

If you want to add an EventHandler to an Element that already exists in the HTML the only idea I've come up with is creating a wrapper class. This is completely untested.

class ElementWrapper extends UIObject implements HasMouseOverHandlers, 
HasMouseOutHandlers
{
     public ElementWrapper(Element theElement)
     {
        setElement(theElement);
     }   

    public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
        return addDomHandler(handler, MouseOutEvent.getType());
    }

    public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
        return addDomHandler(handler, MouseOverEvent.getType());
    }
}

Then you could get an existing Element from the HTML and initialize like this:

onModuleLoad()
{
    Element theElement = RootPanel().get("elementID");
    ElementWrapper wrapper = new ElementWrapper(theElement);
    wrapper.addMouseOverHandler(new myHandler());

}

Hope this helps.

Hannson
This didn't work for me. I think it's because most widgets perform more setup when registering themselves with the DOM. My solution http://stackoverflow.com/questions/879349/adding-a-mouseoverhandler-to-an-element/1885631#1885631 was to use an existing, concrete Widget's wrap(Element) method. But I had to know the element's type beforehand.By the way, you wanted to extend Widget, which has addDomHandler(), not UIObject.
Bluu
+3  A: 

I was hoping we'd see an answer before I needed to tackle this myself. There are some errors in the example code he posted, but the post by Mark Renouf in this thread has most of what we need.

Let's say you want to listen for mouse over and mouse out events on a custom widget. In your widget, add two methods:

public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
  return addDomHandler(handler, MouseOverEvent.getType());
}

public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
  return addDomHandler(handler, MouseOutEvent.getType());
}

Then create a handler class:

public class MyMouseEventHandler implements MouseOverHandler, MouseOutHandler {
  public void onMouseOver(final MouseOverEvent moe) {
    Widget widget = (Widget) moe.getSource();
    widget.addStyleName("my-mouse-over");
  }

  public void onMouseOut(final MouseOutEvent moe) {
    Widget widget = (Widget) moe.getSource();
    widget.removeStyleName("my-mouse-over");
  }
}

Finally, add the handler to the widget:

myWidget.addMouseOverHandler(new MyMouseEventHandler());
myWidget.addMouseOutHandler(new MyMouseEventHandler());

If you are only listening to the mouse over event, you can skip the mouse out handling. And if you aren't making a custom widget, the widget my already have a method to add the handler.

Finally, per the warning from the thread, remember to addDomHandler for the mouse events, not addHandler.

CoverosGene
It's not clear to me how I can use this with an Element object? I don't have a Widget, I have an Element. Thanks for taking the time to answer though.
JP
A: 

If you know the element's type, you can wrap the Element and get the appropriate Widget back. In the case of, say, an Image:

Element el = DOM.getElementById("someImageOnThePage");
Image i = Image.wrap(el);
i.addMouseOverHandler(...);

The only problem with this I've encountered is you'll get an AssertionError in HostedMode if the element is already attached to another parent widget. It'll work fine in production however. There's probably a good reason for that assertion, so be careful.

Bluu
A: 

If you know the type of the object some widgets include a static wrap function. From one of them I was able to derive the following class.

public class Widget extends com.google.gwt.user.client.ui.Widget
{
    public Widget(Element element, boolean detatchFromDom)
    {
        super();
        if (detatchFromDom)
            element.removeFromParent();

        setElement(element);

        if (!detatchFromDom)
        {
            onAttach();
            RootPanel.detachOnWindowClose(this);
        }
    }

    public <H extends EventHandler> HandlerRegistration addDomHandlerPub(final H handler, DomEvent.Type<H> type)
    {
        return addDomHandler(handler, type);
    }
}
LINEMAN78