Problemas com <p:ajax [RESOLVIDO]

Tenho o seguinte combobox:

			<h:form id="formConCliente">
				<p:panel header="Testando">			
					<h:outputLabel for="pais" value="País:" />
					<p:selectOneMenu id="pais" value="#{paisController.pais}">
						<f:selectItem itemLabel="Selecione..." itemValue="" />
						<f:selectItems value="#{paisController.listaPaisesCombo}" />
						<p:ajax listener="#{paisController.actionCarregaUFs}" />
					</p:selectOneMenu>
				</p:panel>
			</h:form>

Código do bean:

package control;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import model.Pais;
import model.UnidadeFederacao;
import dao.PaisDao;
import dao.PaisDaoImp;
import dao.UnidadeFederacaoDao;
import dao.UnidadeFederacaoDaoImp;

@ManagedBean
@ViewScoped
public class PaisController implements Serializable {

	private Pais pais;
	private DataModel listaPaises;
	private List<Pais> filteredPaises;
	private Boolean isInsercao;
	private Boolean isAlteracao;
	private List<SelectItem> ufs = new ArrayList<SelectItem>();
	private List<SelectItem> listaPaisesCombo;			

	public List<Pais> getFilteredPaises() {
		return filteredPaises;
	}

	public void setFilteredPaises(List<Pais> filteredPaises) {
		this.filteredPaises = filteredPaises;
	}

	public DataModel getListarPaises() {
		List<Pais> lista = new PaisDaoImp().list();
		listaPaises = new ListDataModel(lista);
		return listaPaises;
	}
	
	public void setListaPaisesCombo(List<SelectItem> listaPaisesCombo) {
		this.listaPaisesCombo = listaPaisesCombo;
	}	

	public List<SelectItem> getListaPaisesCombo() {
		List<SelectItem> listaCombo = new ArrayList<SelectItem>();
		List<Pais> lista = new PaisDaoImp().list();
		
		PaisDao pd = new PaisDaoImp();
				
		for (int i = 1; i <= lista.size(); i++) {
			SelectItem item = new SelectItem();			
			item.setLabel(lista.get(i - 1).getNome());	
			//item.setValue(pd.findById(lista.get(i - 1).getCodigo()));
			item.setValue(lista.get(i - 1));
			
			listaCombo.add(item);
		}
		
		listaPaisesCombo = listaCombo;
		
		return listaPaisesCombo;
	}
	
	public List<SelectItem> getUFsByPais() {		
		List<SelectItem> listaCombo = new ArrayList<SelectItem>();						
		List<UnidadeFederacao> lista = new PaisDaoImp().getUFsByPais(this.pais.getCodigo());
		
		UnidadeFederacaoDao uf = new UnidadeFederacaoDaoImp();
		
		for (int i = 1; i <= lista.size(); i++) {
			SelectItem item = new SelectItem();			
			item.setLabel(lista.get(i - 1).getNome());						
			item.setValue(uf.findById(lista.get(i - 1).getCodigo()));
			listaCombo.add(item);			
		}
		
		return listaCombo;
	}
	
	public void actionCarregaUFs() {
		System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");

		//this.ufs = this.getUFsByPais();
	}	
	

	public Pais getPais() {
		return pais;
	}

	public void setPais(Pais pais) {
		this.pais = pais;
	}

	public String prepararAdicionarPais() {
		pais = new Pais();
		isInsercao = true;
		isAlteracao = false;
		return "gerenciarPais";
	}

	public String prepararAlterarPais() {
		pais = (Pais) (listaPaises.getRowData());
		isInsercao = false;
		isAlteracao = true;
		return "gerenciarPais";
	}

	public String excluirPais() {
		Pais paisTemp = (Pais) (listaPaises.getRowData());
		PaisDao dao = new PaisDaoImp();
		dao.remove(paisTemp);
		return "index";
	}

	public String adicionarPais() {
		PaisDao dao = new PaisDaoImp();
		dao.save(pais);
		return "index";
	}

	public String alterarPais() {
		PaisDao dao = new PaisDaoImp();
		dao.update(pais);
		return "index";
	}

	public Boolean getIsInsercao() {
		return isInsercao;
	}

	public void setIsInsercao(Boolean insercao) {
		this.isInsercao = insercao;
	}

	public Boolean getIsAlteracao() {
		return isAlteracao;
	}

