Seam Converter de Entity

20 11 2008

O Problema

Exibir apenas uma coluna de uma determinada entidade, por exemplo exibir o nome de uma pessoa.

A Solução

package br.unioeste.sgppls;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.persistence.EntityManager;

import org.jboss.seam.annotations.Name;

@Name("ConverterEntityarConhecimento")
@org.jboss.seam.annotations.faces.Converter
public class ConverterEntityarConhecimento implements Converter {

	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
		try {
			EntityManager entityManager = (EntityManager) org.jboss.seam.Component
				.getInstance("entityManager", true);
			Object o = entityManager.createQuery(
				"from ArConhecimento ar WHERE ar.arCnhCodigo = :codigo")
				.setParameter("codigo", arg2).getSingleResult();
			return o;
		} catch (Exception e) {
			throw new ConverterException(e);
		}
	}

	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		try {
			ArConhecimento a = (ArConhecimento) arg2;
			return a.getArCnhCodigo();
		} catch (Exception e) {
			throw new ConverterException(e);
		}
	}
}

A Visão

Meu campo input esta ligado diretamente com o atributo que é uma outra entidade, sendo assim é necessário usar o conversor para exibir a coluna de ‘descrição’

<h:inputText value="#{projetoHome.instance.arConhecimento}" id="text" size="15" converter="ConverterEntityarConhecimento" required="true"/>




Seam Converter Boolean Sim/Não

20 11 2008

O Problema

Converter atributos do tipo Boolean em String SIM caso true e NÃO caso false.

A Solução

package br.unioeste.sgppls;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

@Name("ConverterBooleanString")
@BypassInterceptors
@org.jboss.seam.annotations.faces.Converter

public class ConverterBooleanString implements Converter {

   public Object getAsObject(FacesContext arg0, UICompon   ent arg1, String arg2) {
      try {
         if (arg2.equalsIgnoreCase("sim")) {
            return new Boolean(true);
         } else
            return new Boolean(false);
      } catch (Exception e) {
            throw new ConverterException (e);
      }
   }

   public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
      try {
         if (((Boolean)arg2) == true) {
            return "Sim";
         } else
            return "Não";
      } catch (Exception e) {
         throw new ConverterException (e);
      }
   }
}

Na Visão

projetoHome.instance.prjPago é do tipo Boolean e na visão deve aparecer a String humanizada, então:

<h:outputText value="#{projetoHome.instance.prjPago}" converter="#{ConverterBooleanString}"/>




Seam Popup Conversation

14 11 2008

O Problema

Em minha aplicação necessitava vincular a cidade do endereço de uma pessoa, não podia usar um elemento html select pois o número de cidades era muito grande então resolvi fazer um popup que listava todas as cidades e com um filtro para que o usuário pude-se escolher a cidade.

A Solução

Na Visão

Para abrir a minha popup este código foi usado

<h:graphicImage value="/img/magnifier.gif" style="margin-left:5px; cursor:pointer"
onclick="window.open('CidadeList.seam?pessoaCodigo=#{pessoaHome.pessoaCodigo}&amp;cid=#{conversation.id}',
'Buscar Área do Conhecimento', 'height = 500, width = 400, scrollbars = 1')"/>

Pontos Importantes

  1. Não é possível utilizar o & para concatenar mais parâmetros a URL, é necessário ‘escapar’ o & através o &amp;
  2. cid=#{conversation.id}: foi usado para manter a conversação entre a janela atual e a popup, sem isso você acaba iniciando um novo workspace, e com isso o que você manipula na popup não é refletido na janela parent;

Na tela onde estavam sendo listadas as cidades foi criado um h:commandLink que ao ser clicado chamava o método que vinculava a pessoa a cidade e setava os dados relativos na janela parent.

O XHTML que foi aberto pelo popup se parece com isso aqui:

