JSF e os Objetos no <h:selectOneMenu <RESOLVIDO>

15 respostas
A

Boa Tarde,

o que acontece é que tenho um Select assim:

&lt;h:selectOneMenu value="#{projetoManaged.projeto.cliente.codCliente}"  valueChangeListener="# {projetoManaged.valueChangeListener}" immediate="true" &gt;
                        
                        &lt;f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.codCliente}" itemValue="#{cliente.codCliente}"/&gt;
                    &lt;/h:selectOneMenu&gt;

porém ele sempre tá retornando null isso: itemValue="#{cliente.codCliente}

não consigui fazer funcionar dessa forma com selectItems... sabendo que a lista não está vazia pois meu Bean coloca a lista correta como:

for (Cliente cliente : c) {
            clientes.add(new SelectItem(cliente, cliente.getNome()));

        }

quando faço assim:

&lt;f:selectItem itemLabel="a" itemValue="a"/&gt;
&lt;f:selectItem itemLabel="b" itemValue="b"/&gt;
&lt;f:selectItem itemLabel="c" itemValue="c"/&gt;

funciona perfeitamente!

alguém sabe onde possso estar errando? ou um esclarecimento mehor do JSF!

15 Respostas

D

Não sei se eu te entendi direito, tente return uma lista de objetos do tipo Cliente, da maneira que você está construindo
o seu SelectOne você não precisa converter os dados para SelectItem. Confirma ai se você está usando JSF 2 ou 1.2.

Se não funcionar posta um pouco mais de código, porque esse ai não esclareceu muito.

A

estou usando JSF 2.

esse é meu Bean Gerenciado:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.kmf.controller;

import br.kmf.bean.Cliente;
import br.kmf.bean.Projeto;
import br.kmf.dao.GenericDAOImpl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

/**
 *
 * @author Bruno
 */
public class ProjetoManaged implements Serializable {

    private Projeto projeto;

    public List&lt;SelectItem&gt; clientes = new ArrayList&lt;SelectItem&gt;();
    private Cliente cliente = new Cliente();
    private String cliente1;


    /** Creates a new instance of ProjetoManaged */
    public ProjetoManaged() {
        projeto = new Projeto();
        projeto.setCliente(cliente);
    }

    /**
     * @return the projeto
     */
    public Projeto getProjeto() {
        return projeto;
    }

    /**
     * @param projeto the projeto to set
     */
    public void setProjeto(Projeto projeto) {
        this.projeto = projeto;
    }

    public void cadastrar(ActionEvent event) {

        System.out.println("Aquiiii: "+ cliente.getCodCliente());
          System.out.println("Aquiiii: "+ cliente1);
        GenericDAOImpl&lt;Projeto, Integer&gt; dao = new GenericDAOImpl();
        this.projeto = dao.save(projeto);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Informacao:", "Projeto " + projeto.getDescricao() + ",  cadastrado com Sucesso!"));

    }

    public List&lt;SelectItem&gt; getClientes() {

        List&lt;Cliente&gt; c = new ArrayList&lt;Cliente&gt;();

        GenericDAOImpl&lt;Cliente, Integer&gt; dao = new GenericDAOImpl();
        c = dao.getAll(new Cliente());

        for (Cliente cliente : c) {
            clientes.add(new SelectItem(cliente, cliente.getNome()));

        }

        return clientes;
    }

    public void valueChangeListener(ValueChangeEvent event) {
        System.out.println(&quot;Cliente: &quot; + event.getNewValue());
 
        PhaseId phaseId = event.getPhaseId();
        //pega o novo valor
        Integer newValue = (Integer) event.getNewValue();
        if (phaseId.equals(PhaseId.ANY_PHASE)) {
            //agenda o evento para a fase que nos interessa
            event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
            event.queue();
        } else if (phaseId.equals(PhaseId.UPDATE_MODEL_VALUES)) {
            //aqui vai o método de antes (um pouco mudado)
            
            this.cliente.setCodCliente(newValue);
            cliente1 = String.valueOf(newValue);
        }
    }