	public void setIsAlteracao(Boolean alteracao) {
		this.isAlteracao = alteracao;
	}

	public List<SelectItem> getUfs() {
		return ufs;
	}

	public void setUfs(List<SelectItem> ufs) {
		this.ufs = ufs;
	}
	
}

Meu problema é bem estranho: por padrão no combobox vem o item “Selecione…”, e logo após vem “Brasil, “Argentina”, “Uruguai”, etc…
O método ‘paisController.actionCarregaUFs’ deveria ser executado cada vez que eu mudasse o item do combo, só que acontece o seguinte: ao carregar a página, vem listados os países no combo e por default vem o item ‘Selecione…’. Se eu clicar no combo e mudar para ‘Brasil’, o método não executa, porém se eu voltar para o item 'Selecione…” o método é executado. Ele deveria ser executado quando eu mudei para ‘Brasil’! O método só executa quando eu volto para ‘Selecione…’, mudando para qualquer outro item do combo o método não executa!
O que tem de errado? O que eu devo fazer? Por favor, ficarei muito grato se alguém puder me ajudar.

não ta faltando o evento ai não!?

<p:ajax event=“change” listener""/>

testa ai creio que seja isso!

abraço

Não… o event=“change” é por padrão caso ele for omitido.

esta errado, o padrão é null

veja a pagina 19 do primefaces user guide

Ok, desculpe a informação errada. Colocando o ‘event=“change”’ ou não colocando, dá na mesma (no meu caso). Encontrei aqui no fórum uma pessoa que estava com a mesma situação que a minha, mas pra ele o problema foi resolvido colocando o o escopo do bean como @ViewScoped. O meu bean já está com @ViewScoped e mesmo assim não funciona. O evento só é acionado quando é selecionado o item ‘Selecione…’.
Preciso muito resolver esse problema. :cry:

tenta coloca o itemLabel e itemValue e faz um teste

Mas o que eu colocaria no “itemLabel” e 'itemValue" já que estou usando uma lista de SelecItem? O SelecItem já tem “dentro” dele o “itemLabel” e “itemValue”.
P.S.: tentei colocar o “itemLabel” e “itemValue” com vazio e não funcionou.

não esta aparecendo nada no seu log?

Acredito que não tenha nada a ver com o meu problema, mas quando eu reinicio o server, dá a seguinte exceção:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: control.PaisController

Caused by: java.io.NotSerializableException: control.PaisControlle

Quando estou testando o combobox, mudando de itens, não dá mensagem nenhuma no console do servidor.

seus managedBeans implementam Serializable?

Não. Basta eu colocar “implements Serializable” ou preciso criar algum método?

Só colocar implements Serializable e declarar um atributo

private static final long serialVersionUID

Amigo, não é o teu <f:selectItems> que está errado? Pra mim que faltaram atributos.
Eu usaria assim:

&lt;f:selectItems value="#{paisController.paises}" var="pais" itemLabel="#{pais.nome}" itemValue="#{pais}"/&gt;

Mas como nunca usei com o objeto SelectItem, posso ta falando besteira.
Abraço.

O SelectItem já possui o itemLabel e itemValue.
Repare o código que estou usando:

	public List<SelectItem> getListarPaisesCombo() {
		List<SelectItem> listaCombo = new ArrayList<SelectItem>();
		List<Pais> lista = new PaisDaoImp().list();
		
		PaisDao pd = new PaisDaoImp();
				
		for (int i = 1; i <= lista.size(); i++) {
			SelectItem item = new SelectItem();			
			item.setLabel(lista.get(i - 1).getNome());						
                        item.setValue(lista.get(i - 1));
			listaCombo.add(item);
		}
				
		return listaCombo;
	}

Você esta setando o objeto Pais direto no sectItem, mas não especificou nenhum Converter. Acredito que tenha que criar um Converter para suas classes.
Não está aparecendo nenhum erro no console?

Não utilizo Converter. O código abaixo supostamente substituiria o conversor, pois estou passando um SelectItem:

	public List<SelectItem> getListarPaisesCombo() {
		List<SelectItem> listaCombo = new ArrayList<SelectItem>();
		List<Pais> lista = new PaisDaoImp().list();
		
		PaisDao pd = new PaisDaoImp();
				
		for (int i = 1; i <= lista.size(); i++) {
			SelectItem item = new SelectItem();			
			item.setLabel(lista.get(i - 1).getNome());						
                        item.setValue(lista.get(i - 1));
			listaCombo.add(item);
		}
				
		return listaCombo;
	}

