2012-09-29 259 views
1

裏面的按鈕我想弄清楚如何在谷歌地圖InfoWindow內傳播組件的事件。 我創建了一個錨或一個按鈕,並希望處理其中任何一個點擊事件。GWT - v3谷歌地圖infowindow

我已經找到了解決方案描述herehere

,但這些都被使用谷歌地圖的包裝爲GWT。 我想避免這些庫。

問題:

你知道有什麼辦法,我怎麼可以從傳播信息窗口,這些事件給它包裝谷歌地圖的一些GWT面板?答:

回答

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

A.瀏覽器事件一直冒泡到DOM樹頂部。您可以將點擊處理程序附加到InfoWindow和widget的父級控件。然後,當用戶點擊你的按鈕時,你需要檢查事件的來源,以確保它來自你的按鈕。

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

一個非常簡單的解決方案是使用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實現,所以包括在您的項目不會過載它,編譯器會拿起剛纔你用的東西。

2

我使用靜態值nextAnchorId來爲每個InfoWindow唯一地生成ID,並且當InfoWindow準備就緒時(通常當您調用infoWindow.open(map);)時,我通過元素ID獲取錨點並添加我的Click處理程序到它。這就是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 
}