Criando um Converter padrão para PickList do Primefaces

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (2)  (0)

Veja neste artigo como criar um conversor para o PickList do Primefaces em Java. Ele nos ajudará a transferir valores da lista do lado esquerdo para o lado direito, e vice-versa.

Neste artigo iremos criar um converter padrão para trabalhar com o PickList do Primefaces. Antes de mais nada é importante saber o que é o PickList e como podemos usufruir deste recurso. Na figura 1 você consegue ver um Picklist básico.

PickList Básico

Figura 1: PickList Básico

Quando estamos trabalhando com valores simples como inteiros, double, strings e outros, o trabalho fica fácil pois não precisamos de um “Converter” para realizar a conversão de objeto para String e vice-versa, mas na maioria dos casos isso não acontece, pois precisamos usar um PickList ligado diretamente a “beans” prontos, por exemplo: Na lista do lado esquerdo podemos ter uma lista de funcionários que não estão de férias e do lado direito podemos ter os funcionários que estão de férias (um exemplo simples e prático).

A picklist nos ajudará a transferir de forma fácil e rápido valores da lista do lado esquerdo para a lista do lado direito e vice-versa, com várias funcionalidades como: adicionar todos, remover todos e etc.

Definindo nosso PickList no ManagedBean

Vamos primeiro definir como será nosso PickList em nosso ManagedBean.

Listagem 1: Definindo o PickList no ManagedBean

private DualListModel<Funcionario> dualListModelFuncionarios;
private List<Funcionario> funcionariosFerias;
private List<Funcionario> funcionariosTrabalhando;
...

dualListModelFuncionarios = new DualListModel<Funcionario>(
				funcionariosTrabalhando,
				funcionariosFerias);
.. .

public DualListModel<Funcionario> getDualListModelFuncionarios() {
		return dualListModelFuncionarios;
	} 

Bom, na primeira parte definimos 3 listas importantes: A DualListModel que terá a lista de funcionários que estão trabalhando (vamos dizer que seja a lista do lado esquerdo) e os funcionários que estão de férias (vamos dizer que seja a lista do lado direito), além disso temos as listas que serão gerenciadas pelo DualListModel.

Na segunda parte iremos inicializar o DualListModel, em nosso caso estamos inicializando ela colocando os funcionários de férias do lado direito e os funcionários trabalhando do lado esquerdo.

Obviamente que estes são apenas trechos de códigos maiores, você precisa definir onde colocar cada trecho, e ainda definir os “getters e setters” para trabalhar com o xhtml e o managedBean.

Vamos agora definir um pickList usando o primefaces.

Listagem 2: Definindo o picklist do xhtml

<p:pickList id="myPickList"
	value="#{meuManagedBeanMB.dualListModelfuncionarios}"
	var="funcionario" required="true"
	converter="primeFacesPickListConverter"
	requiredMessage="Pelo menos 1 funcionário deve ser selecionado"
	itemValue="#{funcionario}" itemLabel="#{funcionario}"
	showSourceControls="true" showTargetControls="true">

	<p:ajax event="transfer"
		listener="#{meuManagedBeanMB.onTransfer}" />

	<f:facet name="sourceCaption">Disponíveis</f:facet>
	<f:facet name="targetCaption">Selecionados</f:facet>

	<p:column style="width:75%;">
		<h:outputText value="#{funcionario.nome}" />
	</p:column>
</p:pickList>

Acima temos diversas opções, temos ainda um evento “transfer” que é disparado sempre que um registro é transferido de uma lista para a outra, assim sendo, sempre que essa transferência ocorre disparamos um evento “onTransfer” no nosso ManagedBean que fará alguma ação. Podemos, por exemplo, verifica se o usuário que está sendo transferindo tem permissão para entrar de férias antes de concluir a transferência.

Você deve ter percebido que usamos um converter chamado “primeFacesPickListConverter” e é exatamente nele que iremos focar a partir daqui, pois este nosso Converter deve servir para qualquer Bean que você precise aplicar mais a frente. Imagine se você tivesse que criar um novo Converter para cada novo PickList que for usar ? Provavelmente você optaria por utilizar esse poderoso recurso menos vezes, e não é isso que queremos.

Enfim, na listagem 3 você verá um exemplo de um PickList Converter padrão.

Listagem 3: PrimefacesPickListConverter

import java.util.Iterator; 
import java.util.List; 
import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.convert.Converter; 
import javax.faces.convert.FacesConverter; 

import org.primefaces.component.picklist.PickList; 
import org.primefaces.model.DualListModel; 

