Blog do projektu Open Source JavaHotel

środa, 29 grudnia 2010

Tooltip and GWT

I'd like to add a tooltip to my GWT application to achieve the effect as below, additional information while hovering over an element.





Unfortunately, GWT does not support tooltip as a standard. But no problem to implement it - just add action on onMouseOver event to display tooltip window and action on onMouseOut action to remove it.
PopupTip
So now it is enough to create a label like:
private class LabTip extends PopupTip {
  LabTip() {
    Label l = new Label("Label")
    initWidget(l);
    setMessage("Help test - look how it looks like !");
  }
and it works as expected.

But it is enough for labels (simple widgets) only. What about Button - more complex widget. What's more important - I'd like to have some buttons with tooltip enabled and some buttons without that feature.
So I'd like to achieve to following goals:
  1. One common reusable tooltip component to have the same look and feel.
  2. Button widget with tooltip enabled and without tooltip at all and the code which uses that button is unaware of that (encapsulation).
Java does not allow multiply inheritance so we cannot simply create "tooltiped" button like that:
class ToolTipButton extends Button, PopupTip 
 More complicated approach is required. There is also another problem that widget being tooltiped should be  derived from PopupTip, this class cannot be a class component.
For the buttons I'm using the following API methods only: addClickHandler, setEnabled and isEnabled.Unfortunately, Composite class (the base class for PopupTip) does not inherit these methods, Composite class is based on the Widget class. These methods are available starting from FocusWidget class
http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/index.html?overview-summary.html
So the only solution is to create additional interface  IGFocusWidget and Decorator pattern. IGFocusWidget interface is a Decorator and Button class as is a component. Interface exposes necessary method and in the class body redirects all methods to the appropriate Button methods. To make the whole solution more universal instead of Button class a more general FocusWidget can be used. In case of Button (FocusWidget) not "tooltiped" a concrete Decorator is not derived from PopupTip class to avoid overloading with unused functionality.

So the final class structure is as follows.
For "tooltiped" component
IGFocusWidget (Decorator interface)- FocusToolTipedWidget  (Decorator concrete class)- PopupTip (tooltip functionality). FocusWidget/Button (Decorator component)
For non-tooltiped component - as above but without PopupTip base class.


Implementation:
I'm using factory for producing Buttons and IGFocuseWidget to hide implementation details. Image buttons are created as "tooltiped" and text buttons are not tooltiped.

ButtonFactory
GFocusWidgetFactory

Usage example - after creation of button the user is unaware of the tooltip functionality. They share the same interface.
TestApp

Running example (installed on Google App Engine)
http://javahoteltest.appspot.com/

Brak komentarzy:

Prześlij komentarz