Boa tarde!
Sou iniciante em JSF, e estou esbarrando em um problema que deve ser muito simples de resolver para alguem que conheça de JSF.
Tenho dois HTMLSelectOneMenu aninhados, no caso classico Estados > Cidades. Quando é selecionado no primeiro HTMLSelectOneMenu um estado, são carregadas as cidades para esse estado no segundo HTMLSelecOneMenu. Até aki, tudo bem (depois de apanhar um pouco, criei os converters do Estado e da Cidade e subescrevi o equals da classe Estado e da classe Cidade e agora está tudo rolando certinho!)
Porem, o meu objeto Cidade possui dois campos int que devem ser editados: valorComp e diasComp.
Criei na página dois HTMLInputText, um para cada campo. Criei um objeto Cidade no meu ManagedBean, e apontei os campos para a propriedade value dos HTMLInputText criados.
O problema é que esses dois valores não aparecem no HTMLInputText nem com Reza Brava! oO
Depois de testar por horas, eu coloquei um breakpoint no setValorComp e eu notei que ele é acionando “sózinho pelo JSF” setando “0”. oO!! ou seja, o objeto é preenchido, e depois o JSF, sabe lá deus porque, joga zero no campo, entenderam?
Segue, abaixo os códigos para, quem puder dar uma olhada: (Os dados e os converters estão “hardcode”, para o exemplo ser testável.
As entidades Estado e Cidade:
package br.com.webdoc.modelo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Estado implements Serializable {
private static final long serialVersionUID = -8247490375284146948L;
private long id;
private String nome;
private List<Cidade> cidades;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public List<Cidade> getCidades() {
return this.cidades;
}
public Estado() {
this.cidades = new ArrayList<Cidade>();
}
public Estado(long id) {
this();
this.setId(id);
}
public Estado(long id, String nome) {
this(id);
this.setNome(nome);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Estado) {
Estado estado = (Estado) obj;
return (estado.getId() == this.getId());
}
return false;
}
public int hashCode() {
return 0;
}
}
package br.com.webdoc.modelo;
import java.io.Serializable;
public class Cidade implements Serializable {
static final long serialVersionUID = 6905091574203767022L;
private long id;
private String nome;
private int valorComp;
private int diasComp;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public int getValorComp() {
return valorComp;
}
public void setValorComp(int valorComp) {
this.valorComp = valorComp;
}
public Integer getDiasComp() {
return diasComp;
}
public void setDiasComp(Integer diasComp) {
this.diasComp = diasComp;
}
public Cidade() {
this.valorComp = 0;
this.diasComp = 0;
}
public Cidade(long id) {
this();
this.setId(id);
}
public Cidade(long id, String nome) {
this(id);
this.setNome(nome);
}
public Cidade(long id, String nome, int valorComp, int diasComp) {
this(id, nome);
this.setValorComp(valorComp);
this.setDiasComp(diasComp);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Cidade) {
Cidade cidade = (Cidade) obj;
return (cidade.getId() == this.getId());
}
return false;
}
public int hashCode() {
return 0;
}
}
os Converters:
package br.com.webdoc.converters;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import br.com.webdoc.modelo.Estado;
public class EstadoConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Estado estado = null;
if (value != null) {
estado = new Estado(new Long(value));
}
return estado;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
long id = 0;
if (value instanceof Estado) {
Estado estado = (Estado) value;
id = estado.getId();
}
return String.valueOf(id);
}
}
package br.com.webdoc.converters;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import br.com.webdoc.modelo.Cidade;
public class CidadeConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Cidade cidade = null;
if (value != null) {
cidade = new Cidade();
cidade.setId(new Long(value.split(",")[0]));
cidade.setNome(value.split(",")[1]);
cidade.setDiasComp(new Integer(value.split(",")[2]));
cidade.setValorComp(new Integer(value.split(",")[3]));
}
return cidade;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
String cidadeString = "";
if (value instanceof Cidade) {
Cidade cidade = (Cidade) value;
cidadeString = String.valueOf(cidade.getId()) + ",";
cidadeString += cidade.getNome() + ",";
cidadeString += cidade.getDiasComp() + ",";
cidadeString += cidade.getValorComp();
}
return cidadeString;
}
}
o managedbean
package br.com.webdoc.handlers;
import java.util.ArrayList;
import java.util.List;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import br.com.webdoc.modelo.Cidade;
import br.com.webdoc.modelo.Estado;
public class EstadosCidadesHandler {
// membros privados
private HtmlSelectOneMenu mnuEstados = new HtmlSelectOneMenu();
private HtmlSelectOneMenu mnuCidades = new HtmlSelectOneMenu();
private List<SelectItem> estados = null;
private List<SelectItem> cidades = null;
private Cidade cidade = null;
// getters/setters
public HtmlSelectOneMenu getMnuEstados() {
return mnuEstados;
}
public void setMnuEstados(HtmlSelectOneMenu mnuEstados) {
this.mnuEstados = mnuEstados;
}
public HtmlSelectOneMenu getMnuCidades() {
return this.mnuCidades;
}
public void setMnuCidades(HtmlSelectOneMenu mnuCidades) {
this.mnuCidades = mnuCidades;
}
public List<SelectItem> getEstados() {
if(this.estados == null) {
this.estados = new ArrayList<SelectItem>();
Estado estado = new Estado(0);
estado.setNome("Selecione um Estado");
this.estados.add(new SelectItem(estado, estado.getNome()));
estado = new Estado(1, "São Paulo");
estado.getCidades().add(new Cidade(1, "São Paulo", 11, 11));
estado.getCidades().add(new Cidade(2, "Campinas", 22, 22));
estado.getCidades().add(new Cidade(3, "São Carlos", 33, 33));
estado.getCidades().add(new Cidade(4, "Americana", 33, 33));
this.estados.add(new SelectItem(estado, estado.getNome()));
estado = new Estado(2, "Rio de Janeiro");
estado.getCidades().add(new Cidade(5, "Rio de Janeiro", 44, 44));
estado.getCidades().add(new Cidade(6, "Trindade", 55, 55));
estado.getCidades().add(new Cidade(7, "Campos dos Goytacazes", 66, 66));
estado.getCidades().add(new Cidade(8, "Barra Mansa", 77, 77));
this.estados.add(new SelectItem(estado, estado.getNome()));
estado = new Estado(3, "Minas Gerais");
estado.getCidades().add(new Cidade(9, "Belo Horizonte", 88, 88));
estado.getCidades().add(new Cidade(10, "Itajuba", 99, 99));
estado.getCidades().add(new Cidade(11, "Rio Claro", 10, 10));
this.estados.add(new SelectItem(estado, estado.getNome()));
estado = new Estado(4, "Bahia");
estado.getCidades().add(new Cidade(13, "Salvador", 11, 11));
estado.getCidades().add(new Cidade(14, "Abaira", 12, 12));
estado.getCidades().add(new Cidade(15, "Antas", 13, 13));
estado.getCidades().add(new Cidade(16, "Aracas", 14, 14));
this.estados.add(new SelectItem(estado, estado.getNome()));
estado = new Estado(5, "Ceará");
estado.getCidades().add(new Cidade(17, "Fortaleza", 15, 15));
estado.getCidades().add(new Cidade(18, "Abaiara", 16, 16));
this.estados.add(new SelectItem(estado, estado.getNome()));
}
return estados;
}
// metodos privados
public List<SelectItem> getCidades() {
if(this.cidades == null) {
this.cidades = new ArrayList<SelectItem>();
Cidade cidade = new Cidade();
cidade.setId(0);
cidade.setNome("Selecione uma Cidade");
this.cidades.add(new SelectItem(cidade, cidade.getNome()));
}
return cidades;
}
public Cidade getCidade() {
return cidade;
}
public void setCidade(Cidade cidade) {
this.cidade = cidade;
}
// metodos publicos
public void carregarCidades(ValueChangeEvent event) {
if(event.getComponent().equals(this.mnuEstados)) {
this.cidade = new Cidade();
this.cidades = new ArrayList<SelectItem>();
Cidade cidadeFake = new Cidade();
cidadeFake.setId(0);
cidadeFake.setNome("Selecione uma Cidade");
this.cidades.add(new SelectItem(cidadeFake, cidadeFake.getNome()));
Estado estadoSelecionado = this.carregarEstado(((Estado)event.getNewValue()).getId());
for (Cidade cidade : estadoSelecionado.getCidades()) {
this.cidades.add(new SelectItem(cidade, cidade.getNome()));
}
}
}
private Estado carregarEstado(long id) {
Estado estado = null;
for (SelectItem item : this.estados) {
if(((Estado)item.getValue()).getId() == id) {
estado = (Estado)item.getValue();
break;
}
}
return estado;
}
public void exibirDados(ValueChangeEvent e) {
if(e.getComponent().equals(this.mnuCidades)) {
this.cidade = new Cidade();
this.cidade = (Cidade)this.mnuCidades.getValue();
}
}
}
a JSP:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view>
<h:form id="pessoaForm">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h:messages />
<h:outputText value="Estados:" />
<h:selectOneMenu binding="#{estadosCidadesHandler.mnuEstados}"
valueChangeListener="#{estadosCidadesHandler.carregarCidades}"
onchange="submit();"
immediate="true">
<f:selectItems value="#{estadosCidadesHandler.estados}"/>
<f:converter converterId="estadoConverter" />
</h:selectOneMenu>
<br />
<h:outputText value="Cidades:" />
<h:selectOneMenu binding="#{estadosCidadesHandler.mnuCidades}"
valueChangeListener="#{estadosCidadesHandler.exibirDados}"
onchange="submit();"
immediate="true">
<f:selectItems value="#{estadosCidadesHandler.cidades}"/>
<f:converter converterId="cidadeConverter" />
</h:selectOneMenu>
<br /><br /><br />
<h:outputLabel value="Valor Comp:" />
<h:inputText value="#{estadosCidadesHandler.cidade.valorComp}" />
<br />
<h:outputLabel value="Dias Comp:" />
<h:inputText value="#{estadosCidadesHandler.cidade.diasComp}" />
</body>
</html>
</h:form>
</f:view>
e as partes relevantes do faces-config:
<managed-bean>
<managed-bean-name>estadosCidadesHandler</managed-bean-name>
<managed-bean-class>
br.com.webdoc.handlers.EstadosCidadesHandler
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<converter>
<converter-id>cidadeConverter</converter-id>
<converter-class>br.com.webdoc.converters.CidadeConverter</converter-class>
</converter>
<converter>
<converter-id>estadoConverter</converter-id>
<converter-class>br.com.webdoc.converters.EstadoConverter</converter-class>
</converter>
Alguem já passou por algum problema parecido ou tem alguma idéia do que possa estar acontecendo?
Muito obrigado turma!