2011-12-15 1 views
5

Ho un problema con Primefaces la cui versione è 3.0.M3. Ho usato gmap e prime p: ajax. Volevo fare qualcosa per fare clic su Marker quando un utente su Gmap fa clic su un marker.NullPointer con Primefaces GMap OverlaySelect event

Ecco il codice

<p:tabView effect="slide" effectDuration="normal" style="width:1050px;height:450px" > 
      <p:tab title="blabla"> 
       <h:panelGrid colums="1">  
       </h:panelGrid> 
      </p:tab> 
      <p:tab title="blabla" > 
       <h:panelGrid colums="1"> 
        <h:form id="mapId"> 

         <p:gmap id="asd" center="39.000409,35.201554" 
          zoom="#{mapBean.modelMap.zoomLevel}" 
          type="ROADMAP" 
          style="width:1000px;height:400px" 
          model="#{mapBean.emptyModel}" 
          widgetVar="map" > 

          <p:ajax event="overlaySelect" listener="#{mapBean.onMarkerSelect}"/> 

         </p:gmap> 

        </h:form> 
       </h:panelGrid> 
      </p:tab></p:tabView> 

e mio ManagedBean

public void onMarkerSelect(OverlaySelectEvent event) { 

    Marker marker = (Marker) event.getOverlay(); 
    if (marker!=null) { 
     System.out.println(marker.getId()); 
    } 
    System.out.println("Clicked"); 
    modelMap.setZoomLevel(modelMap.getZoomLevel()+1); 

} 

bean gestito dichiarazioni

@ManagedBean(name="mapBean") 
@RequestScoped 
public class MapBean implements Serializable 

Sto prendendo NullPointerException in onMarkerSelect metodo. (event.getOverlay();)

+0

Hai provato l'aggiornamento a M4 o RC1? – spauny

+0

Ho lo stesso identico problema. – Simeon

+0

Provato diverse versioni di primefaces (tutte da 3.1 a 3.3) Ho lo stesso problema con tutte loro. – Simeon

risposta

6

risolto il mio problema.

Il problema era che quando il MapModel è stato creato è stato un var locale:

public MapModel getModel() { 

    final MapModel mapModel = new DefaultMapModel(); // this should be a field 

    final Set<MapEventDto> events = service.loadEvents(); 
    for (MapEventDto event : events) { 

     final double latitude = event.getLatitude().doubleValue(); 
     final double longitude = event.getLongitude().doubleValue(); 
     final String magnitude = event.getMagnitude().toString(); 

     final String title = "Id: " + event.getId() + ", Lat: " + latitude + ", Lng: " + longitude + ", Mag: " + magnitude; 

     mapModel.addOverlay(new Marker(new LatLng(latitude, longitude), title)); 

    } 
    return mapModel; 
} 

L'intero mapModel potrebbe essere garbage collection dopo la mappa è reso (in quanto non è più necessario). Quindi, quando viene chiamato l'evento di overlay, non ci sarà più lo mapModel.

Non appena ho reso mapModel un campo del Bean il problema è scomparso.

+0

Se qualcun altro potesse testarlo, sarei estremamente grato. – Simeon

+2

La regola generale in JSF è che i getter/setter dovrebbero ** non ** fare nient'altro che fare * solo * il lavoro a cui sono intitolati: ottenere e impostare una proprietà. La preparazione dei dati dovrebbe essere eseguita nel costruttore (post) o in un metodo di ascolto (azione) o al massimo carico pigro nel getter. Vedi anche http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times – BalusC

3

Utilizzare il campo static come segue. Ha funzionato per me.

final static MapModel mapModel = new DefaultMapModel(); 
+0

Come regola generale, i campi statici non dovrebbero rappresentare lo stato, mentre si apre la strada a molti mal di testa . – Simeon

0
final DefaultMapModel mapModel = new DefaultMapModel(); 

lavorato per variabile come globale, in viewScoped migliore vj

0

ottenuto attraverso questa e risolto modificando portata per il fagiolo di ViewScoped invece di Richiesta Scope, in modo che duri durante l'attività dell'utente .

Nessun dichiaratori finali/static necessari

@ManagedBean(name="mapBean") 
    @ViewScoped 
    public class MapBean implements Serializable { 
    private MapModel draggableModel; 
    ... 
    } 
0

Basta cambiare l'ambito di fagioli al @SessionScoped o @ViewScoped così il bean non verranno inizializzate per ogni richiesta.