contrib: tooltip listener

204 views
Skip to first unread message

sluramod

unread,
May 18, 2006, 8:46:36 PM5/18/06
to Google Web Toolkit
Wow, it is so easy to write your own components... Here is a useful
class, it will allow you to add tooltips (small help messages) to any
component that support SourcesMouseEvents interface. Here is how to use
it:

Image img = new Image("image.gif");
img.addMouseListener(new TooltipListener("your text", 5000 /* timeout
in milliseconds */, "yourcssclass"));

Source code:

package whatever.client;

import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;

public class TooltipListener extends MouseListenerAdapter {
private static final String DEFAULT_TOOLTIP_STYLE = "TooltipPopup";
private static final int DEFAULT_OFFSET_X = 10;
private static final int DEFAULT_OFFSET_Y = 35;

private static class Tooltip extends PopupPanel {
private int delay;

public Tooltip(Widget sender, int offsetX, int offsetY, final String
text, final int delay, final String styleName) {
super(true);

this.delay = delay;

HTML contents = new HTML(text);
add(contents);

int left = sender.getAbsoluteLeft() + offsetX;
int top = sender.getAbsoluteTop() + offsetY;

setPopupPosition(left, top);
setStyleName(styleName);
}

public void show() {
super.show();

Timer t = new Timer() {

public void run() {
Tooltip.this.hide();
}

};
t.schedule(delay);
}

}

private Tooltip tooltip;
private String text;
private String styleName;
private int delay;
private int offsetX = DEFAULT_OFFSET_X;
private int offsetY = DEFAULT_OFFSET_Y;

public TooltipListener(String text, int delay) {
this(text, delay, DEFAULT_TOOLTIP_STYLE);
}

public TooltipListener(String text, int delay, String styleName) {
this.text = text;
this.delay = delay;
this.styleName = styleName;
}

public void onMouseEnter(Widget sender) {
if (tooltip != null) {
tooltip.hide();
}
tooltip = new Tooltip(sender, offsetX, offsetY, text, delay,
styleName);
tooltip.show();
}

public void onMouseLeave(Widget sender) {
if (tooltip != null) {
tooltip.hide();
}
}

public String getStyleName() {
return styleName;
}

public void setStyleName(String styleName) {
this.styleName = styleName;
}

public int getOffsetX() {
return offsetX;
}

public void setOffsetX(int offsetX) {
this.offsetX = offsetX;
}

public int getOffsetY() {
return offsetY;
}

public void setOffsetY(int offsetY) {
this.offsetY = offsetY;
}

}

And... let me know if there is something wrong with the code :)

Alex

Tiago Serafim

unread,
May 18, 2006, 9:26:00 PM5/18/06
to Google-We...@googlegroups.com
Thank you very much, Alex, for sharing this great example... Now everyone can learns how to design a simple custom widget quickly...

btw, I tested your code and it works fine here!

Thanks again,
Tiago Serafim
--
Tiago Serafim

Mr. Monster

unread,
May 18, 2006, 10:03:21 PM5/18/06
to Google Web Toolkit
Neat :)

mohan

unread,
May 18, 2006, 11:23:39 PM5/18/06
to Google Web Toolkit

Nice work.

js

unread,
May 29, 2006, 2:41:47 AM5/29/06
to Google Web Toolkit
Hi Alex,

Thanks for sharing the tooltip code. One problem I'm trying to solve is
that the popup panel seems to block mouse move and mouse click events
on the parent element.

For instance, if you create a tooltip for an image element, once the
tooltip is visible, the image does not detect the mouse move and mouse
click events anymore.

Would you have any suggestions on how to work around this?

Kind regards,
Johan

js

unread,
May 29, 2006, 4:21:08 AM5/29/06
to Google Web Toolkit
I found a solution myself. This is how I got it to work:

- class TooltipListener must implement MouseListener (extending
MouseListenerAdapter does not work for some reason)
- inner class Tooltip should have an onEventPreview method:
public boolean onEventPreview(Event event) { return true; }

Does this make sense or would it create other problems? It seems to
work fine so far.

Johan

Alexei Sokolov

unread,
May 29, 2006, 3:23:24 PM5/29/06
to Google-We...@googlegroups.com
Johan,

You solution does make sense. PopupPanel hijacks all mouse events, so by overwriting onEventPreview() method you disabled that behavior. As of MouseListener vs. MouseListenerAdapter... In my opinion both of them should work, but if your experience tells otherwise... If you have a minute, please test MouseListener vs. MouseListenerAdapter again, and then based on your experience I will update the code online.

Thank you,
Alex

js

unread,
May 30, 2006, 8:16:02 PM5/30/06
to Google Web Toolkit
Hi Alex,

I've changed my code back to 'extends MouseListenerAdapter' and it
still works, so I guess I did something else wrong before. Thanks for
pointing that out.

One more suggestion I have concerns the positioning of the tooltip. I
found that it needs to be corrected for page scrolling. This is the
code I use, but there may be a better way. I've only been using the API
for a couple of days.

