O PrimeFaces é um dos principais frameworks para a construção de interfaces ricas do JavaServer Faces (JSF) e disponibiliza uma grande quantidade de componentes, como campos de formulário, tabelas, galerias de imagens e vídeos e gráficos. Um dos principais componentes é o DataTable, que serve para a construção de tabelas para a exibição de um conjunto de dados.

Esse componente disponibiliza uma grande quantidade de funcionalidades, como ordenação dos elementos por coluna, busca dos dados nas colunas, agrupamento dos dados e funcionalidades como o Drag and Drop. Esse artigo mostrará como criar diversos DataTable, mostrando como implementar boa parte das funcionalidades que esse componente disponibiliza.

Configuração do Projeto

O primeiro passo para a construção de uma aplicação do PrimeFaces é a configuração das dependências do projeto e para isso será utilizado o Maven. A Listagem 1 mostra o código para a configuração das dependências do projeto. Nesse projeto são duas dependências: o PrimeFaces na versão 5.1, e o JavaServer Faces na versão 2.2.0.. Para a dependência do PrimeFaces é necessário configurar o repositório do framework também.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.devmedia</groupId>
   <artifactId>prime</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>war</packaging>

   <dependencies>
         <dependency>
                <groupId>org.primefaces</groupId>
                <artifactId>primefaces</artifactId>
                <version>5.1</version>
                <scope>compile</scope>
         </dependency>
         <dependency>
                <groupId>org.glassfish</groupId>
                <artifactId>javax.faces</artifactId>
                <version>2.2.0</version>
                <scope>compile</scope>
         </dependency>
   </dependencies>
   <repositories>
         <repository>
                <id>prime-repo</id>
                <name>PrimeFaces Maven Repository</name>
                <url>http://repository.primefaces.org</url>
                <layout>default</layout>
         </repository>
   </repositories>
</project>
Listagem 1. Configuração das dependências do projeto

O segundo passo na criação do projeto é configurar o arquivo web.xml para adicionar o JavaServer Faces na aplicação. Para isso, basta incluir o servlet do JSF e também configurar o mapeamento da página, no caso desse exemplo, todos os endereços com final *.xhtml. Na Listagem 2 é mostrado o código do arquivo web.xml.


<?xml version="1.0" encoding="UTF-8"?>
  <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <display-name>com.devmedia.primefaces</display-name>
      <servlet>
          <servlet-name>Faces Servlet</servlet-name>
          <servlet-class>javax.faces.webapp.FacesServlet<
          /servlet-class>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>Faces Servlet</servlet-name>
          <url-pattern>*.xhtml</url-pattern>
      </servlet-mapping>
      <welcome-file-list>
          <welcome-file>/index.xhtml</welcome-file>
      </welcome-file-list>
      <error-page>
          <exception-type>javax.faces.application
          .ViewExpiredException</exception-type>
          <location>/index.xhtml</location>
      </error-page>
  </web-app>
Listagem 2. Arquivo web.xml

Depois das configurações será criada uma classe simples e para representar os objetos que serão adicionados e manipulados nos DataTables. Todos os exemplos utilizarão essa mesma classe Cliente, que tem os atributos nome, idade, endereço, descrição e dataCadastro. Na Listagem 3 é mostrado o código da classe Cliente.


package com.devmedia.model;
   
import java.util.Date;
 
public class Cliente {
       
       private String nome;
       private String endereco;
       private String telefone;
       private int idade;
       private String descricao;
       private Date dataCadastro;
       
    public Cliente() {
             
       }
 
       public Cliente(String nome, String endereco, 
       String telefone, int idade,
             String descricao, Date dataCadastro) {
             super();
             this.nome = nome;
             this.endereco = endereco;
             this.telefone = telefone;
             this.idade = idade;
             this.descricao = descricao;
             this.dataCadastro = dataCadastro;
       }
 
       public String getNome() {
             return nome;
       }
       
       public void setNome(String nome) {
             this.nome = nome;
       }
       
       public String getEndereco() {
             return endereco;
       }
       
       public void setEndereco(String endereco) {
             this.endereco = endereco;
       }
       
       public String getTelefone() {
             return telefone;
       }
       
       public void setTelefone(String telefone) {
             this.telefone = telefone;
       }
       
       public int getIdade() {
             return idade;
       }
       
       public void setIdade(int idade) {
             this.idade = idade;
       }
       
       public String getDescricao() {
             return descricao;
       }
       
