Всплывающие подсказки для дерева GWT: добавление наведений курсора мыши на узлы

#gwt #tree #mouseover #tooltip

#gwt #дерево #наведение курсора мыши #всплывающая подсказка

Вопрос:

Я пытаюсь добавить всплывающие подсказки для узлов дерева в GWT. Таким образом, я хотел бы добавить прослушиватель наведения курсора мыши для узлов дерева, а не на само дерево.

Интерфейс Treelistener кажется тем, что я хочу, но теперь он устарел вместо системы обработки. Я не совсем понимаю, как добиться поведения при наведении курсора мыши на ячейку, поскольку, похоже, я могу добавить обработчик наведения курсора мыши только к самому дереву.

Буду признателен за любую помощь, спасибо.

Ответ №1:

Здесь я собираюсь немного напрячься, поскольку на самом деле я еще не использовал a Tree в GWT, но я вижу, что TreeItem класс является подклассом UIObject . Для любого UIObject может быть вызван свой setTitle() метод. По сути, этот метод устанавливает стандартный атрибут HTML title в качестве любой строки, в которую вы вводите 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 добавляет a к UIObject , в конце концов, заключается в способности обрабатывать события. Итак, можно подумать, что мы не можем добавлять обработчики в TreeItem!)

Хотя это строго верно, обратите внимание, что TreeItem дает нам следующий конструктор:

 public TreeItem(Widget widget)
  

Затем, когда мы создадим каждый экземпляр, мы сможем передать в него real 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);
        }

}
  

Обратите внимание, что могут быть другие способы достижения этого, которые являются менее дорогостоящими. Если у вас огромное дерево, то создание Widget для каждого узла может оказаться дорогостоящим. Затем вы можете захотеть изучить более сложный способ обработки событий мыши, возможно, используя один обработчик, который проверяет, в каком элементе он находится.

Комментарии:

1. Хотя это определенно полезно, я хочу иметь разные всплывающие подсказки для каждого отдельного узла в дереве. Это дает одну всплывающую подсказку для всего дерева, правильно?

2. Нет, я почти уверен, что для представления каждого узла используется TreeItem , поэтому вы должны иметь возможность вызывать setTitle() для каждого из них, чтобы предоставить каждому отдельную всплывающую подсказку. Обратите внимание, что практически все в GWT в конечном итоге наследуется от UIObject , так что это довольно универсальное правило. Всякий раз, когда вам нужна всплывающая подсказка, загляните в Javadoc — если вы видите UIObject в цепочке суперклассов, все готово.

3. Ах, спасибо. Есть идеи по основной части вопроса, касающегося прослушивателей мыши?

4. Выше я добавил еще одну идею для обработки событий.

5. простое решение именно моей проблемы, отлично!

Ответ №2:

Элемент дерева может содержать объект Widget. Итак, добавьте MouseOverHandler и MouseOutHandler к виджету (т. Е. ярлыку) и поместите виджет внутрь элемента дерева для добавления :

 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

Комментарии:

1. Это именно то, что я искал. Спасибо, Жюльен!

Ответ №3:

Альтернативный способ, на котором я остановился, — использовать 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; 
}
  

Конечно, вы можете изменить стиль, добавить затухания и т.д. По своему усмотрению.

Меньше javas / javascript и больше css.