E não aparece nenhuma mensagem de erro. O SelectOneMenu espera um objeto do tipo Pais, e é isso que os itens estão devolvendo.

Alguém com mais alguma sugestão? Estou a ponto de largar de mão e partir pra outra linguagem… :frowning:

Desconheço o fato de não precisar de Converter quando se utiliza uma lista de SelectItem, tem certeza disso?

Qual o servidor de aplicação que vc está utilizando? Pode ser um problema da configuração do log no servidor não está sendo exibida mensagem de erro.

Retorna um List de Pais e usa essa abordagem

<p:selectOneMenu value="#{autoCompleteBean.selectedPlayer1}" converter="player">  
      <f:selectItem itemLabel="Select One" itemValue="" />  
      <f:selectItems value="#{autoCompleteBean.players}" var="player" itemLabel="#{player.name}" itemValue="#{player}"/>  
</p:selectOneMenu>

Você evita um for dentro do código pra popular os SelectItems.

Meu, olha só, tentei simular o problema aqui e o que descobri é que não funciona se vc setar o objeto Pais no controlador, vc precisa setar uma String e através dela encontrar o Pais correspondente.
Provavelmente é o que o outro colega falou, ta faltando um converter.

Segue o código q usei pra fazer funcionar:

&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"&gt;

  &lt;h:body&gt;
    &lt;h:head&gt;
      &lt;style type="text/css"&gt;
        #select {
          position: relative;
          top: 8px;
        }
        #paisOutput {
          border: 1px solid black;
          width: 200px;
        }
      &lt;/style&gt;
    &lt;/h:head&gt;
    &lt;h:form prependId="false" id="form1"&gt;

      &lt;p:panel header="Selecione um país"&gt;
        &lt;p:outputLabel id="label" for="select" value="País:"/&gt;
        &lt;p:selectOneMenu value="#{paisController.selected}" id="select"&gt;
          &lt;f:selectItem itemLabel="Selecione..." itemValue="#{null}"/&gt;
          &lt;f:selectItems value="#{paisController.paises}" var="pais"
                         itemLabel="#{pais.name} - #{pais.acronym}"
                         itemValue="#{pais.acronym}"/&gt;
          &lt;p:ajax event="change" update="paisOutput"/&gt;
        &lt;/p:selectOneMenu&gt;
        
        <br/><br/>
        
        &lt;h:outputText id="paisOutput" value="#{paisController.pais}"/&gt;
      &lt;/p:panel&gt;
    
    &lt;/h:form&gt;
  &lt;/h:body&gt;
&lt;/html&gt;
package com.jpower.pstat;

import java.util.LinkedList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ViewScoped
@ManagedBean
public class PaisController {

  private List&lt;Pais&gt; paises;
  private String selected;
  private Pais pais;
  
  public PaisController() {
    paises = new LinkedList&lt;&gt;();
    selected = &quot;null&quot;;
    pais = null;
    paises.add(new Pais(&quot;Brasil&quot;, &quot;BR&quot;));
    paises.add(new Pais(&quot;Uruguay&quot;, &quot;UY&quot;));
    paises.add(new Pais(&quot;Ucrania&quot;, &quot;UA&quot;));
  }

  public List&lt;Pais&gt; getPaises() {
    return paises;
  }

  public void setPaises(List&lt;Pais&gt; paises) {
    this.paises = paises;
  }

  public String getSelected() {
    return selected;
  }

  public void setSelected(String selected) {
    System.out.println("* setSelected: "+ selected);
    for(Pais p : paises) {
      if(p.getAcronym().equals(selected)) {
        pais = p;
        break;
      }
    }
    System.out.println("* pais: "+ pais);
  }

  public Pais getPais() {
    return pais;
  }
}
package com.jpower.pstat;

public class Pais {
  
  private String name;
  private String acronym;
  
  public Pais() {
    name = null;
    acronym = null;
  }
  
  public Pais(String name, String acronym) {
    this.name = name;
    this.acronym = acronym;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getAcronym() {
    return acronym;
  }

  public void setAcronym(String acronym) {
    this.acronym = acronym;
  }

  @Override
  public String toString() {
    return "Pais{" + "name=" + name + ", acronym=" + acronym + '}';
  }
}