The problem with using large recordsets is when you click next or
previous it goes through the entire collection to find the start and
end index of the page it's about to display.

Maybe it was done this way to help support the sorting functionality. 
 If you have sorting enabled it will sort your results across all the
pages.  Obviously this is bad if you have a huge collection.

Attached is some code that a fellow coder I work with put together.  
If you put the elements in your collection in the PaginatedList it
will take care of giving display tag the start and end index only for
that page.

Unfortunately you cannot have sortable columns with this solution.

I would recommend adding this into the displaytag source code.
package com.displaytag.pagination;

import java.util.List;

import org.apache.log4j.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: baznar
 * Date: May 24, 2004
 * Time: 4:11:04 PM
 * To change this template use File | Settings | File Templates.
 */
public class ListIterator {
    private int from = 0;
    private int limit=10;

    private List fullList=null;
    private int size=0;

    private static Logger log = Logger.getLogger( ListIterator.class );

    public ListIterator(List list,int limit){
        this.limit =limit;
        fullList=list;
    }
    public void init(){
        size = fullList.size();
        if (log.isDebugEnabled()) {  log.debug("List Size is "+size); }
    }

    public List getList(){
        if (log.isDebugEnabled()) {  log.debug("inside  getList"); }
        int to=from+limit;
        if (to > size)
            to = size;
        if (log.isDebugEnabled()) {  log.debug("Returning List (from,to) 
("+from+","+to+")"); }
        return fullList.subList(from,to);
    }

    public void setNext(){
        log.debug("setNext: from was "+from);
        if ( (from+limit) > size)
            from = 0;
        else
            from+=limit;
         log.debug("setNext: from set to "+from);
    }
    public boolean hasNext(){
        if ( (from+limit) > size)
            return false;
        else
            return true;
    }
    public void setPrev(){
        if ((from-limit) < 0)
            from =0;
        else
            from-=limit;
        if (log.isDebugEnabled()) {  log.debug("setPrev set from to "+from); }
    }
    public boolean hasPrev(){
        if ((from-limit) < 0)
            return false;
        else
            return true;
    }
    public int getTo(){
        int i = from+limit;
        if (i > size) i = size;
        return (i);
    }
    public int getFrom(){
        return from+1;
    }
    public int getSize(){
        return size;
    }

}
package com.displaytag.pagination;


import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import org.apache.log4j.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: baznar
 * Date: Jun 3, 2004
 * Time: 2:44:38 PM
 * To change this template use File | Settings | File Templates.
 */
public class PaginatedList implements List {
    private List list;
    private int firstElement, maxElements, size;
        private static Logger log = Logger.getLogger( PaginatedList.class );
    public PaginatedList() {
    }
    //This constructor will work with the a sublist and size rather than a full list
    public PaginatedList(List list, int firstElement, int maxElements, int size) {
        //public PaginatedList(List list, int firstElement, int maxElements, int size) 
{
            log.info("creating a sub list starting at "+firstElement+" and ending at 
"+maxElements);
            this.size = size;
            this.list = list;
            this.firstElement = firstElement;
            this.maxElements = maxElements;
        }

    public PaginatedList(List list, int firstElement, int maxElements) {
        //public PaginatedList(List list, int firstElement, int maxElements, int size) 
{
            log.info("creating a sub list starting at "+firstElement+" and ending at 
"+maxElements);
            this.size = list.size();
            this.list = list.subList(firstElement,size);

            this.firstElement = firstElement;
            this.maxElements = maxElements;
        }

    /**
     * Get list with the elements of this page
     * @return
     */
    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    /**
     * First element of this page, starting at 0
     * @return
     */
    public int getFirstElement() {
        return firstElement;
    }

    public void setFirstElement(int firstElement) {
        this.firstElement = firstElement;
    }

    /**
     * Max number of elements in the page
     * @return
     */
    public int getMaxElements() {
        return maxElements;
    }

    public void setMaxElements(int maxElements) {
        this.maxElements = maxElements;
    }

    /**
     * Set the number of elements in all the pages
     */
    public void setSize(int size) {
        this.size = size;
    }

    /**
     * Number of elements in this page
     * @return
     */
    public int getPageSize() {
        return list.size();
    }

    /**
     * Calculate the page number, starting at 0
     * @return
     */
    public int getPageNumber() {
        return getFirstElement() / getMaxElements();
    }

    /**
     * Calculate the last page number, starting at 0
     * @return
     */
    public int getLastPageNumber() {
        return (size() - 1) / getMaxElements();
    }

    // ---------------------------- List operations ----------------------------

    /**
     * Unsupported operation
     * @see java.util.Collection#iterator()
     * @throws UnsupportedOperationException
     */
    public Iterator iterator() {
        return new PaginatedListIterator(this);
    }

    /**
     * Number of elements in all the pages
     * @see java.util.Collection#size()
     */
    public int size() {
        return size;
    }

    // ---------------------- Unsupported List operations ----------------------

    /**
     * Unsupported operation
     * @see java.util.List#add(int, java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public void add(int arg0, Object arg1) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#add(java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public boolean add(Object arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#addAll(java.util.Collection)
     * @throws UnsupportedOperationException
     */
    public boolean addAll(Collection arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#addAll(int, java.util.Collection)
     * @throws UnsupportedOperationException
     */
    public boolean addAll(int arg0, Collection arg1) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#clear()
     * @throws UnsupportedOperationException
     */
    public void clear() {
        throw new UnsupportedOperationException();

    }

    /**
     * Unsupported operation
     * @see java.util.Collection#contains(java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public boolean contains(Object arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#containsAll(java.util.Collection)
     * @throws UnsupportedOperationException
     */
    public boolean containsAll(Collection arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#get(int)
     * @throws UnsupportedOperationException
     */
    public Object get(int arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#indexOf(java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public int indexOf(Object arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#isEmpty()
     * @throws UnsupportedOperationException
     */
    public boolean isEmpty() {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#lastIndexOf(java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public int lastIndexOf(Object arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#listIterator()
     * @throws UnsupportedOperationException
     */
    public ListIterator listIterator() {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#listIterator(int)
     * @throws UnsupportedOperationException
     */
    public ListIterator listIterator(int arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#remove(int)
     * @throws UnsupportedOperationException
     */
    public Object remove(int arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#remove(java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public boolean remove(Object arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#removeAll(java.util.Collection)
     * @throws UnsupportedOperationException
     */
    public boolean removeAll(Collection arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#retainAll(java.util.Collection)
     * @throws UnsupportedOperationException
     */
    public boolean retainAll(Collection arg0) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#set(int, java.lang.Object)
     * @throws UnsupportedOperationException
     */
    public Object set(int arg0, Object arg1) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.List#subList(int, int)
     * @throws UnsupportedOperationException
     */
    public List subList(int arg0, int arg1) {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#toArray()
     * @throws UnsupportedOperationException
     */
    public Object[] toArray() {
        throw new UnsupportedOperationException();
    }

    /**
     * Unsupported operation
     * @see java.util.Collection#toArray(java.lang.Object[])
     * @throws UnsupportedOperationException
     */
    public Object[] toArray(Object[] arg0) {
        throw new UnsupportedOperationException();
    }

}
package com.displaytag.pagination;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.apache.log4j.Logger;


/**
 * Created by IntelliJ IDEA.
 * User: baznar
 * Date: Jun 3, 2004
 * Time: 3:31:48 PM
 * To change this template use File | Settings | File Templates.
 */
public class PaginatedListIterator implements Iterator{
    private PaginatedList list;
    private int i = 0;
    private Iterator iterator;
        private static Logger log = Logger.getLogger( PaginatedListIterator.class );
    /**
     * @param list
     */
    public PaginatedListIterator(PaginatedList list) {
        this.list = list;
    }

    /**
     * @see java.util.Iterator#hasNext()
     */
    public boolean hasNext() {
        return i < list.size();
    }

    /**
     * This method follows the rules of Iterator.next() except
     * that it returns null when requesting an element that it's
     * not in the current page.
     * @see java.util.Iterator#next()
     */
    public Object next() {
        if (i == list.getFirstElement()) {
            iterator = list.getList().iterator();
        }

        if ((i >= list.getFirstElement()) && (i < list.getFirstElement() + 
list.getMaxElements())) {
            //log.info("i is inside current page");
            i++;
            return iterator.next();
        }

        if (hasNext()) {
            //log.info("i is not inside current page, but hasNext");
            i++;
            return null;
        } else {
            //log.info("no such element");
            throw new NoSuchElementException();
        }
    }

    /**
     * Unsupported operation
     * @see java.util.Iterator#remove()
     * @throws UnsupportedOperationException
     */
    public void remove() {
        throw new UnsupportedOperationException();
    }

}
package com.displaytag.pagination;


import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.displaytag.tags.TableTagParameters;
import org.displaytag.util.ParamEncoder;

/**
 * Created by IntelliJ IDEA.
 * User: baznar
 * Date: Jun 8, 2004
 * Time: 10:36:16 AM
 * To change this template use File | Settings | File Templates.
 */
public class PaginateUtil {
        private static Logger log = Logger.getLogger( PaginateUtil.class );
        private static ParamEncoder paramEncoder = new ParamEncoder("boardMessage");

    public static int getFirstElement(HttpServletRequest request) {

      //  ParamEncoder paramEncoder = new ParamEncoder("boardMessage");
        String pageParameter = 
paramEncoder.encodeParameterName(TableTagParameters.PARAMETER_PAGE);
        String page = request.getParameter(pageParameter);
        //note:  below 10 should really be a constant somewhere that defines
        //a page size.  just don't know where that constant should live.  so
        //for now it is hard coded
        int index = (page == null)
            ? 0
            : 10 * (Integer.parseInt(page) - 1);
        return index;
    }
}

Reply via email to