2011-03-27 13 views
5

Core JSF 3 kitabından p375 örneğini kullanarak kendi destek fasulyesi, ile çalışan bir kompozit bileşen almaya çalışıyorum, ancak sadece bir NPE al. Sorun, encodeBegin() başlangıcında gibi görünüyor, Tarih date = (Tarih) getValue() null döndürür. Dürüst olursam, bileşenin değerinin nerede saklanacağını gerçekten anlamıyorum. depolanıyor, bunu cc: attribute type = java.util.Date olarak belirtiyorum, ancak ben gerçekten yok nasıl olduğunu anlayın: public Object getSubmittedValue() {return this; } - Bir InputDateBean sınıfının bir örneğini döndürecek olan - Bir Tarih ile sonuçlanır. Bunun nasıl çalışması gerektiği genellikle iyi ve kafam karıştı.JSF kompozit komponent, destek kabı ile

Kitap örneğinin tersine, geçici depolama alanı için geri yükleme bileşenini kullanmaya çalışıyorum, , bu nedenle gün girildiğinde, onu [{cc.day} içinde depolamaya çalışıyorum, kitapta onlar için bir uygulama kapsamlı fasulye kullanıyorlar bir sebep.

Yardımlarınız için teşekkür ederiz. Mojarra 2.1 kullanıyorum.

inputDate.xhtml

<cc:interface componentType="uk.co.myco.jsfbeans.sqcc.InputDateBean"> 
    <cc:attribute name="value" type="java.util.Date"/> 
</cc:interface> 

<cc:implementation> 
    <h:panelGrid columns="3"> 
     <h:inputText id="day" value="#{cc.day}" 
        converter="javax.faces.Integer"/> 
     <h:inputText id="month" value="#{cc.month}" 
        converter="javax.faces.Integer"/> 
     <h:inputText id="year" value="#{cc.year}" 
        converter="javax.faces.Integer"/> 
    </h:panelGrid> 
</cc:implementation> 

InputDateBean.java

package uk.co.myco.jsfbeans.sqcc; 


import java.io.IOException; 
import java.util.Calendar; 
import java.util.Date; 
import javax.faces.component.FacesComponent; 
import java.util.GregorianCalendar; 
import javax.faces.application.FacesMessage; 
import javax.faces.component.NamingContainer; 
import javax.faces.component.UIInput; 
import javax.faces.context.FacesContext; 
import javax.faces.convert.ConverterException; 
import uk.co.myco.general.SQLog; 
import uk.co.myco.jsfbeans.helper.Messages; 

@FacesComponent(value = "uk.co.myco.jsfbeans.sqcc.InputDateBean") 
public class InputDateBean extends UIInput implements NamingContainer { 

    private int day = 0, month = 0, year = 0; 

    public InputDateBean() { 
    } 

    @Override 
    public String getFamily() { 
     return "javax.faces.NamingContainer"; 
    } 

    @Override 
    public void encodeBegin(FacesContext context) throws IOException { 
     Date date = (Date) getValue(); 
     Calendar cal = new GregorianCalendar(); 
     cal.setTime(date); 
     UIInput dayComponent = (UIInput) findComponent("day"); 
     UIInput monthComponent = (UIInput) findComponent("month"); 
     UIInput yearComponent = (UIInput) findComponent("year"); 
     dayComponent.setValue(cal.get(Calendar.DATE)); 
     monthComponent.setValue(cal.get(Calendar.MONTH) + 1); 
     yearComponent.setValue(cal.get(Calendar.YEAR)); 
     super.encodeBegin(context); 
    } 

    @Override 
    public Object getSubmittedValue() { 
     return this; 
    } 

    @Override 
    protected Object getConvertedValue(FacesContext context, Object newSubmittedValue) 
      throws ConverterException { 
     UIInput dayComponent = (UIInput) findComponent("day"); 
     UIInput monthComponent = (UIInput) findComponent("month"); 
     UIInput yearComponent = (UIInput) findComponent("year"); 
     int lday = (Integer) dayComponent.getValue(); 
     int lmonth = (Integer) monthComponent.getValue(); 
     int lyear = (Integer) yearComponent.getValue(); 
     if (isValidDate(lday, lmonth, lyear)) { 
      return new GregorianCalendar(lyear, lmonth - 1, lday).getTime(); 
     } else { 
      FacesMessage message = Messages.getMessage("util.messages", "invalidDate", null); 
      message.setSeverity(FacesMessage.SEVERITY_ERROR); 
      throw new ConverterException(message); 
     } 
    } 
    // getters & setters & isValidDate() removed 
} 

cevap

2

şimdi hatamı bakın. Sorun, kompozit bileşenin bir Date nesnesi, yani <cclib:inputDate value="#{bean.date}"/>. olarak adlandırılan olması gerektiği yönündeydi. kodu, tarihin somutlaştırılmasını gerektirdiğinden, ancak bu değildi. Bunu yapmanın daha güçlü olan yolu, getValue() öğesinin boş olması durumunda, encodeBegin() öğesinde yeni bir Tarih() yapmaktır. Bu daha sonra aynı h: inputText/f: convertDateTime çalışır ve bu da değerin başlatılmasını gerektirmez.