       public void setDescricao(String descricao) {
             this.descricao = descricao;
       }
       
       public Date getDataCadastro() {
             return dataCadastro;
       }
       
       public void setDataCadastro(Date dataCadastro) {
             this.dataCadastro = dataCadastro;
       }
 
}
Listagem 3. Código da classe Cliente

Além da classe Cliente também será necessária a criação de um ManagedBean, que é uma classe do JSF. Essa classe será responsável por criar algumas pessoas e as colocar em uma lista que, por sua vez, será exibida nos dataTable. Para criar diversos dados diferentes foi utilizado um método que cria alguns objetos do tipo Cliente, de forma randômica. Na Listagem 4 é mostrado o código dessa classe.


package com.devmedia.mb;
   
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
   
  import javax.faces.bean.ManagedBean;
  import javax.faces.bean.ViewScoped;
   
  import com.devmedia.model.Cliente;
   
  @ManagedBean(name="clienteMB")
  @ViewScoped
  public class ClienteMB {
         
         private List<Cliente> clientes = 
         new ArrayList<Cliente>();
         
         public ClienteMB() {
               for (int i = 0; i < 20; i++) {
                      clientes.add(generateRandomCliente());
               }
         }
         
         public String [] nomes = {"Eduardo", "Luiz", 
         "Henrique", "Felipe", "Bruna", "Brianda", "Sonia"};
               
         public List<Cliente> getClientes() {
               return clientes;           
         }
         
         public Cliente generateRandomCliente() {
               
               int indice = (int) Math.floor(Math.random()*7);
               Cliente cliente = new Cliente();
               cliente.setNome(nomes[indice]);
               cliente.setEndereco("Rua " + indice);
               cliente.setIdade((indice + 1) * 3);
               cliente.setDescricao("Teste");
               cliente.setTelefone(indice * 20 + "123");
               cliente.setDataCadastro(new Date());
               
               return cliente;
                             
         }
   
  }
Listagem 4. ManagedBean que cria objetos Cliente

Utilizando o DataTable

O primeiro exemplo implementado é um DataTable simples que terá uma coluna para cada atributo da classe Cliente. A tag cria um DataTable e o atributo value indica o método do ManagedBean que recuperará os valores para serem exibidos na tabela. O atributo var indica o nome da variável que será utilizada dentro da tabela. Na Listagem 5 é exibido o código para a criação dessa tabela.


<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:f="http://java.sun.com/jsf/core"
     xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>

<h:body>

   <p:dataTable var="cliente" value="#{clienteMB.clientes}">
     <p:column headerText="Nome">
            <h:outputText value="#{cliente.nome}" />
     </p:column>

     <p:column headerText="Endereço">
            <h:outputText value="#{cliente.endereco}" />
     </p:column>

     <p:column headerText="Idade">
            <h:outputText value="#{cliente.idade}" />
     </p:column>

     <p:column headerText="Descrição">
            <h:outputText value="#{cliente.descricao}" />
     </p:column>

     <p:column headerText="Telefone">
            <h:outputText value="#{cliente.telefone}" />
     </p:column>
                   
     <p:column headerText="Data Cadastro">
            <h:outputText value="#{cliente.dataCadastro}" >
                   <f:convertDateTime pattern="dd/MM/yyyy" />
            </h:outputText>
     </p:column>
                       
   </p:dataTable>



</h:body>
</html>
Listagem 5. DataTable simples

Para cada coluna da tabela deve ser utilizada a tag. Além disso, o atributo headerText indica o título da coluna que irá aparecer no cabeçalho da tabela. Como a classe Pessoa tem seis atributos, foram criadas seis colunas, todas com um para exibir o valor de cada atributo.

O atributo dataCadastro é uma data, por isso é necessário a tag para mostrar a data no padrão correto. Na Figura 1 é mostrada a tabela criada.

DataTable simples
Figura 1. DataTable simples

Duas das funcionalidades mais interessantes do DataTable são a criação de filtros e a ordenação das colunas. Isso é bastante simples de fazer com o prime faces, bastando apenas adicionar a tag e os atributos filterBy e orderBy, indicando qual a coluna que deve ser utilizada. Na Listagem 6 é mostrado como utilizar essas funcionalidades. Quando essas tags forem utilizadas, o dataTable deve estar dentro de um form, definido com a tag.


<html xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>

