将GWT小部件插入到div元素中

时间:2012-07-13 14:06:44

标签: gwt html

我正在使用GWT库(gwt-openlayers),它允许我创建一个包含任意HTML的地图弹出窗口,类似于谷歌地图。我需要这个HTML来包含一个GWT Button小部件。

我正在创建一些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
String src = outerDiv.toString();

并将此html插入我的地图标记。现在我的地图标记显示内容确定,包括按钮。但是,该按钮不会响应任何事件!从我可以收集到的,这是因为onAttach()方法的按钮永远不会被调用。

有更好的方法吗?

谢谢,

乔恩

~~~~ EDIT ~~~~

我现在正在尝试一种新方法,这似乎是接受其他类似帖子的公认方法。

首先我要创建我的div:

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

然后我将它添加到我的地图弹出窗口并显示它(将其添加到DOM)。显示弹出窗口后,我按如下方式获取Element,并尝试在其周围包装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";

我放了一些断点,似乎第二个断言失败了!

有人知道为什么会这样吗?如果失败,这个断言真的会导致方法完全失败(不返回)吗?

5 个答案:

答案 0 :(得分: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%有效!

答案 1 :(得分:2)

您可以尝试类似

的内容
RootPanel.get("idOfYourMapMarker").add(popupButton);

请参阅RootPanel.get()

不幸的是,RootPanels AbsolutePanels对于布局来说不是很好,但是如果你只需要添加一个简单的按钮就可以工作。您也可以尝试RootLayoutPanel,这将为您提供一个LayoutPanel(当您只想要事物流动时也不是那么好)。您最终可能会创建一个容器窗口小部件,为您执行布局,并将 添加到RootPanel。

答案 2 :(得分:2)

SimplePanel 是一个DIV。也许这可以用来代替?

答案 3 :(得分:0)

您添加了元素,但您必须保留实际GWT小部件的层次结构。

我没有看到一个干净的方法来执行此操作,但您可以使用类似jQuery的东西来抓取按钮和ID并添加一个点击处理程序,它将调用原始点击处理程序。

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

    //check click
    $('#'+buttonId).live('click', function(e) {
        e.preventDefault();
        instance.@com.package.MyClass::handleButtonClick(Lcom/google/gwt/event/dom/client/ClickEvent;)(null);
    });
}-*/;

在onAttach或构造函数中调用此registerEvents()。

答案 4 :(得分: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小部件)添加到PopupPanel。此外,您现在应该能够将处理程序添加到gwt按钮。