2012-07-13 90 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按钮。