<h:body>
   <h:form>

     <p:dataTable var="cliente" value="#{clienteMB.clientes}">
        <p:column headerText="Nome" sortBy="#{cliente.nome}"
           filterBy="#{cliente.nome}">
           <h:outputText value="#{cliente.nome}" />
        </p:column>

        <p:column headerText="Endereço" sortBy="#{cliente.endereco}"
           filterBy="#{cliente.endereco}">
           <h:outputText value="#{cliente.endereco}" />
        </p:column>

        <p:column headerText="Idade" sortBy="#{cliente.idade}"
           filterBy="#{cliente.idade}">
           <h:outputText value="#{cliente.idade}" />
        </p:column>

        <p:column headerText="Descrição" sortBy="#{cliente.descricao}"
           filterBy="#{cliente.descricao}">
           <h:outputText value="#{cliente.descricao}" />
        </p:column>

        <p:column headerText="Telefone" sortBy="#{cliente.telefone}"
           filterBy="#{cliente.telefone}">
           <h:outputText value="#{cliente.telefone}" />
        </p:column>

        <p:column headerText="Data Cadastro" sortBy="#{cliente.dataCadastro}"
           filterBy="#{cliente.dataCadastro}">
           <h:outputText value="#{cliente.dataCadastro}">
              <f:convertDateTime pattern="dd/MM/yyyy" />
           </h:outputText>
        </p:column>

     </p:dataTable>
   </h:form>


</h:body>
</html>
Listagem 6. DataTable com filtro e ordenação

A Figura 2 mostra a página com o dataTable com as funcionalidades de ordenação e filtro em cada uma das colunas.

DataTable com filtro e ordenação das colunas.
Figura 2. DataTable com filtro e ordenação das colunas

Outra funcionalidade muito útil é a paginação para que um DataTable tenha um tamanho fixo. Para criar a paginação, basta adicionar os atributos rows, que indicam quantas linhas devem ser exibidas por página, e o atributo paginator, que deve ter o valor true para a tag. Na Listagem 7 é mostrado como criar um DataTable com paginação.


<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:f="http://java.sun.com/jsf/core"
     xmlns:p="http://primefaces.org/ui">
   
  <h:head>
   
  </h:head>
   
  <h:body>
     <h:form>

       <p:dataTable var="cliente" value="#{clienteMB.clientes}" 
       rows="10"
          paginator="true"
          >
          <p:column headerText="Nome" sortBy="#{cliente.nome}"
             filterBy="#{cliente.nome}">
             <h:outputText value="#{cliente.nome}" />
          </p:column>

          <p:column headerText="Endereço" 
          sortBy="#{cliente.endereco}"
             filterBy="#{cliente.endereco}">
             <h:outputText value="#{cliente.endereco}" />
          </p:column>

          <p:column headerText="Idade" 
          sortBy="#{cliente.idade}"
             filterBy="#{cliente.idade}">
             <h:outputText value="#{cliente.idade}" />
          </p:column>

          <p:column headerText="Descrição" 
          sortBy="#{cliente.descricao}"
             filterBy="#{cliente.descricao}">
             <h:outputText value="#{cliente.descricao}" />
          </p:column>

          <p:column headerText="Telefone" 
          sortBy="#{cliente.telefone}"
             filterBy="#{cliente.telefone}">
             <h:outputText value="#{cliente.telefone}" />
          </p:column>

          <p:column headerText="Data Cadastro" 
          sortBy="#{cliente.dataCadastro}"
             filterBy="#{cliente.dataCadastro}">
             <h:outputText value="#{cliente.dataCadastro}">
                    <f:convertDateTime pattern="dd/MM/yyyy" />
             </h:outputText>
          </p:column>

       </p:dataTable>
     </h:form>
   
   
  </h:body>
  </html>
Listagem 7. DataTable com paginação

Na Figura 3 é mostrado o DataTable criado na listagem anterior. Esse exemplo tem as funcionalidades de ordenação, filtragem e paginação.

DataTable com paginação
Figura 3. DataTable com paginação

Na Listagem 8 é mostrada a funcionalidade de alterar a ordem das colunas e das linhas em um DataTable através de Drag e Drop. Para isso, basta adicionar os atributos draggableColumns e draggableRows com os valores true para ambos.


<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>

<h:body>
 <h:form>

   <p:dataTable var="cliente" value="#{clienteMB.clientes}" rows="10"
          paginator="true" draggableColumns="true" draggableRows="true"
      >
      <p:column headerText="Nome" sortBy="#{cliente.nome}"
         filterBy="#{cliente.nome}">
         <h:outputText value="#{cliente.nome}" />
      </p:column>

      <p:column headerText="Endereço" sortBy="#{cliente.endereco}"
         filterBy="#{cliente.endereco}">
         <h:outputText value="#{cliente.endereco}" />
      </p:column>

      <p:column headerText="Idade" sortBy="#{cliente.idade}"
         filterBy="#{cliente.idade}">
         <h:outputText value="#{cliente.idade}" />
      </p:column>

      <p:column headerText="Descrição" sortBy="#{cliente.descricao}"
         filterBy="#{cliente.descricao}">
         <h:outputText value="#{cliente.descricao}" />
      </p:column>

      <p:column headerText="Telefone" sortBy="#{cliente.telefone}"
         filterBy="#{cliente.telefone}">
         <h:outputText value="#{cliente.telefone}" />
      </p:column>

      <p:column headerText="Data Cadastro" sortBy="#{cliente.dataCadastro}"
         filterBy="#{cliente.dataCadastro}">
         <h:outputText value="#{cliente.dataCadastro}">
            <f:convertDateTime pattern="dd/MM/yyyy" />
         </h:outputText>
      </p:column>

   </p:dataTable>
 </h:form>


</h:body>
</html>
Listagem 8. Alteração da ordem de colunas e linhas

No PrimeFaces é possível incluir cabeçalhos e rodapés nas tabelas. Isso é interessante para incluir um título no cabeçalho, e no rodapé inserir alguma informação adicional sobre a tabela, como, por exemplo, quantos itens existem na tabela ou o somatório de alguma das colunas da tabela.

Na Listagem 9 é mostrado o código que cria um DataTable com um cabeçalho e um rodapé. Para incluir o cabeçalho é incluída a tag com o atributo name com valor header. Para incluir o rodapé é incluída a mesma tag, mas com o atributo name com valor footer.


<html xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:p="http://primefaces.org/ui"
   xmlns:fn="http://java.sun.com/jsp/jstl/functions">

<h:head>

</h:head>

<h:body>
   <h:form>

     <p:dataTable var="cliente" value="#{clienteMB.clientes}" rows="10">
          <f:facet name="header">
          Lista de Pessoas Cadastradas
          </f:facet>
          <p:column headerText="Nome" sortBy="#{cliente.nome}"
             filterBy="#{cliente.nome}">
             <h:outputText value="#{cliente.nome}" />
          </p:column>

          <p:column headerText="Endereço" sortBy="#{cliente.endereco}"
             filterBy="#{cliente.endereco}">
             <h:outputText value="#{cliente.endereco}" />
          </p:column>

          <p:column headerText="Idade" sortBy="#{cliente.idade}"
             filterBy="#{cliente.idade}">
             <h:outputText value="#{cliente.idade}" />
          </p:column>

          <p:column headerText="Descrição" sortBy="#{cliente.descricao}"
             filterBy="#{cliente.descricao}">
             <h:outputText value="#{cliente.descricao}" />
          </p:column>

          <p:column headerText="Telefone" sortBy="#{cliente.telefone}"
             filterBy="#{cliente.telefone}">
             <h:outputText value="#{cliente.telefone}" />
          </p:column>

          <p:column headerText="Data Cadastro" sortBy="#{cliente.dataCadastro}"
             filterBy="#{cliente.dataCadastro}">
             <h:outputText value="#{cliente.dataCadastro}">
                <f:convertDateTime pattern="dd/MM/yyyy" />
             </h:outputText>
          </p:column>
          <f:facet name="footer">
           <h:outputText value="Existem " />
           <h:outputText value="#{fn:length(clienteMB.clientes)}" />
           <h:outputText value=" pessoas cadastradas. " />
            
           
       </f:facet>
     </p:dataTable>
   </h:form>


</h:body>
</html>
Listagem 9. DataTable com cabeçalho e rodapé

Na Figura 4 é mostrada o DataTable com o cabeçalho exibindo a mensagem “Lista de pessoas cadastradas”, e o rodapé com o número de pessoas exibidas na tabela.

DataTable com cabeçalho e rodapé
Figura 4. DataTable com cabeçalho e rodapé

Existem outras funcionalidades para o DataTable no primefaces, mas considero que as mostradas nesse artigo são as mais úteis. Mas para quem quiser saber mais, a documentação do Primefaces é bastante completa. Na seção Links temos as referências que podem ajudar a descobrir mais sobre o Primefaces e o DataTable.

Espero que esse artigo seja útil. Até a próxima!