    /**
     * @return the cliente
     */
    public Cliente getCliente() {
        return cliente;
    }

    /**
     * @param cliente the cliente to set
     */
    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    /**
     * @return the cliente1
     */
    public String getCliente1() {
        return cliente1;
    }

    /**
     * @param cliente1 the cliente1 to set
     */
    public void setCliente1(String cliente1) {
        this.cliente1 = cliente1;
    }

}

tem algumas coisas como esse cliente1 que tava colocando pra testar!

e minha pagina:

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

    &lt;ui:define name="content"&gt;

        &lt;h:form&gt;
            &lt;p:messages id="messages" showDetail="true"/&gt;

            &lt;p:panel header="Projetos"&gt;

                &lt;h:panelGrid columns="2" &gt;
                    &lt;h:outputText value="Descricao: "/&gt;
                    &lt;h:inputText value="#{projetoManaged.projeto.descricao}"/&gt;

                    &lt;h:outputText value="URL: "/&gt;
                    &lt;h:inputText value="#{projetoManaged.projeto.url}"/&gt;

                    &lt;h:outputText value="Cliente: "/&gt;

                    &lt;h:selectOneMenu value="#{projetoManaged.cliente.codCliente}"  valueChangeListener="#{projetoManaged.valueChangeListener}" immediate="true" &gt;
                        &lt;f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.nome}" itemValue="#{cliente.codCliente}"/&gt;
                    &lt;/h:selectOneMenu&gt;
                &lt;/h:panelGrid&gt;

                &lt;p:commandButton value="Cadastrar" actionListener="#{projetoManaged.cadastrar}" update="messages"/&gt;
            &lt;/p:panel&gt;

        &lt;/h:form&gt;

    &lt;/ui:define&gt;



&lt;/ui:composition&gt;

a questão é que essa linha <f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.nome}" itemValue="#{cliente.codCliente}"/> ele não pega o itemValue. e quando vai Validar o Bean não passa, o que não acontece se eu usar estaticamente o selectItem

D

Me parece que o seu problema é que o seu método getClientes() está retornando um List mas a sua viu
está tentando acessar os atributos dos items como se esses fossem do tipo Cliente.

Modifique o seu método getClientes() disso:

public List<SelectItem> getClientes() {  
  
        List<Cliente> c = new ArrayList<Cliente>();  
  
        GenericDAOImpl<Cliente, Integer> dao = new GenericDAOImpl();  
        c = dao.getAll(new Cliente());  
  
        for (Cliente cliente : c) {  
            clientes.add(new SelectItem(cliente, cliente.getNome()));  
  
        }  
  
        return clientes;  
    }

… para isso:

public List<Cliente> getClientes() {  
  
        return new GenericDAOImpl().getAll(new Cliente());
  
    }

… e me avise se funcionou.

A

funcionou sim. mas algumas questões agora me deixaram na dúvida.

primeiro: da forma que está eu não estou trabalhando com Objetos no selectOne certo??

existe como fazer isso, ou seja no lugar do vaor dele ser o codCliente inteiro ser o objeto Cliente??

outra coisa estranha é que achei que tinha que retornar o SelectItens assim como vi em muitos tutorias do JSF 2. isso mudou do JSF 1.2 e 2??

mas tá funcionando direitinho… so isso que fiquei em duvida agora!

D

PRIMEIRO:
Sim é possível fazer isso e inclusive é aconselhável que você o faça pois dessa forma o componente vai armazenar os objetos
Cliente ficando mais fácil para escrever um converter que entregue o objeto para o seu ManagedBean e não o código dele. Ai
segue as modificações que você precisa fazer no seu código, apenas o valor do atributo itemValue.

<h:selectOneMenu value="#{projetoManaged.projeto.cliente.codCliente}"  valueChangeListener="# {projetoManaged.valueChangeListener}" immediate="true" >  
    <f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.codCliente}" itemValue="#{cliente}"/>  