<h:form id="arConhecimentoSearch" styleClass="edit">
   <rich:simpleTogglePanel label="Parâmetros de Busca" switchType="ajax">
      <s:decorate template="layout/display.xhtml">
      <ui:define name="label">Descrição</ui:define>
      <h:inputText id="arCnhDescricao" value="#{cidadeList.cidade.nome}"/>
      </s:decorate>
   </rich:simpleTogglePanel>

   <div class="actionButtons">
      <h:commandButton id="search" value="Pesquisar" action="/cidadeList.xhtml"/>
   </div>
   </h:form>

   <rich:panel>
      <f:facet name="header">Cidades Localizadas</f:facet>
      <div class="results" id="cidadeList">
         <h:outputText value="Nenhuma cidade localizada."
            rendered="#{empty cidadeList.resultList}"/>
         <rich:dataTable id="cidadeList"
                        var="cidade"
                        value="#{cidade.resultList}"
                        rendered="#{not empty cidade.resultList}">
            <h:column>
               <f:facet name="header">Código</f:facet>
                  #{cidade.codigo}
            </h:column>
            <h:column>
                  <f:facet name="header">Nome</f:facet>
                  #{cidade.nome}
            </h:column>
            <h:column>
               <f:facet name="header">Ações</f:facet>
               <h:form>
               <h:commandLink value="Select" action="#{cidadeHome.cidadeLocalizada(cidade)}"
onclick="window.opener.document.getElementById('cidade_codigo').value = '#{cidade.codigo}';
window.opener.document.getElementById('cidade_descricao').innerHTML = '#{cidade.descricao';
window.close()"/>
                  </h:form>
            </h:column>
         </rich:dataTable>

Pontos Importantes

  1. Não use s:link pois ele não permite que se passe parâmetros para o método, perdi um tempão pra descobrir isso :(.
  2. action=”#{cidadeHome.cidadeLocalizada(cidade)}: chama o método que irá ligar a cidade a pessoa;
  3. Para dar uma ‘enfeitada’ quando o cidadão clica na cidade então a janela será fechada e os dados serão exibidos na janela parent, isso é feito usando o código em javascript window.opener.document.getElementById(‘cidade_descricao’).innerHTML = ‘#{cidade.descricao’};

No Modelo

Para pedir ao SEAM que ligue a entidade cidade com a entidade pessoa então será usado o método

public void cidadeLocalizada(Cidade cidade)
{
   pessoaHome.getInstance().setCidade(cidade);
}

Finalizando

Aqui não está o código completo mas da pra ter uma idéia de como a ciosa funciona. Espero de alguma forma ter contribuído com alguém.





Checkbox Seam Character Hybernate YesNoType

6 11 2008

O Problema

Meu banco de dados não possiu suporte ao tipo de dado boolean, sendo assim, tenho que contornar o problema usando um CHAR(1). Quando fiz a engenharia reversa para o Hibernate ele definiu meu atributo como Character e nessa jogada eu queria usar um checkbox na minha visão para setar o valor do atributo como true/false. Meu código original era assim:

private Character prjPago;

@Column(name = "Prj_pago")
public Character getPrjPago() {
   return this.prjPago;
}

A Solução

A solução foi alterar o tipo de dado do seu atributo para boolean e no mapeamento do Hibernate definir o tipo de dado como sendo YesNoType veja como ficou:

private Boolean prjPago;

@Column(name = "Prj_pago")
@Type(type = "org.hibernate.type.YesNoType")
public Boolean getPrjPago() {
   return this.prjPago;
}

E na minha camada de apresentação ficou algo parecido com isso aqui:

<h:selectBooleanCheckbox id="prjPago" value="#{projetoHome.instance.prjPago}" />

Referências

http://www.seamframework.org/16450.lace

http://forum.hibernate.org/viewtopic.php?p=2212819&sid=db8f69cc8753ebe4b8f40c2633367e85





Criando Select no SEAM

31 10 2008

Objetivo

Apresentar uma das formas de se criar um elemento HTML do tipo SELECT utilizando o Seam Framework. Continue lendo »





Seam / Hibernate / JSF = Deus nos Acuda

29 10 2008

Introdução

Estou começando a trabalhar com o SEAM e por isso resolvi postar aqui algumas coisas que estou nesses últimos 10 dias. Grande parte do conhecimento aqui descrito foi obtive com a valorosa ajuda do meu amigo Kadu e a curva de aprendizado como em praticamente tudo que envolva java e sua sopa de letrinhas é longa.

Alguns Links

  1. 3 Vídeo Aulas, a primeira mostra como rodar o jboss a segunda como iniciar um projeto no seam e a terceira como rodar o exemplos do seam;
  2. JBoss Tool: Plugin para o eclipse que facilita o trabalho com o JBoss;
  3. JSF: Introdução ao JSF.

Continue lendo »