Mostrando postagens com marcador PrimeFaces. Mostrar todas as postagens
Mostrando postagens com marcador PrimeFaces. Mostrar todas as postagens

sexta-feira, 1 de abril de 2016

Trabalhando com enum no JSF/Primefaces

      O JSF / Primefaces consegue trabalhar com enum de forma simples, sem precisarmos implementar conversores, basta passarmos para o componente uma lista com os valores da classe enum para o componente JSF / Primefaces. Segue o código do ManagedBean:

public class CadastroModeloCarroBean {
     
... //outros atributos da classe
      private List<Categoria> categorias;
           
      @PostConstruct
      public void init(){
            ... //outras inicializações necessárias
            categorias = Arrays.asList(Categoria.values());
      }
     
      ... //outros métodos da classe  
     
      public List<Categoria> getCategorias(){
            return categorias;
      }
     

}
         O atributo categorias trata-se de uma lista de itens da própria enum Categoria. Note que para pegar todos os atributos e devolve-los em forma de lista foi usado o seguinte código:

categorias = Arrays.asList(Categoria.values());

         Dessa forma eu posso usar a lista criada a partir do enum como qualquer outra lista. Veja no arquivo XHTML como fica:

<p:outputLabel value="Categoria" for="categoria"/>
<p:selectOneMenu id="categoria" value="#{cadastroModeloCarroBean.modeloCarro.categoria}">
     
<f:selectItem itemLabel="Selecione uma categoria"/>
     
<f:selectItems value="#{cadastroModeloCarroBean.categorias}" var="categoria" itemLabel="#{categoria}" itemValue="#{categoria}"/>

</p:selectOneMenu>

E olha o código da classe Categoria que é um enum:

public enum Categoria {
      
       SEDAN("Sedan"), HATCH("Hatch"), SUV("SUV");
      
       private String descricao;
      
       public String getDescricao(){
             return this.descricao;
       }
      
       private Categoria(String descricao){
             this.descricao = descricao;
       }

}

terça-feira, 29 de março de 2016

Paginação de dados com Hibernate e Primefaces

     Esse post sobre paginação com hibernate, considero que você já tenha seu DAO, ManagedBean, o Bean e a página XHTML feita, e quer apenas mudar a forma como os dados são trazidos do banco, melhorando dessa forma o desempenho do sistema.

Para fazermos paginação com o Hibernate, precisamos preparar a camada View (Páginas XHTML) para lidar com essa paginação. No caso do primefaces, isso é bem simples. Vamos analisar como fica o componente <p:dataTable> de forma a trabalhar com a paginação:

<p:dataTable id="carroTable" paginator="true" rows="20" lazy="true" paginatorAlwaysVisible="false" paginatorPosition="bottom" var="carro" value="#{pesquisaCarroBean.lazyCarros}" rowsPerPageTemplate="10,20,50"
emptyMessage="Nenhum carro encontrado." style="margin-top: 20px" >

      ...

<p:dataTable>

         A propriedade paginator=”true” indica que haverá um paginação, e mesmo que não fizéssemos a parte de paginação na camada  Model, o primefaces conseguiria paginar os dados trazidos para esse dataTable, porém, mesmo a exibição estando paginada, todos os dados estariam carregados em memória. Daí a importância de fazermos realmente a paginação dos dados, mudando a forma como esses dados são trazidos do banco de dados, que é o que vamos ver mais a frente nesse post.

         A propriedade paginatorAlwaysVisible=”false” serve para que o paginador aparece apenas quando houver dados suficientes para serem paginados. O paginatorPosition=”bottom” informa a posição que a paginação será exibida. A propriedade rows=”20” indica quantas linhas serão exibidas por default, já a propriedade rowsPerPageTemplate=”10,20,50” é responsável por permitir a customização da quantidade de linhas visualizadas.

         Porém, a propriedade lazy=”true” é quem realmente faz o componente do primefaces entender que haverá uma paginação real dos dados. Com isso, podemos passar para a camada Model.

       Precisamos criar uma classe responsável por fazer o meio de campo entre o componente do primefaces que será paginado e o método responsável por buscar a consulta paginada usando o hibernate. Vamos começar criando a classe LazyCarro, que criei dentro de um novo pacote chamado lazy_model dentro da minha hierarquia de pacotes. Segue o código:

public class LazyCarro extends LazyDataModel<Carro> implements Serializable{

      private static final long serialVersionUID = 1L;
     
      private CarroDAO carroDAO;
     
      public LazyCarro(CarroDAO carroDAO) {
            this.carroDAO = carroDAO;
      }
     
      @Override
      public List<Carro> load(int first, int pageSize,
                  String sortField, SortOrder sortOrder, Map<String, Object> filters) {
           
           
            List<Carro> carros = carroDAO.buscarTodosPaginado(first, pageSize);
           
            this.setRowCount(carroDAO.pegarQuantidadeDeCarros().intValue());
           
            return carros;
      }
     
}

        Essa classe estende a classe LazyDataModel do primefaces, e tem uma implementação bem simples. Preste bastante atenção quanto ao método load que deve ser sobrescrito, que deve ser o segundo e não o primeiro. Note que os dois métodos que chamamos do carroDAO (buscarTodosPaginado(first, pageSize) e pegarQuantidadeDeCarros()) precisam ser criados, então vamos adicioná-los a classe CarroDAO.

public List<Carro> buscarTodosPaginado(int primeiroDigito, int segundoDigito){
      return em.createQuery("FROM Carro", Carro.class)
                  .setFirstResult(primeiroDigito)
                  .setMaxResults(segundoDigito)
                  .getResultList();
}

public Long pegarQuantidadeDeCarros(){
      return em.createQuery("SELECT count(c) FROM Carro c", Long.class)
.getSingleResult();
}

Agora que já temos tudo feito na camada model, vamos a camada Controller que é responsável por fazer a ligação entre a View e a Model. Na classe PesquisaCarroBean vamos adicionar o objeto do tipo LazyCarro que será inicializado no método init que possui a anotação @PostConstruct e também o seu método getter para que a página XHTML possa ter acesso.

@ManagedBean
@ViewScoped
public class PesquisaCarroBean implements Serializable{
private LazyCarro lazyCarros;
      ...
public LazyCarro getLazyCarros() {
      return lazyCarros;
}
      ...
@PostConstruct
public void init(){
      lazyCarros = new LazyCarros(new CarroDAO);
...
}
      ...
}

         Pronto, com isso já temos uma consulta paginada. Caso apareça um erro informando e o “Lazy loading não foi implementado”, sugiro que verifique o método load que você sobrescreveu na classe LazyCarro, checando os parâmetros com estes:

load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters){...}


Qualquer dúvida, pode deixar nos comentários que tentarei ajudar no que for possível...

quinta-feira, 24 de março de 2016

Calendar do Primefaces em Português

       O primefaces é uma biblioteca fantástica, porém não sei por que eles não já deixaram padrão a parte de tradução dos componentes pelo menos para as principais linguagens distribuindo os aqruivos junto com o .jar. Já que não vem por padrão, cabe a nós fazermos essa configuração que é bastante simples.

         Primeiro vamos criar um arquivo chamado locale-primefaces.js Java com o seguinte código:

PrimeFaces.locales['pt'] = {
    closeText: 'Fechar',
    prevText: 'Anterior',
    nextText: 'Próximo',
    currentText: 'Começo',
    monthNames:['Janeiro','Fevereiro','Março','Abril','Maio','Junho''Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
    monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', 'Jul','Ago','Set','Out','Nov','Dez'],
    dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'],
    dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
    dayNamesMin: ['D','S','T','Q','Q','S','S'],
    weekHeader: 'Semana',
    firstDay: 0,
    isRTL: false,
    showMonthAfterYear: false,
    yearSuffix: '',
    timeOnlyTitle: 'Só Horas',
    timeText: 'Tempo',
    hourText: 'Hora',
    minuteText: 'Minuto',
    secondText: 'Segundo',
    ampm: false,
    month: 'Mês',
    week: 'Semana',
    day: 'Dia',
    allDayText : 'Todo o Dia'
};


         Guarde esse arquivo na pasta js dentro de resources em webapp:


Adicione as suas páginas ou no seu template a chamada ao arquivo:

<h:outputScript library="js" name="locale-primefaces.js"/>

Agora, basta nos componentes <p:calendar> usar a propriedade locale e informar o valor “pt” como mostrado abaixo:

<p:calendar id="dataDevolucao" value="#{novoAluguelBean.aluguel.dataDevolucao}" pattern="dd/MM/yyyy HH:mm" mask="true" locale="pt" />



Links úteis:

Formatação de campos de valor Monetário

        Trabalhar com valores monetários em páginas WEB é meio chato, porém vou mostrar duas maneiras de facilitar esse trabalho, uma é do próprio primefaces, e outra é com JQuery, que funciona em qualquer aplicação web, bastando configurar corretamente.

         Primeiro vamos a solução com primefaces, que é uma biblioteca de extensão que deve ser adicionada ao projeto. Vamos então configurar no arquivo pom.xml o seguinte:

<dependencies>
    ...   
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>primefaces-extensions</artifactId>
        <version>4.0.0</version>
    </dependency>
    ...
</dependencies>

         Depois, temos que adicionar na página xhtml o namespace da extensão do primefaces no topo da página:

xmlns:pe="http://primefaces.org/ui/extensions"

         E então podemos usar a biblioteca de extensão para formatarmos os componentes que guardarão valores monetários.

<pe:inputNumber id="valor" value="#{meuManagedBean.valor}" symbol=" R$" 
symbolPosition="s" decimalSeparator="," thousandSeparator="." decimalPlaces="2/>

Caso dê algum erro de conversão, você pode adicionar o seguinte componente:

<pe:inputNumber id="valor" value="#{meuManagedBean.valor}" symbol=" R$"
symbolPosition="s" decimalSeparator="," thousandSeparator="." decimalPlaces="2>

<f:convertNumber maxFractionDigits="2" minFractionDigits="2"/>

</pe:inputNumber>

Agora vamos fazer a biblioteca JQuery-MaskMoney. Basta fazer o download da biblioteca no link http://plentz.github.io/jquery-maskmoney, lá tem o arquivo zip para baixar. Então crie o diretório “js” dentro da pasta resources em webapp como mostra a imagem a seguir:



Se você trabalha com templates do facelets basta adicionar isso no cabeçalho do template, se não, terá que adicionar nas paginas que irá precisar. Dentro do header coloque:

<h:outputScript library="js" name="jquery.maskMoney.js"/>

      Dentro do body, no final crie a função:

<script>

function configurarMoeda(objeto){
$(objeto).maskMoney({decimal: ",", thousands: ".", allowZero: true, symbolStay: "R$"});
       }
      
</script>
        
         Então basta chamar no componente que deseja usar da seguinte forma:
 
<p:inputText id="valorUnitario" value="#{meuManagedBean.valorUnitario }" 
onfocus="configurarMoeda(this);">
        <f:convertNumber maxFractionDigits="2" minFractionDigits="2"/>
<p:inputText>


     Se você não trabalha com primefaces, no link do download do JQuery-MaskMoney você vai encontrar ajuda para usar a biblioteca. Abraços!
            
ATENÇÃO! <pe:inputnumber> foi removido das extensões do PF e agora faz parte do pacote principal, então nas versões mais recentes, simplesmente substitua <pe:inputNumber> por <p:inputNumber>.

Links úteis: