复合组件中的primefaces p:gmap,OverlaySelectEvent为null

时间:2012-04-04 07:39:56

标签: google-maps jsf java-ee primefaces

环境:

1,glassfish 3.1

2,primefaces 3.0.1

要求:

1,开发一个名为“corpInfoMap”的复合组件,它将谷歌地图中公司的位置显示为“标记”。当用户单击标记时,在mapInfoWindow中显示公司的信息。

2,开发另一个名为“corpInfoMapDialog”的复合组件,它是一个p:对话框,包含“corpInfoMap”。

问题:

地图在页面或对话框中都非常出色。但是当用户点击地图中的标记时:

传递给侦听器方法的“OverlaySelectEvent”(事件)为NULL。所以“event.getgetOverlay()”抛出NullPonterException。

代码:

1 corpInfoMap.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:cc="http://java.sun.com/jsf/composite" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:c="http://java.sun.com/jsp/jstl/core" 
    xmlns:f="http://java.sun.com/jsf/core"
>
<cc:interface displayName="单位地理信息">
    <cc:attribute name="mapModel" required="true" displayName="地理信息Model,com.ui.fwjg.viewModel.CorporationMapModel类型" />
    <cc:attribute name="selectedListener" required="true" method-signature="void method(org.primefaces.event.map.OverlaySelectEvent)" displayName="选择锚点的方法" />
</cc:interface>
<cc:implementation>
    <f:view contentType="text/html">
    <p:gmap zoom="#{cc.attrs.mapModel.zoom}" 
            type="HYBRID" 
            center="#{cc.attrs.mapModel.centerWd},#{cc.attrs.mapModel.centerJd}" 
            style="width:#{cc.attrs.mapModel.width}px;height:#{cc.attrs.mapModel.height}px;"
            model="#{cc.attrs.mapModel.model}"
            >
        <p:ajax event="overlaySelect" listener="#{cc.attrs.selectedListener}"></p:ajax>
         <p:gmapInfoWindow rendered="#{cc.attrs.mapModel.selectedMarker != null}" maxWidth="#{cc.attrs.mapModel.width / 2}">
            <p:outputPanel style="text-align:center;display:block;margin:auto:" rendered="#{cc.attrs.mapModel.selectedMarker != null}">
                <h:panelGroup style="width:100%;font-size:1.5em;line-height:2em;font-weight:bold;text-align:center;">
                    #{cc.attrs.mapModel.selectedMarker.data.dwmc}
                </h:panelGroup>
                <h:panelGroup layout="block" styleClass="com-ui-clearboth"></h:panelGroup>
                <h:graphicImage rendered="#{not empty cc.attrs.mapModel.selectedMarker.data.dwsltFile}" 
                                style="max-width:#{cc.attrs.mapModel.width / 2};display:block;margin:20px auto;" 
                                url="/file.ui?f=#{cc.attrs.mapModel.selectedMarker.data.dwsltFile}"></h:graphicImage> 
                <h:outputText value="#{mapBean.marker.title}" />
                <h:panelGroup layout="block" styleClass="com-ui-clearboth"></h:panelGroup>
                <h:outputText rendered="#{not empty cc.attrs.mapModel.selectedMarker.dwjj}" 
                                value="&lt;p style=&quot;font-size:1em;line-height:1.5em;text-indent:2em;&quot;&gt;"
                                escape="false"></h:outputText>
                    <h:outputText rendered="#{not empty cc.attrs.mapModel.selectedMarker.dwjj}" value="#{cc.attrs.mapModel.selectedMarker.dwjj}">
                    </h:outputText>
                <h:outputText rendered="#{not empty cc.attrs.mapModel.selectedMarker.dwjj}" value="&lt;/p&gt;" escape="false"></h:outputText>
            </p:outputPanel> 
        </p:gmapInfoWindow>  
    </p:gmap>
    </f:view>
</cc:implementation>

2 corpInfoMapDialog.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:cc="http://java.sun.com/jsf/composite" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:c="http://java.sun.com/jsp/jstl/core" 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:comuicommon="http://java.sun.com/jsf/composite/components/ui/common">
<!-- INTERFACE -->
<cc:interface displayName="单位地理信息窗口">
    <cc:attribute name="mapModel" required="true" displayName="地理信息Model,com.ui.fwjg.viewModel.CorporationMapModel类型" />
    <cc:attribute name="selectedListener" required="true" method-signature="void method(javax.faces.component.behavior.AjaxBehavior)" displayName="选择锚点的方法" />
    <cc:attribute name="dialogId" default="corpInfoMapDialog" displayName="对话框的ID" />
</cc:interface>
<cc:implementation>
    <p:dialog header="单位地理信息" widgetVar="#{cc.attrs.dialogId}" id="#{cc.attrs.dialogId}" width="#{cc.attrs.mapModel.width}">
        <h:panelGroup rendered="#{cc.attrs.mapModel != null and cc.attrs.mapModel.model != null and (not empty cc.attrs.mapModel.model.markers)}" layout="block">
            <comuicommon:corpInfoMap mapModel="#{cc.attrs.mapModel}" selectedListener="#{cc.attrs.selectedListener}"/>
        </h:panelGroup>
        <h:panelGroup rendered="#{not (cc.attrs.mapModel != null and cc.attrs.mapModel.model != null and (not empty cc.attrs.mapModel.model.markers))}" 
                    layout="block" style="font-size:2em;text-align:center;">
            该单位无地理信息。
        </h:panelGroup>
    </p:dialog>
</cc:implementation>
</html>

3支持豆(其中之一):

@ManagedBean
@ViewScoped
public class JlltWssbDjjsbEditPage  implements Serializable{

    ... // a lot of lines
    private CorporationMapModel corporationMapModel;

    @PostConstruct
    public void init() {
        corporationMapModel = new CorporationMapModel();
        ... // other codes, have no business with corporationMapModel.
    }

    // the OverlaySelectEvent listener method
    // when user click the marker in map, this method is invoked, but the parameter "evnet" is null.
    public void setSelectedMarker(OverlaySelectEvent event){
        corporationMapModel.onMarkerSelect(event);
    }

    public CorporationMapModel getCorporationMapModel() {
        return corporationMapModel;
    }

    public void setCorporationMapModel(CorporationMapModel corporationMapModel) {
        this.corporationMapModel = corporationMapModel;
    }

    // reset the jsb, reset the corporationMapModel's properties(only it's properties, neither it nor the mapModel in it.)
    public void setJsb(JlltWssbDjjsb jsb) {
        this.jsb = jsb;
        Corporation corporation = jsb == null ? null : (jsb.getWineInfo() == null ? null : jsb.getWineInfo().getCorporation());
        corporationMapModel.resetModel(corporation);
        setShowHistory(jsb != null);
        initWineInfo();
    }

    ... // a lot of lines, have no business with 
}

4 CorporationMapModel.java

public class CorporationMapModel implements Serializable{
    private List<Corporation> corporations; // 企业列表 corporation list
    private MapModel model; // 地理信息Model primefaces map model
    private String centerJd; // 地图中间位置-经度 lng
    private String centerWd; // 地图中间位置-维度 lat
    private String zoom; // 地图缩放级别 gmap zoom
    private Marker selectedMarker; // 被选择的Marker selected marker(overlay)
    private int width = 600; // the width(px) of the map
    private int height = 480; // the height(px) of the map 

    public void resetModel(Corporation corporation) {
        List<Corporation> corporations = new ArrayList<Corporation>();
        if(corporation != null){
            corporations.add(corporation);
        }
        setCorporations(corporations);
    }
    public void resetModel(List<Corporation> corporations) {
        corporations = corporations == null ? new ArrayList<Corporation>() : corporations;
        setCorporations(corporations);
    }

    private void calInfosByCorporations() {
        if(model == null)
            model = new DefaultMapModel();
        model.getMarkers().clear();
        if (corporations != null && corporations.size() > 0) {
            for (Corporation corporation : corporations) {
                CorporationMapInfo mapInfo = CorporationMapInfo.generateNewCorporationMapInfo(corporation);
                if (mapInfo != null) {
                    model.addOverlay(mapInfo);
                }
            }
            List<Marker> markers = model.getMarkers();
            if (markers != null && markers.size() > 0) {
                double maxWd = 0D;
                double minWd = 0D;
                double maxJd = 0D;
                double minJd = 0D;
                for (int i = 0; i < markers.size(); i++) {
                    Marker marker = markers.get(i);
                    if (i == 0) {
                        maxWd = marker.getLatlng().getLat();
                        minWd = marker.getLatlng().getLat();
                        maxJd = marker.getLatlng().getLng();
                        minJd = marker.getLatlng().getLng();
                    } else {
                        double wd = marker.getLatlng().getLat();
                        double jd = marker.getLatlng().getLng();
                        maxWd = maxWd < wd ? wd : maxWd;
                        maxJd = maxJd < jd ? jd : maxJd;
                        minWd = minWd > wd ? wd : minWd;
                        minJd = minJd > jd ? jd : minJd;
                    }
                }
                BigDecimal centerWd = new BigDecimal((maxWd + minWd) / 2D);
                BigDecimal centerJd = new BigDecimal((maxJd + minJd) / 2D);
                centerWd = centerWd.setScale(6, BigDecimal.ROUND_HALF_UP);
                centerJd = centerJd.setScale(6, BigDecimal.ROUND_HALF_UP);
                setCenterWd(centerWd.toPlainString());
                setCenterJd(centerJd.toPlainString());
                zoom = GoogleMapZoom.getZoom(maxWd, minWd, maxJd, minJd, width, height);
            }
        }
    }

    public void onMarkerSelect(OverlaySelectEvent event) {
        selectedMarker = (Marker) event.getOverlay();
    }

    public List<Corporation> getCorporations() {
        return corporations;
    }

    public void setCorporations(List<Corporation> corporations) {
        corporations = corporations == null ? new ArrayList<Corporation>() : corporations;
        this.corporations = corporations;
        calInfosByCorporations();
    }

    public MapModel getModel() {
        return model;
    }

    public String getCenterJd() {
        return centerJd;
    }

    public void setCenterJd(String centerJd) {
        this.centerJd = centerJd;
    }

    public String getCenterWd() {
        return centerWd;
    }

    public void setCenterWd(String centerWd) {
        this.centerWd = centerWd;
    }

    public String getZoom() {
        return zoom;
    }

    public void setZoom(String zoom) {
        this.zoom = zoom;
    }

    public Marker getSelectedMarker() {
        return selectedMarker;
    }
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public void setModel(MapModel model) {
        this.model = model;
    }
    public void setSelectedMarker(Marker selectedMarker) {
        this.selectedMarker = selectedMarker;
    }
}

5 js.xhtml(“js”表示“减少”,而非“javascript”),这个xhtml文件中的重要部分:

<h:form id="dwMapForm">
            <comuicommon:corpInfoMapDialog
                mapModel="#{jlltWssbDjjsbEditPage.corporationMapModel}"
                selectedListener="#{jlltWssbDjjsbEditPage.setSelectedMarker(org.primefaces.event.map.OverlaySelectEvent)}"
                dialogId="dwMapDialog"
            />
</h:form>

我做了什么:

1,我搜索了很多,但没有答案。

2,我已经发现,我发现事件对象是由primefaces生成的(至少在AjaxBehaviorRenderer.decode(FacesContext上下文,UIComponent组件,ClientBehavior行为)的方法中,事件对象是存在的,而不是空。)

3,在JlltWssbDjjsbEditPage.setSelectedMarker(OverlaySelectEvent事件)的方法中,该事件为空。

谢谢大家!

我希望我已经说清楚了。

最好的问候!

0 个答案:

没有答案