@FacesConverter(value = "primeFacesPickListConverter") 
public class PrimeFacesPickListConverter implements Converter { 

	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { 
		Object ret = null; 
		if (arg1 instanceof PickList) { 
			Object dualList = ((PickList) arg1).getValue(); 
			DualListModel dl = (DualListModel) dualList; 
			for (Iterator iterator = dl.getSource().iterator(); iterator 
					.hasNext();) { 
				Object o = iterator.next(); 
				String id = (new StringBuilder()).append( 
						((AbstractBean) o).getId()).toString(); 
				if (arg2.equals(id)) { 
					ret = o; 
					break; 
				} 
			} 

			if (ret == null) { 
				for (Iterator iterator1 = dl.getTarget().iterator(); iterator1 
						.hasNext();) { 
					Object o = iterator1.next(); 
					String id = (new StringBuilder()).append( 
							((AbstractBean) o).getId()).toString(); 
					if (arg2.equals(id)) { 
						ret = o; 
						break; 
					} 
				} 

			} 
		} 
		return ret; 
	} 

	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) { 
		String str = ""; 
		if (arg2 instanceof AbstractBean) 
			str = ((AbstractBean) arg2).getId().toString(); 
		return str; 
	} 
} 

Vale ressaltar que para usar um PickListConverter padrão você precisará de um Bean padrão, assim sendo é importante criar um Bean padrão, que chamamos aqui de AbstractBean, veja a listagem 4 como fazemos.

Listagem 4: Criando um AbstractBean ou Bean Padrão para usar no PickList Converter

package br.com.odontonew.bean; 

import java.io.Serializable; 

import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.MappedSuperclass; 

@MappedSuperclass 
public abstract class AbstractBean implements Serializable { 

	@Id 
	@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY) 
	private Integer id; 

	public Integer getId() { 
		return id; 
	} 

	public void setId(Integer id) { 
		this.id = id; 
	} 

	@Override 
	public int hashCode() { 
		final int prime = 31; 
		int result = 1; 
		result = prime * result + ((id == null) ? 0 : id.hashCode()); 
		return result; 
	} 

	@Override 
	public boolean equals(Object obj) { 
		if (this == obj) 
			return true; 
		if (obj == null) 
			return false; 
		if (getClass() != obj.getClass()) 
			return false; 

		return (obj instanceof AbstractBean) ? (this.getId() == null ? this == obj 
				: this.getId().equals(((AbstractBean) obj).getId())) 
				: false; 
	} 

} 

O ideal é que qualquer outro bean que você criar estenda do AbstractBean, sendo assim você poderá trabalhar com o AbstractBean e não com um Bean específico como: Funcionario, Categoria e etc.

Veja outro exemplo de como criar um PickList no seu ManagedBean, este foi retirado do próprio ShowCase do Primefaces e ilustra a associação de um Bean chamado “Player” ao seu PickList de forma estática.

Listagem 5: Outra forma de criar um PickList no ManagedBeean

//Players  
List<Player> source = new ArrayList<Player>();  
List<Player> target = new ArrayList<Player>();  
  
source.add(new Player("Messi", 10, "messi.jpg"));  
source.add(new Player("Iniesta", 8, "iniesta.jpg"));  
source.add(new Player("Villa", 7, "villa.jpg"));  
source.add(new Player("Alves", 2, "alves.jpg"));  
source.add(new Player("Xavi", 6, "xavi.jpg"));  
source.add(new Player("Puyol", 5, "puyol.jpg"));      
  
players = new DualListModel<Player>(source, target);  
  
//Cities  
List<String> citiesSource = new ArrayList<String>();  
List<String> citiesTarget = new ArrayList<String>();  
  
citiesSource.add("Istanbul");  
citiesSource.add("Ankara");  
citiesSource.add("Izmir");  
citiesSource.add("Antalya");  
citiesSource.add("Bursa");  
  
cities = new DualListModel<String>(citiesSource, citiesTarget);  

Então veja bem o que foi feito: criamos duas lista uma source e outra target, na source definimos vários Players e na target deixamos vazia, então criamos nosso DualListModel com essas duas listas, o PickList apresentado será 2 tabelas sendo o lado esquerdo preenchido e o lado direito vazio. A mesma coisa é feita com a lista de Cidades.

Este componente é muito útil em muitas situações como as citadas aqui neste artigo. Vale ressaltar que o PickList Converter é apenas uma sugestão para aqueles que não desejam criar inúmeras classes para beans diferentes na sua aplicação, mas é óbvio que você precisará padronizar sua aplicação para usar tal recurso, como é o caso do uso do AbstractBean.

Este artigo teve como principal objetivo demonstrar como criar um PickList Converter padrão para ser usado em todo tipo de Bean, mostramos também como criar um PickList mas este não foi o foco, por isso não foi feito o detalhamento do mesmo.

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?