quarta-feira, 21 de abril de 2010

Colunas ordenadas no DataTable

Utilizar o componente commandSortHeader do IceFaces pode parecer um pouco confuso no início, mas é um componente muito útil e oferece bastante controle de suas características.
Para utilizá-lo, começamos por modificar as colunas do componente dataTable, dessa maneira:

<ice:column>
   <f:facet name="header">
      <ice:commandsortheader arrow="true" columnname="Nome">
         <ice:outputtext value="Nome"/>
      </ice:commandsortheader>
      <ice:outputtext value="#{item.name}"/>
   </f:facet>
</ice:column>

O valor da propriedade columnname deve ser sempre o título da coluna. Para que o componente dataTable entenda essas mudanças, devemos adicionar a ele algumas propriedades:

<ice:dataTable id="tabelaPessoas"
               value="#{controlador.lista}"
               var="item" border="1"
               rows="3"
               sortColumn="#{controlador.colunaOrdenada}"
               sortAscending="#{controlador.ordemCrescente}">

As duas últimas propriedades é que fazem a diferença. A boa notícia é que o componente se encarrega de enviar as mudanças de coluna que o usuário fizer aos atributos do backing bean (colunaOrdenada e ordemCrescente). Esses atributos serão utilizados para determinar como deve ser feita a ordenação do atributo lista do backing bean, e podem ser declarados como segue, no controlador:
private boolean ordemCrescente = true;
private String colunaOrdenada = "Nome";

É importante perceber que ao ser instanciado, o DataTabe vai ficar ordenado pela coluna "Nome", e qualquer seleção feita pelo usuário será transmitida para o atributo colunaOrdenada. Agora, a má notícia: deve ser implementado um método específico para a ordenação. Eu optei por utilizar um comparator e o método sort da classe java.util.Collections. A seguir, o método utilizado para a ordenação:

01     protected void ordenar(List relacao) {
02         Comparator comparator = new Comparator() {
03 
04             public int compare(Object o1, Object o2) {
05                 Person c1 = (Person) o1;
06                 Person c2 = (Person) o2;
07                 if (colunaOrdenada.equals("Nome")) {
08                     return ordemCrescente
09                             ? (c1.getName()).compareTo((c2.getName()))
10                             : (c2.getName()).compareTo((c1.getName()));
11                 }
12                 if (colunaOrdenada.equals("Tratamento")) {
13                     return ordemCrescente
14                             ? (c1.getJobtitle()).compareTo((c2.getJobtitle()))
15                             : (c2.getJobtitle()).compareTo((c1.getJobtitle()));
16                 }
17                 if (colunaOrdenada.equals("Atualizado em")) {
18                     return ordemCrescente
19                             ? (c1.getLastupdated()).compareTo((c2.getLastupdated()))
20                             : (c2.getLastupdated()).compareTo((c1.getLastupdated()));
21                 }
22                 return 0;
23             }
24         };
25         Collections.sort(relacao, comparator);
26     }

Fica bem claro que para cada coluna, será necessário um tratamento para que o Comparator possa executar as comparações. É importante observar a utilização dos atributos colunaOrdenada e ordemCrescente, que são alterados pela página, conforme as escolhas do usuário. Este método deve ser colocado em algum local onde seja executado quando houver mudança de coluna ou mudança da ordenação. Um bom local é o método que retorna a lista para o dataTable:

    public ListDataModel getLista() {
        List relacao = dao.crud("from Person");
        ordenar(relacao);
        lista = new ListDataModel(relacao);
        return lista;
    }

Para finalizar, é necessário declarar os atributos e criar os métodos get e set para cada um deles. A seguir, um screenshot com a ordenação funcionando, e observamos que ela respeita a paginação, o que em muitas linguagens não funciona de maneira adequada.


Nenhum comentário:

Postar um comentário