【问题标题】:Google Maps API v3 - Buttons and TextBoxes inside InfoWindow?Google Maps API v3 - InfoWindow 中的按钮和文本框?
【发布时间】:2012-07-17 18:30:28
【问题描述】:

我正在使用来自gwt-google-apis 的新地图 v3 API。

是否可以从 InfoWindow 内的 GWT 小部件中捕获事件?我错过了什么吗?

尝试了上面的代码(button.addClickHandler),它没有显示警报:

    Marker m = Marker.create();
    m.setIcon(MarkerImage.create(icone));
    m.setPosition(LatLng.create(posicao.lat(), posicao.lng()));
    m.setMap(map);

    m.addClickHandler(new ClickHandler() {

        @Override
        public void handle(MouseEvent event) {

            InfoWindow info = InfoWindow.create();

            Button button = new Button("Desativar");
            button.addClickHandler(new com.google.gwt.event.dom.client.ClickHandler() {

                @Override
                public void onClick(ClickEvent event) {
                    Window.alert("click");

                }
            });

            final HTMLPanel html = new HTMLPanel(("<div id='button'></div>"));
            html.add(button, "button");

            info.setContent(html.getElement());
            info.setPosition(posicao);
            info.open(map);

        }
    });

谢谢。

【问题讨论】:

    标签: gwt google-maps-api-3


    【解决方案1】:

    问题是小部件之间的层次结构破坏的结果,通常的方法是通过附加/分离小部件。您可以通过设置小部件的元素来做到这一点。这也是 Google Maps API 的问题。

    这可以通过使用将成为InfoWindow 一部分的假面板来解决,因此当您制作setContent(Widget widget) 时,假面板将被更新并且小部件的元素将被设置为内容(如前所述) .

    请看一下这门课:

    public class MyInfoWindow extends 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);
        }
      }
    
      private IsWidget widgetContent = null;
    
      FakePanel widgetAttacher;
    
      public MyInfoWindow() {
        super(InfoWindowImpl.impl.construct());
      }
    
      private void detachWidget() {
        if (this.widgetAttacher != null) {
          this.widgetAttacher.detachWidget();
          this.widgetAttacher = null;
        }
      }
    
      public void close() {
        super.close();
        detachWidget();
      }
    
      public void setContent(String content) {
        this.widgetContent = null;
        this.detachWidget();
        super.setContent(content);
      }
    
      /** */
      public void setContent(Widget value) {
        this.widgetContent = value;
        setContent(value.getElement());
    
        if (this.widgetAttacher == null) {
          addListener(getJso(), "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);
        }
      }
    
      private void setContent(Element element) {
        InfoWindowImpl.impl.setContent(getJso(), element);
      }
    
      public IsWidget getContentWidget() {
        return widgetContent;
      }
    
      public final native void addListener(JavaScriptObject jso, String whichEvent, Runnable handler)
      /*-{
        var that = jso;
        $wnd.google.maps.event.addListener(jso, whichEvent, function() {
          handler.@java.lang.Runnable::run()();
        });
      }-*/;
    
    }
    

    【讨论】:

    【解决方案2】:

    我必须在 InfoWindow 上构建一个包装器才能使其工作。

    public class NXInfoWindow {
    
        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);
            }
        }
    
        private InfoWindow info;
    
        private IsWidget widgetContent = null;
    
        private Long id;
    
        FakePanel widgetAttacher;
    
        public static NXInfoWindow create(Long id){
            NXInfoWindow myInfo = new NXInfoWindow();
            myInfo.info = InfoWindow.create(); 
            myInfo.id = id;
            return myInfo;
        };
    
        private void detachWidget() {
            if (this.widgetAttacher != null) {
                this.widgetAttacher.detachWidget();
                this.widgetAttacher = null;
            }
        }
    
        public void close() {
            info.close();
            detachWidget();
        }
    
        public void setPosition(LatLng posicao) {
            info.setPosition(posicao);
        }
    
        public void open(GoogleMap map) {
            info.open(map);
        }
    
        public void setContent(Widget value) {
            this.widgetContent = value;
            info.setContent(value.getElement());
    
            if (this.widgetAttacher == null) {
                addListener(info, "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);
            }
        }
    
        private void setContent(Element element) {
            this.setContent(element);
        }
    
        public IsWidget getContentWidget() {
            return widgetContent;
        }
    
        public final native void addListener(JavaScriptObject jso, String whichEvent, Runnable handler)
        /*-{
            var that = jso;
            $wnd.google.maps.event.addListener(jso, whichEvent, function() {
              handler.@java.lang.Runnable::run()();
            });
          }-*/;
    }
    

    【讨论】:

    • setContent(Element element) 调用自己。您也可以将代码用作关闭事件处理程序:info.addCloseClickListener(new CloseClickHandler() { @Override public void handle() { detachWidget(); }}); 并删除本机方法。
    • 也将默认构造函数设为私有,这样会阻止用户调用它(应该禁止,因为您的代码不支持它)。
    猜你喜欢
    • 1970-01-01
    • 2016-02-10
    • 2012-01-06
    • 2011-02-11
    • 2011-01-03
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多