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

问题描述 投票:0回答:2

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

java gwt
2个回答
1
投票

作为Adam的优秀答案的替代品,以完全相反的方式运行 - 不是查看每个Widget的根元素并调整它,而是在整个文档上观察mouseover事件,并尝试找出它所在的窗口小部件,尽管我实际上并没有实现工具提示,只是一个console.log消息。

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

这种方法的两个小优点:它不会改变每个Widget元素的title属性,并且它甚至可以在最初设置后添加的小部件上工作,而不是要求它重新运行。缺点:这假设小部件是如何连接的,使用GWT内部而不是实际遍历小部件层次结构,它可能会记录一些UIObject或其他事件处理程序(尽管这些很少是Widget以外的东西,如果这种行为是真的不希望,可以添加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中实现,以允许检查使用Widgets的正在运行的GWT应用程序 - getEventListener只是在元素上寻找__listener属性,而大多数其他行或多或少地直接转换为JS。 getClass()方法是唯一有问题的方法,具体取决于应用程序的编译方式。


1
投票

我有一个小程序可以做你想要的。

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

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

将其类名显示为工具提示。

这是代码:

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());
}

它更深入地检查子窗口小部件,检查父窗口小部件是否是HasWidgetsHasOneWidget的实例。

只需使用RootPanel作为顶级窗口小部件调用此方法,它应该为页面上的所有窗口小部件添加工具提示:

traverse(RootPanel.get());

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

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.