9
respostas

Erro ao não instanciar uma classe Calendar

Boa noite, estou com um problema aqui, tenho uma classe Cliente e dentro dela tenho um atributo do tipo Calendar.

@Temporal(TemporalType.DATE)
    private Calendar dataNascimento = Calendar.getInstance();

Mais eu não quero pegar a data atual, quero que venha vazio no meu html, fazendo desse jeito vem com a data atual, e quando eu tiro o getInstance, deixando assim.

@Temporal(TemporalType.DATE)
    private Calendar dataNascimento;

Ele me retorna um erro no meu html, falando que minha dataNascimento está vindo nulla, oque devo trocar para não receber essa exception? Meu html está desse jeito.

<p:outputLabel value="Data Nascimento: " for="dataNascimento" />
                                    <p:inputMask mask="99/99/9999" id="dataNascimento"
                                        value="#{clienteBean.cliente.dataNascimento.time}"
                                        required="true"
                                        requiredMessage="O campo Data Nascimento é obrigatório"
                                        size="10">
                                        <f:convertDateTime pattern="dd/MM/yyyy" />
                                        <p:ajax listener="#{clienteBean.totalDeIdade}"
                                            update="formularioCliente:idade" />
                                    </p:inputMask>

Lembrando não quero recuperar a data atual, que que venha em branco no html para que o dono do sistema possa digitar a data de nascimento, e claro quero usar o calendar!

9 respostas

Fala, Alisson!

Isso tá acontecendo porque você não está usando um conversor. Implementa um e o erro deve ser resolvido.

Abraço!

Opa mano quanto tempo velho kkkkk, então é só implementar um conversor de data e ja era?

Manoel fiz um converter aqui e o erro continua ainda :(

@FacesConverter(value = "dataConverter")
@SuppressWarnings("serial")
public class DataConverter implements Serializable, Converter{

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        DateTimeFormatter formato = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        return LocalDate.parse(value, formato);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        LocalDate dataValor = (LocalDate) value;
        return dataValor.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
    }

}
    <p:inputMask mask="99/99/9999" id="dataNascimento"
                                        value="#{clienteBean.cliente.dataNascimento.time}"
                                        required="true"
                                        requiredMessage="O campo Data Nascimento é obrigatório"
                                        size="10" converter="dataConverter">

Pois é, mano... Andei ausente mesmo... mais férias... hehe.

Então...

Implementei aqui e funcionou...

Teu converter deve ser chamado assim:

<f:converter converterId="dataConverter" />

Acrescentei o blur no atributo event da tag ajax porque, por padrão, as requisições são feitas no change. Daí, no formulário, ficou assim:

<h:form id="formularioCliente">
    <p:outputLabel value="Data Nascimento: " for="dataNascimento" />
    <p:inputMask mask="99/99/9999" id="dataNascimento" value="#{clienteBean.cliente.dataNascimento}">
        <f:converter converterId="dataConverter" />
        <p:ajax event="blur" listener="#{clienteBean.totalDeIdade()}" update="formularioCliente:idade" />
    </p:inputMask>
    <h:outputText id="idade" value="#{clienteBean.idade}" />
</h:form>

Segue o converter que fiz:

package br.com.mssl.modelo.entidade;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;

@FacesConverter(value = "dataConverter")
public class DataConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String valor) throws ConverterException {
        Calendar calendar = Calendar.getInstance();
        if (valor == null || valor.equals("")) {
            return "";
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            try {
                Date data = sdf.parse(valor);
                calendar.setTime(data);
            } catch (Exception e) {
                System.out.println("Erro: " + e.getMessage());
            }
            return calendar;
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object objeto) throws ConverterException {
        String data = null;
        if (objeto == null) {
            return null;
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            Calendar calendar = (Calendar) objeto;
            data = sdf.format(calendar.getTime());
            return data;    
        }
    }
}

Na classe Cliente.java apenas declarei o atributo, não instanciei, pra ficar como você precisa que seja feito.

@Temporal(TemporalType.DATE)
private Calendar dataNascimento;

O cálculo da data só será feito quando você tirar o foco do input (blur), ou seja, só digitar a data e clicar fora do input, em qualquer área em branco da tela.

Faz os teste aí pra gente ver se funciona.

Abraço.

Perfeito mano! funcionou, você manja de mais, estava fazendo o coverter errado e chamando no lugar errado também :(, aonde que você aprende tanta coisa? kkk, eu procurei na documentação do calendar como usar, mais não achei nada como usar no jsf, aonde que tem essas coisas para mim ficar sabendo e procurar também? E sobre o event é sempre change por padrão né? Qual a diferença do change pro blur? Muito obg mano!

Ow manoel, eu consegui dois temas aqui com meu parceiro, o barcelona e o ultima, você deve fazer bastante projeto seila, quer que eu lance eles para você? É muito bom, claro se quiser...

É isso aí! Os detalhes ferram mesmo... kkkk

Alisson, o lance é buscar entender como funciona a tecnologia, o ciclo de vida (no caso do JSF) é essencial. O resto é mão na massa mesmo, programando, batendo cabeça, pesquisando nos fóruns as respostas para alguns problemas complexos, etc. Vejo sempre o stackoverflow, sempre tem respostas bacanas por lá, principalmente do BlausC, que saca muito de JSF.

O padrão do event, se nada for especificado, é o do componente ao qual ele está aninhado. No caso do botão, por exemplo, é o click. No input é o change.

O blur é o evento de tirar o foco do objeto. Por isso a renderização da idade é feita somente após clicar fora do input, isso evita que o conversor seja chamado a cada número que você for inserir. Se não tiver o blur, o método totalDeIdade() será chamado 8 vezes (uma para cada dígito da data).

Valeu!

Mano, dificilmente uso primefaces, acho ele muito pesado e pouco customizável... hehe.

Mas posta aí no dropbox, ftp, ou drive qualquer e manda o link... quem sabe dá pra pegar umas sacadas de layout, css e javascript.

Valeu!

Blz Manoel irei postar lá e te mando o link, sim sim da pra pegar uma boa sacada. Você usa oque então mano? kkkk então muita coisa aprendi aqui na alura, alias tudo que eu sei foi daqui com tópicos e tudo mais, cada dia apreendo uma coisinha nova, como por exemplo esse evento, já tinha usado muito ele, mais não sabia a nacessidade, mais muito obrigado denovo.