</h:selectOneMenu>

SEGUNDO:
Antes do JSF 2 a tag f:selectItems não possuía os atributos var, itemLabel e itemValue, essas informações eram obtidas através
dos atributos dos objetos SelectItem retornados. O problema, como você pode perceber, é que dessa forma você sempre precisava
converter os objetos das suas listas para SelectItem, o que é massante e trabalhoso. Com esses três atributos é possível que seus
ManagedBeans retornem a lista de dados sem nenhum tipo de processamento prévio, ou seja, assim como ela veio do banco.

A

blz, dev.rafael, como ficaria pra armazenar os Objetos??

pq quando tento fazer isso ele dá um erro de Null Converter.

D

Acho que não entendi, o que você quer dizer com “armazenar os Objetos”? Você quer armazena-los onde?
Com relação ao seu erro, poste o stackTrace da sua exceção.

J

aeciovc Isso é um sistema ? caralho fiquei bolado… muito legal jsf 2

Tu tem mais codigo para postar aqui ? gostaria de dar um Contro C + Control V, para fazer um CRUD.

abraço.

J
public void cadastrar(ActionEvent event) {  
  
        System.out.println("Aquiiii: "+ cliente.getCodCliente());  
          System.out.println("Aquiiii: "+ cliente1);  
        GenericDAOImpl&lt;Projeto, Integer&gt; dao = new GenericDAOImpl();  
        this.projeto = dao.save(projeto);  
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Informacao:", "Projeto " + projeto.getDescricao() + ",  cadastrado com Sucesso!"));  
  
    }

da ate pra ver que ta usando Facade !

D

Cara, vou ver se arranjo um tempo para escrever um artigo e posto ae. Beleza?

A

blz dev.rafael…

minha questão de armazenar os Objetos é no selectOneMenu mesmo… pq da forma que fiz no meu selectItems eu to usando o ItemValue como cliente.codCliente e não como o Objeto = cliente

entende??

J

otimo vou ficar aqui no agurado, e estudando sobre o spring

T

aeciovc:
blz dev.rafael…

minha questão de armazenar os Objetos é no selectOneMenu mesmo… pq da forma que fiz no meu selectItems eu to usando o ItemValue como cliente.codCliente e não como o Objeto = cliente

entende??

Caro aeciovc

veja:

  • primeiro crie os metodos hashCode e equals da sua classe cliente
  • Na seu managed bean a classe que retorna a lista pode ser assim:
public List&lt;Cliente&gt; getClientes() {     
  
    return new GenericDAOImpl().getAll(new Cliente());   
  
}
  • crie uma classe para converter
@FacesConverter(value="converteCliente", forClass=Cliente.class) 
public class ConverteCliente implements Converter {

	@Override
	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
		return GenericDAOImpl().getCliente(Integer.valueOf(arg2));
	}

	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		return String.valueOf(((Cliente) arg2).getCodigoCliente());
	}

}
  • e sua pagina
&lt;h:selectOneMenu value="#{projetoManaged.projeto.cliente}"   &gt;     
    &lt;f:selectItems value="#{projetoManaged.clientes}" var="cliente" itemLabel="#{cliente.descricao}" itemValue="#{cliente}"/&gt;     
    &lt;f:converter converterId="converteCliente"/&gt;
&lt;/h:selectOneMenu&gt;

e pronto.

não sei se fui claro

Flw

D

tonyam, tentei fazer desta forma como você postou mas não funcionou. Você teria um exemplo com o Dao para eu poder comparar.

obrigado.

C

Pra quem se interessar, tenho um exemplo sem converter aqui:
codepianist.com/2012/06/exemplo-jsf2-selectcombo-sem-coverter/

Um grande abraço e sucesso! 8)

Criado 13 de julho de 2010
Ultima resposta 9 de jun. de 2012
Respostas 15
Participantes 6