Problema Combos aninhados no Primefaces

Fala galera, estou com um problema que não consigo resolver, estou fazendo um projeto com primefaces, um cadastro simples, e tenho um combo com estados e outro com cidades, onde quero selecionar o estado no primeiro combo, e o segundo deve mostrar apenas as cidades referentes ao estado selecionado. Estou me baseando na demo no site do primefaces, mas não tá dando certo, se alguem poder ajudar…

Os combos:

<h:outputText value="Estado:" />
                            <p:selectOneMenu id="estado" value="#{ClienteBean.cliente.codEstado}" height="120" style="width: 150px"  required="true" requiredMessage="Selecione o Estado">
                                <f:selectItem itemLabel="Selecione" itemValue=""/>
                                <f:selectItems value="#{CidadeUFComboBean.UFs}"/>
                                <p:ajax update="cidade" listener="#{CidadeUFComboBean.changeUF}"/>
                            </p:selectOneMenu>

                            <h:outputText value="Cidade:" />
                            <p:selectOneMenu id="cidade" value="#{ClienteBean.cliente.codCidade}" height="120" style="width: 150px"  required="true" requiredMessage="Selecione a Cidade">
                                <f:selectItem itemLabel="Selecione" itemValue=""/>
                                <f:selectItems value="#{CidadeUFComboBean.cidades}"/>
                            </p:selectOneMenu>

Meu managedBean:

public class CidadeUFComboBean implements Serializable {

    CidadeDAO cidDao = new CidadeDAO();
    EstadoDAO ufDao = new EstadoDAO();

    /*
     * Construtor
     */
    public CidadeUFComboBean() {

            populateUFs();
            populateCidades();
          
    }

    /*
     * Propriedades
     */
    private String uf;

    public String getUF() {
        return uf;
    }

    public void setUF(String uf) {
        this.uf = uf;
    }
    private String cidade;

    public String getCidade() {
        return cidade;
    }

    public void setCidade(String cidade) {
        this.cidade = cidade;
    }
    private SortedMap<Integer, String> ufs =
            new TreeMap<Integer, String>();

    public SortedMap<Integer, String> getUFs() {
        return ufs;
    }

    public void setUFs(SortedMap<Integer, String> ufs) {
        this.ufs = ufs;
    }
    private SortedMap<Integer, SortedMap<Integer, String>> cidadesData =
            new TreeMap<Integer, SortedMap<Integer, String>>();

    public SortedMap<Integer, SortedMap<Integer, String>> getCidadesData() {
        return cidadesData;
    }

    public void setCidadesData(SortedMap<Integer, SortedMap<Integer, String>> cidadesData) {
        this.cidadesData = cidadesData;
    }
    private SortedMap<Integer, String> cidades = new TreeMap<Integer, String>();

    public SortedMap<Integer, String> getCidades() {
        return cidades;
    }

    public void setCidades(SortedMap<Integer, String> cidades) {
        this.cidades = cidades;
    }

