GWT - v3谷歌地图infowindow内的按钮

时间:2012-09-29 21:50:27

标签: gwt google-maps-api-3 gwt2 infowindow

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

我找到了here所描述的解决方案 和 here

但是这两个都使用谷歌地图包装为gwt。 我想避免使用这些库。

问题:

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

4 个答案:

答案 0 :(得分:3)

一个。浏览器事件一直冒泡到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将它置于顶部。

答案 1 :(得分: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);
        }
}

答案 2 :(得分: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
}

答案 3 :(得分: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实现,所以将它包含在你的项目中不会重载它,编译器会只选择你使用的东西。