2012-07-13 115 views
5

我正在使用GWT庫(gwt-openlayers),它允許我創建包含任意HTML的地圖彈出窗口,類似於Google Maps。我需要這個HTML來包含一個GWT Button小部件。將GWT小部件插入div元素

我創造了一些HTML元素的即時這樣的:

Element outerDiv = DOM.createDiv(); 
outerDiv.getStyle().setOverflow(Overflow.HIDDEN); 
outerDiv.getStyle().setWidth(100, Unit.PCT); 
outerDiv.appendChild(new HTML(mapPOI.getHtmlDetails()).getElement()); 
Button popupButton = new Button("View Property"); 
popupButton.getElement().getStyle().setFloat(com.google.gwt.dom.client.Style.Float.RIGHT); 
outerDiv.appendChild(popupButton.getElement()); 

然後我得到這些元素的源HTML調用

和插入這個網站進入我的地圖標記。現在我的地圖標記顯示內容ok,包括按鈕。但是,該按鈕不會響應任何事件!從我可以收集的信息來看,這是因爲onAttach()方法上的按鈕永遠不會被調用。

有沒有更好的方法來做到這一點?

感謝,

喬恩

~~~~編輯~~~~

現在我想這樣做,這似乎是一種新的方式是找的接受的方法在其他類似的職位。

首先,我創造我的div:

String divId = "popup-" + ref; 
String innerHTML = "<div id=\"" +divId + "\"></div>"; 

然後我加入這個我的地圖彈出窗口並顯示它(它添加到DOM)。彈出顯示後,我得到的元素如下,並試圖環繞它HTMLPanel:

Element element = Document.get().getElementById(divId); 
HTMLPanel popupHTML = HTMLPanel.wrap(element); 

我的div元素被成功取出。但是,HTMLPanel.wrap(element);未完成。這樣做的原因是,wrap(..)電話RootPanel.detachOnWindowClose(Widget widget),其中包括以下斷言:

assert !widgetsToDetach.contains(widget) : "detachOnUnload() called twice " 
    + "for the same widget"; 
assert !isElementChildOfWidget(widget.getElement()) : "A widget that has " 
    + "an existing parent widget may not be added to the detach list"; 

我把一些斷點,似乎第二斷言失敗!

有沒有人有任何想法,爲什麼這可能是這種情況?如果失敗這個斷言真的導致該方法的完全失敗(不返回)?

回答

3

你的第一種方法是很好的,你只需要註冊onClick事件爲您的按鈕是這樣的:

DOM.sinkEvents(popupButton.getElement(), Event.ONCLICK); 
DOM.setEventListener(popupButton.getElement(), new EventListener() { 
    @Override 
    public void onBrowserEvent(Event event) { 
     //implement the logic after click 
    } 
}); 

我已經檢查了這一點,它的工作原理100%!

2

你可以嘗試像

RootPanel.get("idOfYourMapMarker").add(popupButton); 

RootPanel.get()

不幸的是,RootPanels是AbsolutePanels這是不是很好的佈局,但可以工作,如果你只是有一個簡單的按鈕來添加。你也可以嘗試RootLayoutPanel這會給你一個LayoutPanel(當你只想讓事情流動時也不那麼好)。您最終可能會創建一個容器小部件來爲您做佈局,並將添加到RootPanel。

+0

我試過這種方法,但它似乎不工作。它甚至不會超過'RootPanel.get(「divId」);'但它也不會拋出異常!很奇怪。 – DeadPassive 2012-07-16 12:18:39

0

您添加了該元素,但您必須保留實際GWT Widgets的層次結構。

我沒有看到一個乾淨的方式來做到這一點,但你可以使用像jQuery的通過和ID搶按鈕,添加一個單擊處理程序返回到它會調用原來的單擊處理程序。

private static native void registerEvents(String buttonId, MyClass instance)/*-{ 
    var $ = $wnd.$; 

    //check click 
    $('#'+buttonId).live('click', function(e) { 
     e.preventDefault(); 
     [email protected]::handleButtonClick(Lcom/google/gwt/event/dom/client/ClickEvent;)(null); 
    }); 
}-*/; 

在onAttach或構造函數中調用此registerEvents()。

+0

這會在舊版瀏覽器中造成內存泄漏,有GWT構建的標準方式 – 2012-07-13 18:59:56

+0

他的問題是他正在構建元素,然後爲所有這些元素抓取HTML併發送到第三方小部件(某些地圖標記)。最初的問題已經聽起來很危險,這就是爲什麼我說'我看不到一個乾淨的方式',但是這是一個他可以使用的解決方案,他只需要自己調用和等效的清理方法。 – checketts 2012-07-13 19:08:11

1

SimplePanel是一個DIV。也許這可以用來代替?

0

我曾經有過類似的問題。您可以使用GWT-openlayer的MapWidget如下:

private MapWidget createMapWidget() { 
    final MapOptions defaultMapOptions = new MapOptions(); 
    defaultMapOptions.setDisplayProjection(DEFAULT_PROJECTION); 
    defaultMapOptions.setNumZoomLevels(TOTAL_ZOOM_LEVELS); 

    MapWidget mapWidget = new MapWidget(MAP_WIDGET_WIDTH, MAP_WIDGET_HEIGHT, defaultMapOptions); 

    map = mapWidget.getMap(); 

    return mapWidget; 
} 

然後將其添加到任何面板無論是垂直或水平。

MapWidget mapWgt = createMapWidget(); 

VerticalPanel mainPanel = new VerticalPanel(); 
mainPanel.add(mapWgt); 
... 
... add whatever you want 
... 

你終於可以添加創建Panel(含MapWidget和GWT部件)的​​。此外,您現在應該能夠將處理程序添加到gwt按鈕。