JSF 2データテーブルのソートの例 - DataModel

前のリンク://jsf2/jsf-2-datatable-sorting-example/[JSF 2 dataTableソートの例]では、リストをソートしてdataTableに表示するカスタムコンパレータを示しました。

DataModelデコレータ

この例では、dataModel Decoratorと呼ばれる Core JavaServer Faces(第3版) に記載されているdataTableのリストをソートする別の方法を示しています。

1. DataModel

package com.mkyong;

import java.util.Arrays;
import java.util.Comparator;
import javax.faces.model.DataModel;

public class SortableDataModel<E> extends DataModel<E>{

    DataModel<E> model;
    private Integer[]rows;

    SortableDataModel(DataModel<E> model){
        this.model = model;
        initRows();
    }

    public void initRows(){
        int rowCount = model.getRowCount();
        if(rowCount != -1){
            this.rows = new Integer[rowCount];
            for(int i = 0; i < rowCount; ++i){
                rows[i]= i;
            }
        }
    }

    public void sortBy(final Comparator<E> comparator){
        Comparator<Integer> rowComp = new Comparator<Integer>() {
            public int compare(Integer i1, Integer i2){
                E o1 = getData(i1);
                E o2 = getData(i2);
                return comparator.compare(o1, o2);
            }
        };
        Arrays.sort(rows, rowComp);

    }

    private E getData(int row){
        int originalRowIndex = model.getRowIndex();

        model.setRowIndex(row);
        E newRowData = model.getRowData();
        model.setRowIndex(originalRowIndex);

        return newRowData;
    }

    @Override
    public void setRowIndex(int rowIndex) {

        if(0 <= rowIndex && rowIndex < rows.length){
            model.setRowIndex(rows[rowIndex]);
        }else{
            model.setRowIndex(rowIndex);
        }
    }

    @Override
    public boolean isRowAvailable() {
        return model.isRowAvailable();
    }

    @Override
    public int getRowCount() {
        return model.getRowCount();
    }

    @Override
    public E getRowData() {
        return model.getRowData();
    }

    @Override
    public int getRowIndex() {
        return model.getRowIndex();
    }

    @Override
    public Object getWrappedData() {
        return model.getWrappedData();
    }

    @Override
    public void setWrappedData(Object data) {

        model.setWrappedData(data);
        initRows();

    }

}

2.マネージドBean

テストのためのダミーリストを提供するマネージドBean、およびカスタムDataModelを使用してdataTableリスト** をソートする方法を示します。

package com.mkyong;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Comparator;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.ArrayDataModel;
import javax.faces.model.DataModel;

@ManagedBean(name="order")
@SessionScoped
public class OrderBean implements Serializable{

    private static final long serialVersionUID = 1L;

    private SortableDataModel<Order> sotableDataModel;

    private boolean sortAscending = true;

    private static final Order[]orderList = {
        new Order("A0002", "Harddisk 100TB",
                new BigDecimal("500.00"), 3),
        new Order("A0001", "Intel CPU",
                new BigDecimal("4200.00"), 6),
        new Order("A0004", "Samsung LCD",
                new BigDecimal("5200.00"), 10),
        new Order("A0003", "Dell Laptop",
                new BigDecimal("11600.00"), 9),
        new Order("A0005", "A4Tech Mouse",
                new BigDecimal("200.00"), 20)
    };

    public OrderBean(){

        sotableDataModel = new SortableDataModel<Order>(
            new ArrayDataModel<Order>(orderList));

    }

    public DataModel<Order> getOrderList() {

        return sotableDataModel;

    }

   //sort by order no
    public String sortByOrderNo() {

        if(sortAscending){

          sotableDataModel.sortBy(new Comparator<Order>() {

            @Override
            public int compare(Order o1, Order o2) {

                return o1.getOrderNo().compareTo(o2.getOrderNo());

            }
        });

        sortAscending = false;

      }else{

       //descending order
        sotableDataModel.sortBy(new Comparator<Order>() {

            @Override
            public int compare(Order o1, Order o2) {

                return o2.getOrderNo().compareTo(o1.getOrderNo());

            }
        });
        sortAscending = true;
      }

      return null;
    }

    public static class Order{

        String orderNo;
        String productName;
        BigDecimal price;
        int qty;

        public Order(String orderNo, String productName,
                BigDecimal price, int qty) {
            this.orderNo = orderNo;
            this.productName = productName;
            this.price = price;
            this.qty = qty;
        }

       //getter and setter methods

    }
}

2. dataTableタグ

JSFページでcommandLinkタグを "Order No"列ヘッダーに配置し、クリックするとdataTableリストをソートします。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:c="http://java.sun.com/jsp/jstl/core"
      >
    <h:head>
        <h:outputStylesheet library="css" name="table-style.css" />
    </h:head>
    <h:body>

        <h1>JSF 2 dataTable sorting example</h1>
          <h:form>
            <h:dataTable value="#{order.orderList}" var="o"
                styleClass="order-table"
                headerClass="order-table-header"
                rowClasses="order-table-odd-row,order-table-even-row"
            >

            <h:column>
                <f:facet name="header">
                   <h:commandLink action="#{order.sortByOrderNo}">
                    Order No
                   </h:commandLink>
                </f:facet>
                #{o.orderNo}
            </h:column>

            <h:column>
                <f:facet name="header">
                    Product Name
            </f:facet>
                #{o.productName}
            </h:column>

            <h:column>
                <f:facet name="header">Price</f:facet>
                #{o.price}
            </h:column>

            <h:column>
                <f:facet name="header">Quantity</f:facet>
                #{o.qty}
            </h:column>

            </h:dataTable>
          </h:form>
    </h:body>
</html>

デモ

上から順に、dataTableリストが昇順および降順にソートされていることを示します。

jsf2-dataTable-Sorting-Example-1、title = "jsf2-dataTable-Sorting-Example-1"、幅= 546、高さ= 423

jsf2-dataTable-Sorting-Example-2、title = "jsf2-dataTable-Sorting-Example-2"、幅= 546、高さ= 423

jsf2-dataTable-Sorting-Example-3、title = "jsf2-dataTable-Sorting-Example-3"、幅= 546、高さ= 423

ソースコードをダウンロードする

ダウンロード - リンク://wp-content/uploads/2010/10/JSF-2-DataTable-Sorting-DataModel-Example.zip[JSF-2-DataTable-Sorting-DataModel-Example.zip](11KB)

リファレンス

  1. link://jsf2/jsf-2-datatable-sorting-example/[JSF 2 dataTableソート

例]。リンク://java/java-object-sorting-example-comparable-and-comparator/[Java

オブジェクトソートの例]