#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.