1

我试图弄清楚如何在谷歌地图信息窗口中传播组件的事件。我创建锚点或按钮,并希望处理其中任何一个上的点击事件。

我在这里这里找到了描述的解决方案

但它们都使用谷歌地图包装器进行 gwt。我想避免那些图书馆。

问题:

您知道如何将这些事件从信息窗口传播到包装谷歌地图的 GWT 面板吗?

4

4 回答 4

3

A. 浏览器事件一直冒泡到 DOM 树的顶部。您可以将单击处理程序附加到作为地图 InfoWindow 和小部件的父级的小部件。然后,当用户单击您的按钮时,您需要检查事件源以确保它来自您的按钮。

public void onClick(final ClickEvent event) {    
    Element e = Element.as(event.getNativeEvent().getEventTarget());
    // check if e is your button
}

B. 您可以创建一个常规 GWT 按钮,将 ClickHandler 附加到它。不要将它放在 InfoWindow 内:使用绝对定位和更高的 z-index 将其放在上面。

于 2012-09-29T22:45:12.447 回答
3

基于此处找到的代码:http: //gwt-maps3.googlecode.com/svn/trunk/src/com/googlecode/maps3/client/

我创建了这个类,它解决了不使用外部库的问题(你必须只从给定的链接中获取 InfoWindowJSO 源)然后将 InnerHtml 作为字符串传递给 setContent ...你只需传递 Widget 元素。

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;

public class InfoWindow
{
        static class FakePanel extends ComplexPanel
        {
                public FakePanel(Widget w)
                {
                        w.removeFromParent();
                        getChildren().add(w);
                        adopt(w);
                }

                @Override
                public boolean isAttached()
                {
                        return true;
                }

                public void detachWidget()
                {
                        this.remove(0);
                }
        }

        /** */
        InfoWindowJSO jso;

        /** If we have a widget, this will exist so we can detach later */
        FakePanel widgetAttacher;

        /** Keep track of this so we can get it again later */
        Widget widgetContent;

        /** */
        public InfoWindow()
        {
                this.jso = InfoWindowJSO.newInstance();
        }

        /** */
        public InfoWindow(InfoWindowOptions opts)
        {
                this.jso = InfoWindowJSO.newInstance(opts);
        }

        /** Detaches the handler and closes */
        public void close()
        {
                this.detachWidget();
                this.jso.close();
        }

        /** Detaches the content widget, if it exists */
        private void detachWidget()
        {
                if (this.widgetAttacher != null)
                {
                        this.widgetAttacher.detachWidget();
                        this.widgetAttacher = null;
                }
        }

        /** */
        public void open(JavaScriptObject map)
        {
                this.jso.open(map);
        }

        public void open(JavaScriptObject map, JavaScriptObject marker)
        {
                this.jso.open(map, marker);
        }

        /** */
        public void setOptions(InfoWindowOptions value)
        {
                this.jso.setOptions(value);
        }

        /** */
        public void setContent(String value)
        {
                this.widgetContent = null;
                this.detachWidget();
                this.jso.setContent(value);
        }

        /** */
        public void setContent(Element value)
        {
                this.widgetContent = null;
                this.detachWidget();
                this.jso.setContent(value);
        }

        /** */
        public void setContent(Widget value)
        {
                this.widgetContent = value;
                this.detachWidget();
                this.jso.setContent(value.getElement());

                if (this.widgetAttacher == null)
                {
                        // Add a hook for the close button click
                        this.jso.addListener("closeclick", new Runnable() {
                                @Override
                                public void run()
                                {
                                        detachWidget();
                                }
                        });
                        this.widgetAttacher = new FakePanel(value);
                }
                else if (this.widgetAttacher.getWidget(0) != value)
                {
                        this.widgetAttacher.detachWidget();
                        this.widgetAttacher = new FakePanel(value);
                }
        }

        /** @return the widget, if a widget was set */
        public Widget getContentWidget()
        {
                return this.widgetContent;
        }

        /** */
        public JavaScriptObject getPosition()
        {
                return this.jso.getPosition();
        }

        /** */
        public void setPosition(JavaScriptObject value)
        {
                this.jso.setPosition(value);
        }

        /** */
        public int getZIndex()
        {
                return this.jso.getZIndex();
        }

        /** */
        public void setZIndex(int value)
        {
                this.jso.setZIndex(value);
        }

        /** */
        public void addListener(String whichEvent, Runnable handler)
        {
                this.jso.addListener(whichEvent, handler);
        }
}
于 2012-09-30T07:01:24.407 回答
2

我使用静态值 nextAnchorId 为每个 InfoWindow 唯一地生成 ID,并且当 InfoWindow 准备好时(通常当您调用 infoWindow.open(map); 时),我通过元素 ID 获取锚点并将我的单击处理程序添加到它。这就是 Manolo 正在做的事情,但是这个实现不需要 gwtquery,这意味着我可以在超级开发模式下运行我的代码。

private static int nextAnchorId = 1;

public InfoWindow makeInfo() {
    InfoWindowOptions infoWindowOptions = InfoWindowOptions.create();
    FlowPanel infoContentWidget = new FlowPanel();
    final String theAnchorId_str = "theAnchor" + nextAnchorId;
    HTML theAnchor = new HTML("<a id=\"" + theAnchorId_str + "\">Click me!</a>");
    infoContentWidget.add(theAnchor);
    infoWindowOptions.setContent(infoContentWidget.getElement());
    InfoWindow infoWindow = InfoWindow.create(infoWindowOptions);

    infoWindow.addDomReadyListenerOnce(new InfoWindow.DomReadyHandler() {
        @Override
        public void handle() {
            com.google.gwt.user.client.Element muffinButton = (com.google.gwt.user.client.Element) Document.get().getElementById(theAnchorId_str);
            DOM.sinkEvents(muffinButton, Event.ONCLICK);
            DOM.setEventListener(muffinButton, new EventListener() {
                @Override
                public void onBrowserEvent(Event event) {
                  Window.alert("You clicked on the anchor!");
                  // This is where your click handling for the link goes.
                }
            });
        }
    });

    nextAnchorId++;
    return infoWindow
}
于 2013-09-07T10:44:46.660 回答
1

一个非常简单的解决方案是使用 gwtquery:

确定地图中要添加点击处理程序的锚点并为其定义一个 css 选择器(例如 id=my_link)

使用 gquery 找到它并添加事件。

$('#my_link').click(new Function() {
   public boolean f(Event e) {
     [...]
     return false; //false means stop propagation and prevent default
   }
});

请注意,gwtquery 不是 jquery 的包装器,而是其 api 的完整 gwt 实现,因此将其包含在您的项目中不会使其过载,并且编译器只会拾取您使用的东西。

于 2012-10-01T07:23:34.000 回答