📄 abstractpageableview.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.wicket.markup.repeater;import java.util.Iterator;import java.util.NoSuchElementException;import org.apache.wicket.markup.html.navigation.paging.IPageable;import org.apache.wicket.model.IModel;import org.apache.wicket.version.undo.Change;/** * An abstract repeater view that provides paging functionality to its subclasses. * <p> * The view is populated by overriding the <code>getItemModels(int offset, int count)</code> * method and providing an iterator that returns models for items in the current page. The * AbstractPageableView builds the items that will be rendered by looping over the models and * calling the <code>newItem(String id, int index, IModel model)</code> to generate the child item * container followed by <code>populateItem(Component item)</code> to let the user populate the * newly created item container with with custom components. * </p> * * @see org.apache.wicket.markup.repeater.RefreshingView * @see org.apache.wicket.markup.html.navigation.paging.IPageable * * @author Igor Vaynberg (ivaynberg) * */public abstract class AbstractPageableView extends RefreshingView implements IPageable{ /** * */ private static final long serialVersionUID = 1L; /** * Keeps track of the number of items we show per page. The default is Integer.MAX_VALUE which * effectively disables paging. */ private int itemsPerPage = Integer.MAX_VALUE; /** * Keeps track of the current page number. */ private int currentPage; /** * <code>cachedItemCount</code> is used to cache the call to * <code>internalGetItemCount()</code> for the duration of the request because that call can * potentially be expensive ( a select count query ) and so we do not want to execute it * multiple times. */ private transient int cachedItemCount; /** @see org.apache.wicket.Component#Component(String, IModel) */ public AbstractPageableView(String id, IModel model) { super(id, model); clearCachedItemCount(); } /** @see org.apache.wicket.Component#Component(String) */ public AbstractPageableView(String id) { super(id); clearCachedItemCount(); } /** * This method retrieves the subset of models for items in the current page and allows * RefreshingView to generate items. * * @return iterator over models for items in the current page */ protected Iterator getItemModels() { int offset = getViewOffset(); int size = getViewSize(); Iterator models = getItemModels(offset, size); models = new CappedIteratorAdapter(models, size); return models; } protected void onBeforeRender() { clearCachedItemCount(); super.onBeforeRender(); } /** * Returns an iterator over models for items in the current page * * @param offset * index of first item in this page * @param size * number of items that will be shown in the current page * @return an iterator over models for items in the current page */ protected abstract Iterator getItemModels(int offset, int size); // ///////////////////////////////////////////////////////////////////////// // ITEM COUNT CACHE // ///////////////////////////////////////////////////////////////////////// private void clearCachedItemCount() { cachedItemCount = -1; } private void setCachedItemCount(int itemCount) { cachedItemCount = itemCount; } private int getCachedItemCount() { if (cachedItemCount < 0) { throw new IllegalStateException("getItemCountCache() called when cache was not set"); } return cachedItemCount; } private boolean isItemCountCached() { return cachedItemCount >= 0; } // ///////////////////////////////////////////////////////////////////////// // PAGING // ///////////////////////////////////////////////////////////////////////// /** * @return maximum number of items that will be shown per page */ protected final int internalGetRowsPerPage() { return itemsPerPage; } /** * Sets the maximum number of items to show per page. The current page will also be set to zero * * @param items */ protected final void internalSetRowsPerPage(int items) { if (items < 1) { throw new IllegalArgumentException("Argument [itemsPerPage] cannot be less than 1"); } if (itemsPerPage != items) { if (isVersioned()) { addStateChange(new Change() { private static final long serialVersionUID = 1L; final int old = itemsPerPage; public void undo() { itemsPerPage = old; } public String toString() { return "ItemsPerPageChange[component: " + getPath() + ", itemsPerPage: " + old + "]"; } }); } } itemsPerPage = items; // because items per page can effect the total number of pages we always // reset the current page back to zero setCurrentPage(0); } /** * @return total item count */ protected abstract int internalGetItemCount(); /** * @return total item count */ public final int getRowCount() { if (!isVisibleInHierarchy()) { return 0; } if (isItemCountCached()) { return getCachedItemCount(); } int count = internalGetItemCount(); setCachedItemCount(count); return count; } /** * @see org.apache.wicket.markup.html.navigation.paging.IPageable#getCurrentPage() */ public final int getCurrentPage() { int page = currentPage; /* * trim current page if its out of bounds this can happen if items are added/deleted between * requests */ if (page > 0 && page >= getPageCount()) { page = Math.max(getPageCount() - 1, 0); currentPage = page; return page; } return page; } /** * @see org.apache.wicket.markup.html.navigation.paging.IPageable#setCurrentPage(int) */ public final void setCurrentPage(int page) { // If page == 0, short-circuit the range check. This saves a call to // getPageCount(), but more importantly avoids it being called until // your AbstractPageableView is actually rendered. if (page != 0 && (page < 0 || (page >= getPageCount() && getPageCount() > 0))) { throw new IndexOutOfBoundsException("argument [page]=" + page + ", must be 0<=page<" + getPageCount()); } if (currentPage != page) { if (isVersioned()) { addStateChange(new Change() { private static final long serialVersionUID = 1L; private final int old = currentPage; public void undo() { currentPage = old; } public String toString() { return "CurrentPageChange[component: " + getPath() + ", currentPage: " + old + "]"; } }); } } currentPage = page; } /** * @see org.apache.wicket.markup.html.navigation.paging.IPageable#getPageCount() */ public final int getPageCount() { int total = getRowCount(); int page = internalGetRowsPerPage(); int count = total / page; if (page * count < total) { count++; } return count; } /** * @return the index of the first visible item */ protected int getViewOffset() { return getCurrentPage() * internalGetRowsPerPage(); } /** * @return the number of items visible */ protected int getViewSize() { return Math.min(internalGetRowsPerPage(), getRowCount() - getViewOffset()); } // ///////////////////////////////////////////////////////////////////////// // HELPER CLASSES // ///////////////////////////////////////////////////////////////////////// /** * Iterator adapter that makes sure only the specified max number of items can be accessed from * its delegate. */ private static class CappedIteratorAdapter implements Iterator { private final int max; private int index; private final Iterator delegate; /** * Constructor * * @param delegate * delegate iterator * @param max * maximum number of items that can be accessed. */ public CappedIteratorAdapter(Iterator delegate, int max) { this.delegate = delegate; this.max = max; } /** * @see java.util.Iterator#remove() */ public void remove() { throw new UnsupportedOperationException(); } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return (index < max) && delegate.hasNext(); } /** * @see java.util.Iterator#next() */ public Object next() { if (index >= max) { throw new NoSuchElementException(); } index++; return delegate.next(); } }; protected void onDetach() { clearCachedItemCount(); super.onDetach(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -