覆盖Primefaces GMap渲染器类

时间:2014-01-13 01:48:12

标签: javascript jsf java-ee primefaces primefaces-gmap

我正在尝试覆盖GMap渲染器类,因此我可以在渲染器阶段为其设置样式。我是通过js函数window.onload=function(...)来设置它的,但它非常难看,因为地图首先显示默认样式。只有在1-2秒后它才会改变风格。

这是我的渲染器类:

public class MyGMapRenderer extends GMapRenderer {

@Override
protected void encodeScript(FacesContext context, GMap map) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    String clientId = map.getClientId();
    String widgetVar = map.resolveWidgetVar();
    GMapInfoWindow infoWindow = map.getInfoWindow();

    startScript(writer, clientId);

    writer.write("$(function() {");

    writer.write("PrimeFaces.cw('GMap','" + widgetVar + "',{");
    writer.write("id:'" + clientId + "'");

    //Required configuration
    writer.write(",mapTypeId:google.maps.MapTypeId." + map.getType().toUpperCase());
    writer.write(",center:new google.maps.LatLng(" + map.getCenter() + ")");
    writer.write(",zoom:" + map.getZoom());

    if (!map.isFitBounds()) {
        writer.write(",fitBounds:false");
    }

    //Overlays
    encodeOverlays(context, map);

    //Controls
    if (map.isDisableDefaultUI()) {
        writer.write(",disableDefaultUI:true");
    }
    if (!map.isNavigationControl()) {
        writer.write(",navigationControl:false");
    }
    if (!map.isMapTypeControl()) {
        writer.write(",mapTypeControl:false");
    }
    if (map.isStreetView()) {
        writer.write(",streetViewControl:true");
    }

    //Options
    if (!map.isDraggable()) {
        writer.write(",draggable:false");
    }
    if (map.isDisableDoubleClickZoom()) {
        writer.write(",disableDoubleClickZoom:true");
    }

    //##### HERE THE ONLY LINE I ADDED ####
    writer.write(",styles:[{\"stylers\":[{hue:\"#0077ff\"}]}]");


    //Client events
    if (map.getOnPointClick() != null) {
        writer.write(",onPointClick:function(event) {" + map.getOnPointClick() + ";}");
    }

    /*
     * Behaviors
     * - Adds hook to show info window if one defined
     * - Encodes behaviors
     */
    if (infoWindow != null) {
        Map<String, List<ClientBehavior>> behaviorEvents = map.getClientBehaviors();
        List<ClientBehavior> overlaySelectBehaviors = behaviorEvents.get("overlaySelect");
        for (ClientBehavior clientBehavior : overlaySelectBehaviors) {
            ((AjaxBehavior) clientBehavior).setOnsuccess("PF('" + widgetVar + "').openWindow(data)");
        }
    }

    encodeClientBehaviors(context, map);

    writer.write("});});");

    endScript(writer);
}
}

faces-config.xml中:

<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.GMapRenderer</renderer-type>
        <renderer-class>br.com.carona.mb.MyGMapRenderer</renderer-class>
    </renderer>
</render-kit>

其他观察结果是我通过ajax更新地图时重新绘制了所有地图,从而避免了这种丑陋的闪光。所以我通过javascript,remoteCommand和inputHidden的组合添加和操作来自backing bean的每个标记。它工作得非常好。

唯一的问题是触发叠加选择事件时:

var markers = new Array();
 function loadMarks(){
 for(var i=0;markers.length>i; i++){
  markers[i].setMap(null);
 }


markers = new Array();
var marksJSON=document.getElementById('form:marks').value;
var marksArray= JSON.parse(pontosStr);
bounds = new google.maps.LatLngBounds();
for (var i = 0;pontos.length>i; i++) {
    var ponto = pontos[i];
    var marker= new google.maps.Marker(
    {
        position: new google.maps.LatLng(ponto.lat, ponto.lon),
        icon: ponto.icon,
        id: ponto.id,
        draggable: ponto.draggable
    });

    marker.setMap(wmap.getMap());
    bounds.extend(marker.getPosition());

    //THAT DON'T WORK ANYMORE
    google.maps.event.addListener(marker, 'click', function(event) {
         wmap.fireOverlaySelectEvent(event, this);
    });  


    //Drag is working fine
    google.maps.event.addListener(marker, 'dragend', function(event) {
        wmap.fireMarkerDragEvent(event, this);
    });

    markers.push(marker);
}
var map=wmap.getMap();
var zoomChangeBoundsListener =
google.maps.event.addListener(map, 'bounds_changed', function(event) {
    google.maps.event.removeListener(zoomChangeBoundsListener);
    map.setZoom( Math.min( 17, map.getZoom() ) );
});
wmap.getMap().fitBounds(bounds);
}

我的地图:

 <p:gmap id="gmap"  widgetVar="wmap" mapTypeControl="false" fitBounds="true" center="-18.57904130, -46.51830770" model="#{procuraRotaMB.mapModel}" zoom="14" type="ROADMAP" style="width:700px;height:600px">  
                    <p:ajax event="pointSelect" listener="#{procuraRotaMB.onPointSelect}" update=":form:marks" oncomplete="setupMarks();" />  
                    <p:ajax event="markerDrag" listener="#{procuraRotaMB.onMarkerDrag}" update=":formProcurar:pontos" oncomplete="setupMarks();" />
                    <p:ajax event="overlaySelect" listener="#{procuraRotaMB.onMarkerSelect}" update=":form:destinoRota,:form:infoW" oncomplete="setupDestiny();"/>
                    <p:gmapInfoWindow id="infoW"> 
                            ...
                    </p:gmapInfoWindow>
</p:gmap>

编辑:

我刚刚发现问题实际上在InfoWindow中。当我删除它一切正常。

1 个答案:

答案 0 :(得分:0)

错误是GMapRenderer类中源代码和JAR之间的差异。更准确地说,在编写行为的行中,在encodeScript方法中。

我已经在primefaces论坛发布了这个问题。