如何知道我的鼠标在 GWT 中悬停在哪个组件上? [JAVA]

How to know which component my mouse is hovering over in GWT? [JAVA]

我有一个基于 GWT 的应用程序,当我的鼠标悬停在一个元素上时,我希望在该特定元素上触发 getClass() 方法以在 TooTip 中显示 class 名称。我想为页面上的每个元素自动执行此过程。因此,如果我有一种方法可以告诉我鼠标悬停在哪个元素上,我的工作就完成了。请帮忙。

我有一个小程序可以满足您的需求。

想法是递归地遍历小部件树(从父部件到所有子部件)。对于每个访问过的小部件,您可以调用

widget.setTitle(widget.getClass().getName());

使其 class 名称显示为工具提示。

代码如下:

private void traverse(Widget widget) {
    widget.setTitle(widget.getClass().getName());
    if(widget instanceof HasWidgets) {
        Iterator<Widget> iter = ((HasWidgets) widget).iterator();
        while(iter.hasNext())
            traverse(iter.next());
    }
    else
        if(widget instanceof HasOneWidget)
            traverse(((HasOneWidget) widget).getWidget());
}

它更深入到子部件,检查父部件是否是 HasWidgets or HasOneWidget 的实例。

只需将 RootPanel 作为顶级小部件调用此方法,它就会向页面上的所有小部件添加工具提示:

traverse(RootPanel.get());

这是 运行 此方法在 this example 上的结果打印屏幕(注意工具提示显示 com.google.gwt.user.client.ui.PasswordTextBox):

Adam 出色答案的替代方案,以完全相反的方式构建功能 - 不是查看每个 Widget 的根元素并对其进行调整,而是查看整个文档上的 mouseover 事件,并尝试弄清楚它在哪个小部件中,尽管我实际上并没有实现工具提示,目前只是一条 console.log 消息。

原则是从事件发生的元素开始,检查每个父元素,直到发现有 Widget 附加到它,然后记录该详细信息(或者,如果没有找到匹配的父元素,停止。

这种方法的两个小优点:它不会改变每个 Widget 元素的 title 属性,它甚至可以在最初设置后添加的 widget 上工作,而不是要求重新设置它-运行。缺点:这对小部件的连接方式做了一些假设,使用 GWT 内部而不是实际遍历小部件层次结构,并且它可能会记录一些 UIObjects 或其他事件处理程序(尽管这些很少是小部件以外的东西,如果这种行为是真的不需要,可以添加 instanceof Widget 检查)。

    Event.addNativePreviewHandler(e -> {
        // Listen to all events before a widget gets the chance, only handle the "mouseover".
        // Depenending on which ToolTip is used, a "mouseout" handler might be desirable too,
        // to hide the tooltip, or else just use a single instance and move it around the page
        // as needed
        if (e.getTypeInt() != Event.ONMOUSEOVER) {
            return;
        }

        // If the event somehow happens to a non-element, ignore
        EventTarget eventTarget = e.getNativeEvent().getEventTarget();
        if (!Element.is(eventTarget)) {
            return;
        }

        // examine each node up the hierarchy until a parent is found, or we run out of options
        Element elt = eventTarget.cast();
        // Could also add that instanceof check here, ignore non-Widgets
        while (DOM.getEventListener(elt) == null) {
            elt = elt.getParentElement();
            if (elt == null) {
                // give up
                return;
            }
        }

        // Whatever we've found is attached to that element to handle events like a widget would.
        // Other examples include UIObjects (like tree nodes) or GQuery event listeners
        Object attachedObject = DOM.getEventListener(elt);

        // Log it (assumes elemental2, could just as easily use GWT.log()
        // but really should be replaced by your preferred ToolTip
        DomGlobal.console.log(attachedObject.getClass());
    });

这也可以很容易地在普通 JS 中实现,以允许检查使用小部件的 运行ning GWT 应用程序 - getEventListener 只是在寻找 __listener 属性元素,大部分其他行或多或少直接翻译成 JS。 getClass() 方法是唯一有问题的方法,具体取决于应用程序的编译方式。