GWT树工具提示:为节点添加鼠标悬停提示

3
我正在尝试为GWT中的树节点添加工具提示。因此,我希望为树节点添加鼠标悬停侦听器,而不是在树本身上添加侦听器。
Treelistener接口似乎是我想要的,但现在已经被弃用,改用处理程序系统。我不太明白如何在单元格上实现鼠标悬停行为,因为我似乎只能将MouseOverHandler添加到树本身。
感谢您的帮助。
3个回答

4
我要冒昧一点,因为我实际上还没有在GWT中使用过Tree,但是我发现TreeItem类是UIObject的子类。任何UIObject都可以调用其setTitle()方法。在幕后,此方法将标准HTML标题属性设置为您传递给setTitle()的任何字符串。
这应该可以为您提供所需的工具提示行为。作为额外的奖励,浏览器为您处理所有鼠标事件:
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;

public class TreeTest extends Composite {

    public TreeTest() {
        Tree root = new Tree();
        initWidget(root);
        TreeItem dogs = new TreeItem("canines");
        dogs.addItem("Fido").setTitle("faithful");
        dogs.addItem("Lassie").setTitle("starlet");
        dogs.addItem("Touser").setTitle("ruthless killer");
        root.addItem(dogs);

        TreeItem cats = new TreeItem("felines");
        cats.addItem("Boots").setTitle("needy");
        cats.addItem("Fabio").setTitle("aloof");
        cats.addItem("Mandu").setTitle("bob seger");
        root.addItem(cats);
    }


}

编辑:现在让我们想象一下,您不想使用上述浏览器内置的工具提示机制,并且希望自己处理鼠标事件。

TreeItem 表面上看起来可能不可行。毕竟,它直接从 UIObject 继承,而不是从 Widget 继承。(Widget 增加到 UIObject 的关键区别是能够处理事件。因此,人们认为我们无法向 TreeItem 添加处理程序!)

尽管这是严格正确的,但请注意,TreeItem 给我们提供了以下构造函数:

public TreeItem(Widget widget)

因此,当我们创建每个实例时,可以将真正的Widget传递给它(例如Label或您自己的class MyWidget extends Composite),并且我们可以直接向其添加事件处理程序:

    import com.google.gwt.core.client.GWT;
    import com.google.gwt.event.dom.client.MouseOutEvent;
    import com.google.gwt.event.dom.client.MouseOutHandler;
    import com.google.gwt.event.dom.client.MouseOverEvent;
    import com.google.gwt.event.dom.client.MouseOverHandler;
    import com.google.gwt.user.client.ui.Composite;
    import com.google.gwt.user.client.ui.Label;
    import com.google.gwt.user.client.ui.Tree;
    import com.google.gwt.user.client.ui.TreeItem;

    public class AnotherTreeTest extends Composite {

        public AnotherTreeTest() {
            Tree root = new Tree();
            initWidget(root);
            TreeItem dogs = new TreeItem("canines");
            makeItem(dogs,"Fido","faithful");
            makeItem(dogs,"Lassie","starlet");
            makeItem(dogs,"Touser","ruthless killer");
            root.addItem(dogs);

            TreeItem cats = new TreeItem("felines");
            makeItem(cats,"Boots","needy");
            makeItem(cats,"Fabio","aloof");
            makeItem(cats,"Mandu","bob seger");
            root.addItem(cats);
        }

        private void makeItem(TreeItem parent, String name, final String tip) {
            Label label = new Label(name);
            TreeItem animal = new TreeItem(label);
            label.addMouseOverHandler(new MouseOverHandler() {

                @Override
                public void onMouseOver(MouseOverEvent event) {
                    GWT.log("mouse over " + tip); // do something better here
                }

            });
            label.addMouseOutHandler(new MouseOutHandler() {

                @Override
                public void onMouseOut(MouseOutEvent event) {
                    GWT.log("mouse out " + tip); // do something better here
                }

            });
            parent.addItem(animal);
        }

}

请注意,可能有其他更便宜的方法来实现这一点。如果您有一棵巨大的树,则为每个节点创建一个小部件可能会变得昂贵。那么您可能需要探索一种更复杂的处理鼠标事件的方式,例如通过拥有一个检查其所在元素的处理程序。

虽然这确实有帮助,但我想为树中的每个不同节点拥有不同的工具提示。这会为整个树提供一个工具提示,对吗? - Goren
1
不,我非常确定TreeItem用于表示每个节点,因此您应该能够在每个节点上调用setTitle()以给每个节点设置不同的工具提示。请注意,几乎GWT中的所有内容最终都继承自UIObject,因此这是一个非常通用的规则。每当您想要工具提示时,请查看Javadoc - 如果在超类链中看到UIObject,那么就可以使用它。 - pohl
谢谢。关于鼠标监听器的主要问题,您有什么想法吗? - Goren
我在上面添加了另一个事件处理的想法。 - pohl
很容易解决我的问题,太棒了! - rich

2

TreeItem可以包含一个Widget对象。因此,在widget(即Label)上添加MouseOverHandler和MouseOutHandler,并将widget放入TreeItem中以添加:

Label myItemContent = new Label("My content");
myItemContent.addMouseOverHandler(new MouseOverHandler() {

  public void onMouseOver(MouseOverEvent event) {
    // construct and/or open your tooltip
  }
});

myItemContent.addMouseOutHandler(new MouseOutHandler() {

  public void onMouseOut(MouseOutEvent event) {
    // close your tooltip

  }
});
//put your Label inside a TreeItem
TreeItem myItem = new TreeItem(myItemContent);
// let's assume that parentNode is an ItemTree
parentNode.addItem(myItem);

另一种解决方案可以使用 GwtQuery。GwtQuery 允许将事件处理程序绑定到任何 DOM 元素:
import static com.google.gwt.query.client.GQuery.$;

...

TreeItem myItem = new TreeItem("My content");
$(myItem.getElement()).hover(new Function() {

  //method called on mouse over
  public void f(Element e) {
      // construct and/or open your tooltip
  }

}, new Function() {

  //method called on mouse out
  public void f(Element e) {
      //close your tooltip
  }
});

parentNode.addItem(myItem);

朱利安


这正是我正在寻找的。谢谢Julien! - Goren

0
我采用的另一种方法是利用CSS。
/**
 * @return a label with a CSS controlled popup
 */
public static Widget labelWithHTMLPopup(String text, String description)
{
    FlowPanel p = new FlowPanel();
    p.addStyleName("tooltipLabel");
    p.add(new Label(text));

    HTML contents = new HTML(description);
    contents.setStyleName("tooltip");
    p.add(contents);

    return p;
}

带有相应的CSS:

/*************** Tooltip **************/

div.tooltip
{
    display: none;

    position: absolute; 
    border: 1px outset black;
    left: 90%;  
    top: -20px;

    background: white;
    padding: 5px;
    box-shadow: 3px 3px 2px 0px #555;       
    overflow-y: auto;
    max-height: 150px;
    font-size: 80%; 
    z-index: 99;
}

div.tooltipLabel
{
    position: relative;
}
div.tooltipLabel:hover div.tooltip
{
    display: block;
    position: absolute; 
}

当然,您可以根据自己的喜好更改样式,添加淡入淡出等效果。

尽量减少使用JavaScript,增加CSS的使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接