Adding a div element inside a panel?

我只是一个虾纸丫 提交于 2019-12-07 05:09:27

You need to make sure initializeMap() is called on load, to verify the DOM element is accessible.

Try and refresh your approach and use another technique to create the maps panel:

  1. Extend Widget to define a custom widget that will be used for the Google Maps container:

    public class MapPanel extends Widget {
    
        private Element container;
    
        public MapPanel() {
    
            container = DOM.createDiv();
            container.setId("map");
    
            // this is required by the Widget API to define the underlying element
            setElement(container);
        }
    
        @Override
        protected void onLoad() {
            super.onLoad();
    
                initializeMap();
            }
        }
    }
    
  2. Invoke initialization:

    runsPanel.add(new MapPanel());
    

There are other issues, like the id attribute, hard-coded in the JSNI method and forcing duplication of code, and the proper location for initializeMap() and whether to create an overlay type for the JSNI layer, but that's outside the scope here.

References:

Your code works fine, if you make sure to attach runsPanel to the DOM before calling initializeMap().

You can test it with this simple EntryPoint:

@Override
public void onModuleLoad() {

  final Panel runsPanel = new ...Panel; /* Use the kind of panel you like */

  runsPanel.add(new HTMLPanel("<div id=\"map\"></div>"));

  RootLayoutPanel.get().add(runsPanel);

  initializeMap();
}

It's not enough to add the HTMLPanel to the runsPanel. If the runsPanel itself isn't attached to the DOM, then $doc.getElementById('map') cannot find anything.

Note: Make sure to set the height of the "map" div somehow, otherwise you won't see the map.

You might want to simplify things by using UiBinder; see the Hello World example here: https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder

UiBinder lets you write XML that defines the structure of the UI layout, similar to the way you can lay out a page using HTML. However the XML can construct widgets, such as buttons, etc. Further, you can attach a name to an XML element and refer to it in your Java code to bind event handlers to it, etc. It works great and it makes code very easy to read.

Further, however, in these situations, UiBinder can make the native HTML elements for you and nest them the way you want, rather than having to call methods to make widgets and put them inside other widgets. Further, however, the UiBinder documentation says that UiBinder can do a better job of using the browsers native way of representing things, supposedly resulting in more efficient code (from the above link):

Besides being a more natural and concise way to build your UI than doing it through code, UiBinder can also make your app more efficient. Browsers are better at building DOM structures by cramming big strings of HTML into innerHTML attributes than by a bunch of API calls. UiBinder naturally takes advantage of this, and the result is that the most pleasant way to build your app is also the best way to build it.

I think this feature might make it more likely for the browser to correctly register your widgets so they are found later by getElementById().

Your above code might look like this in UiBinder:

<g:HTMLPanel ui:field='my_HTMLPanel'>
  <div ui:field='map_div'>
    <!-- put some HTML here -->
  </div>
</g:HTMLPanel>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!