    /*
     * Helpers
     */
    private void populateUFs(){
        try {

            System.out.println("Populando Ufs...");
            List<Estado> estados = ufDao.getEstado();
            for (Estado estado : estados) {
                ufs.put(estado.getCodEstado(), estado.getUf());
            }
            System.out.println("Populando Ufs com " + ufs.size() + " itens...");
            
        } catch (SQLException ex) {
            Logger.getLogger(CidadeUFComboBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void populateCidades() {
        for (int codEstado : ufs.keySet()) {
            try {

                cidadesData.put(codEstado, cidDao.getCidade(codEstado));

            } catch (SQLException ex) {
                Logger.getLogger(CidadeUFComboBean.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /*
     * Action handlers
     */
    public void changeUF() {
        if (uf != null && !uf.equals("")) {
            cidades = cidadesData.get(uf);
        } else {
            cidades = new TreeMap<Integer, String>();
        }
    }
}

No combo so mostra o codigo do estado, e nem altera o combo de cidades…

no p:ajax, acredito que tenha que colocar event=“change” para chamar o ajax.

Fiz o teste e não dá certo, os selects estao como no site do primefaces, acredito que problema seja no ManagedBean

outra coisa que esqueci de avisar (não vi que estava sem), adiciona process="@this" no p:ajax.

E no lugar de cidadesData.put(codEstado, cidDao.getCidade(codEstado));
Acho que deveria ser cidades.put(codEstado, cidDao.getCidade(codEstado));

evefuji obrigado pela ajuda, mas tmb não deu certo :frowning:

Acho que está tudo errado, pelo que eu andei pesquisando, o único jeito de fazer isso pelo primefaces é populando os combos através de Maps, e não através de List,e é uma complicação usar Map, além disso todos os exemplos que vi a cidade é buscada através do nome do estado e não através do código, como faço, mas to tentando solucionar o problema…

Acho que agora consegui, mas cai em outro problema, na hora de exibir o combo nao ta mostrando os nomes dos estados, mas sim o nome do objeto…

tipo br.com.sacx.model.estado@200

ManagedBean agora:

package br.com.sacx.controls;

import br.com.sacx.daos.CidadeDAO;
import br.com.sacx.daos.ClienteDAO;
import br.com.sacx.daos.EstadoDAO;
import br.com.sacx.models.Cidade;
import br.com.sacx.models.Cliente;
import br.com.sacx.models.Estado;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import org.primefaces.component.selectonemenu.SelectOneMenu;

@ManagedBean
@SessionScoped

public class ClienteBean implements Serializable {

    private Cliente cliente = new Cliente();
    private ClienteDAO dao = new ClienteDAO();
    private EstadoDAO estadoDao = new EstadoDAO();
    private CidadeDAO cidadeDao = new CidadeDAO();

    private Estado estado;
    private Cidade cidade;
    private Map<Estado, Estado> estados = new HashMap<Estado, Estado>();
    private Map<Estado, Map<Cidade, Cidade>> cidadesData = new HashMap<Estado, Map<Cidade, Cidade>>();
    private Map<Cidade, Cidade> cidades = new HashMap<Cidade, Cidade>();


    public ClienteBean() throws SQLException {

         for (Estado listaUF : estadoDao.getEstado()) {
            estados.put(listaUF, listaUF);
            System.out.println("----------------- ESTADO LIDO: " + listaUF.getNome());

            Map<Cidade, Cidade> cidadesTemp = new HashMap<Cidade, Cidade>();
            for (Cidade listaCIDADE : cidadeDao.getCidade(listaUF.getCodEstado())) {
                System.out.println("----------------- CIDADE LIDA: " + listaCIDADE.getNome());
                cidadesTemp.put(listaCIDADE, listaCIDADE);
                cidades.put(listaCIDADE, listaCIDADE);
            }
             cidadesData.put(listaUF, cidadesTemp);
        }
    }

    public void atualizaCidades() {

        cidades = cidadesData.get(estado);


    }

Página xhtml:

[code]
<h:outputText value=“Estado:” />
<p:selectOneMenu id=“estado” value="#{ClienteBean.cliente.codEstado}" converter=“EstadoConverter” height=“120” style=“width: 150px” required=“true” requiredMessage=“Selecione o Estado”>
<f:selectItem itemLabel=“Selecione” itemValue=""/>
<f:selectItems value="#{ClienteBean.estados}"/>
<p:ajax update=“cidade” listener="#{ClienteBean.atualizaCidades}"/>
</p:selectOneMenu>

                        <h:outputText value="Cidade:" />
                        <p:selectOneMenu id="cidade" value="#{ClienteBean.cliente.codCidade}" converter="CidadeConverter" height="120" style="width: 150px"  required="true" requiredMessage="Selecione a Cidade">
                            <f:selectItem itemLabel="Selecione" itemValue=""/>
                            <f:selectItems value="#{ClienteBean.cidades}"/>
                        </p:selectOneMenu>[/code]