int left = - getPageScrollLeft() +
sender.getAbsoluteLeft() + offsetX;
int top = - getPageScrollTop() +
sender.getAbsoluteTop() + sender.getOffsetHeight() + offsetY;
setPopupPosition(left, top);

...

private int getPageScrollLeft() {
return
DOM.getAbsoluteLeft(DOM.getParent(RootPanel.getBodyElement()));
}

private int getPageScrollTop() {
return
DOM.getAbsoluteTop(DOM.getParent(RootPanel.getBodyElement()));
}


In the positioning of the tooltip I also correct for
sender.getOffsetHeight(), but that's because I'm building small image
buttons and I want the tooltip to pop up below the button.

Johan

ks

unread,
Mar 7, 2007, 5:31:14 PM3/7/07
to sluramod, Google-We...@googlegroups.com
Hi sluramod,

Thanks for the code. I am facing one issue though. I'd be glad if you
could look into this.

My user interface consists of only a label and a textbox, placed in a
horizontal panel. The label is associated with the tooltip listener.
Everything goes fine, until I move the mouse 'fast' from the label to
the textbox; I get this javascript exception:

[ERROR] Uncaught exception escaped
com.google.gwt.core.client.JavaScriptException: JavaScript null
exception: null
at
com.google.gwt.dev.shell.moz.ModuleSpaceMoz.invokeNative(ModuleSpaceMoz.java:
200)
at
com.google.gwt.dev.shell.moz.ModuleSpaceMoz.invokeNativeBoolean(ModuleSpaceMoz.java:
59)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeBoolean(JavaScriptHost.java:
39)
at
com.google.gwt.user.client.impl.DOMImplMozilla.isOrHasChild(DOMImplMozilla.java:
104)
at com.google.gwt.user.client.DOM.isOrHasChild(DOM.java:713)
at
com.google.gwt.user.client.ui.MouseListenerCollection.fireMouseEvent(MouseListenerCollection.java:
91)
at com.google.gwt.user.client.ui.Label.onBrowserEvent(Label.java:107)
at com.google.gwt.user.client.DOM.dispatchEventImpl(DOM.java:950)
at com.google.gwt.user.client.DOM.dispatchEventAndCatch(DOM.java:934)
at com.google.gwt.user.client.DOM.dispatchEvent(DOM.java:902)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)

I know this sounds extremely dumb, initially I had no clue under what
conditions the exception occurred but I finally zeroed in on the exact
conditions. I have repeated this a number of times and found the exact
same thing happening. Also when I move fast from the label to the
textbox the tooltip continues to be displayed, while in other 'normal'
conditions it disappears as soon as the mouse leaves the widget.

Am I missing something extremely basic? Or is such a condition never
going to happen in a real UI, that I can simply ignore it and hope
that users dont move their mice very fast?

I have attached my code below.

Thanks,
ks


public class dnd implements EntryPoint, MouseListener {

TooltipPopup t;

public void onModuleLoad() {

HorizontalPanel tt = new HorizontalPanel();
Label l = new Label("E Value");
TooltipListener ttl = new TooltipListener("My tip", 5000);
ttl.setStyleName("tooltip");
l.addMouseListener(ttl );

tt.add(l);
tt.add( new TextBox());
RootPanel.get().add(tt);
}

public void onMouseEnter(Widget sender){
t.show();
}

public void onMouseMove(Widget sender, int a, int b){
}

public void onMouseLeave(Widget sender){
}

public void onMouseUp(Widget sender, int a, int b){
}

public void onMouseDown(Widget sender, int a, int b){
}

}

On May 18 2006, 7:46 pm, "sluramod" <alexei.soko...@gmail.com> wrote:
> Wow, it is so easy to write your own components... Here is a useful
> class, it will allow you to add tooltips (small help messages) to any
> component that support SourcesMouseEvents interface. Here is how to use
> it:
>
> Image img = new Image("image.gif");
> img.addMouseListener(new TooltipListener("your text", 5000 /* timeout
> in milliseconds */, "yourcssclass"));
>
> Source code:
>
> package whatever.client;
>
> import com.google.gwt.user.client.Timer;
> import com.google.gwt.user.client.ui.HTML;
> import com.google.gwt.user.client.ui.MouseListenerAdapter;
> import com.google.gwt.user.client.ui.PopupPanel;
> import com.google.gwt.user.client.ui.Widget;
>
> public class TooltipListener extends MouseListenerAdapter {
> private static final String DEFAULT_TOOLTIP_STYLE = "TooltipPopup";
> private static final int DEFAULT_OFFSET_X = 10;
> private static final int DEFAULT_OFFSET_Y = 35;
>
> private static classTooltipextends PopupPanel {
> private int delay;
>

> publicTooltip(Widget sender, int offsetX, int offsetY, final String

> tooltip= newTooltip(sender, offsetX, offsetY, text, delay,


> styleName);
> tooltip.show();
> }
>
> public void onMouseLeave(Widget sender) {

> if (tooltip!= null) {

Reply all
Reply to author
Forward
0 new messages