KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > databinding > datagrid > api > pager > PagerModel


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.databinding.datagrid.api.pager;
19
20 import org.apache.beehive.netui.util.Bundle;
21
22 /**
23  * <p>
24  * The PagerModel is a JavaBean that represents the page state of a data grid. In the default implementation,
25  * the page state consists of three pieces of data:
26  * <ul>
27  * <li>the current row</li>
28  * <li>current page</li>
29  * <li>the href / action used to page through data</li>
30  * </ul>
31  * This pager model implementation is row based which means that the notion of the current page
32  * is based on which row is at the top of a page. Row numbering starts at zero and continues to page size.
33  * For example, in a data grid on its first page and with a page size of 10, the rows 0-9 will be displayed. The
34  * next page would contain rows 10-11 and so on.
35  * </p>
36  * <p>
37  * The pager model provides JavaBean-style access to the properties of a pager. In addition, it provides read-only
38  * access to information about the row to use in order to navigate to a specific page. To navigate to the previous
39  * page, the {@link #getRowForPreviousPage()} will return the row number that will appear at the top of the previous
40  * page. In order to build effective paging UI, it is also often useful to know the absolute page number.
41  * As with row numbers, page numbers are zero based. For example, if a data set displayed in a data grid has 30
42  * records and the grid is on page a page displaying rows 10-19, the current page is 1. When displaying this value
43  * in UI, it is often useful to display it as:
44  * <pre>
45  * Page 2 of 3
46  * </pre>
47  * Random page access can also be accomplished using the {@link #encodeRowForPage(int)} method which will return
48  * the row number to display when jumping to a specific page in a grid.
49  * </p>
50  */

51 public class PagerModel
52     implements java.io.Serializable JavaDoc {
53
54     public static final int DEFAULT_PAGE_SIZE = 10;
55     public static final int DEFAULT_ROW = 0;
56
57     private String JavaDoc _pageHref = null;
58     private String JavaDoc _pageAction = null;
59     private Integer JavaDoc _currentRow = null;
60     private Integer JavaDoc _dataSetSize = null;
61     private Integer JavaDoc _explicitPageSize = null;
62     private Integer JavaDoc _defaultPageSize = null;
63
64     /**
65      * Default constructor. This initializes the current row to the default row value {@link #DEFAULT_ROW}.
66      */

67     public PagerModel() {
68         _currentRow = new Integer JavaDoc(DEFAULT_ROW);
69     }
70
71     /**
72      * Get the action used when building URLs for navigating to another page.
73      * @return the action name or <code>null</code> if no action name is set
74      */

75     public String JavaDoc getPageAction() {
76         return _pageAction;
77     }
78
79     /**
80      * Set the action used to navigate to another page.
81      * @param pageAction the action name
82      */

83     public void setPageAction(String JavaDoc pageAction) {
84         _pageAction = pageAction;
85     }
86
87     /**
88      * Get the href used when building URLs for navigating to another page.
89      * @return the href or <code>null</code> if no href is set
90      */

91     public String JavaDoc getPageHref() {
92         return _pageHref;
93     }
94
95     /**
96      * Set the href used to navigate to another page.
97      * @param pageHref the href
98      */

99     public void setPageHref(String JavaDoc pageHref) {
100         _pageHref = pageHref;
101     }
102
103     /**
104      * Get the default page size. If no page size has been set via {@link #setDefaultPageSize(int)} this
105      * value is {@link #DEFAULT_PAGE_SIZE}
106      * @return the default page size
107      */

108     public int getDefaultPageSize() {
109         if(_defaultPageSize != null)
110             return _defaultPageSize.intValue();
111         else return DEFAULT_PAGE_SIZE;
112     }
113
114     /**
115      * Set the default page size. The default page size is used when no other page size has been set and is useful
116      * when clients wish to occasionally override the page size but wish to have the default page size set
117      * differently than the PagerModel's default.
118      *
119      * @param pageSize the new page size
120      * @throws IllegalArgumentException if the page size is less than 1
121      */

122     public void setDefaultPageSize(int pageSize) {
123         if(pageSize < 1)
124             throw new IllegalArgumentException JavaDoc(Bundle.getErrorString("PagerModel_IllegalDefaultPageSize"));
125
126         _defaultPageSize = new Integer JavaDoc(pageSize);
127     }
128
129     /**
130      * Set the data set size. In order to calculate paging state for the last page such as the
131      * state returned for {@link #getRowForLastPage()} the default PagerModel implementation must
132      * know the total size of the data set.
133      *
134      * @return the size
135      */

136     public int getDataSetSize() {
137         if(_dataSetSize == null)
138             return 0;
139         else return _dataSetSize.intValue();
140     }
141
142     /**
143      * Set the data set size.
144      * @param dataSetSize the size
145      */

146     public void setDataSetSize(int dataSetSize) {
147         _dataSetSize = new Integer JavaDoc(dataSetSize);
148     }
149
150     /**
151      * Get the current page size.
152      * @return the page size
153      */

154     public int getPageSize() {
155         return _explicitPageSize != null ? _explicitPageSize.intValue() : getDefaultPageSize();
156     }
157
158     /**
159      * Sets the page size and overrides the default page size if one has been set.
160      * @param pageSize the specific page size
161      */

162     public void setPageSize(int pageSize) {
163         if(pageSize < 1)
164             throw new IllegalArgumentException JavaDoc(Bundle.getErrorString("PagerModel_IllegalPageSize"));
165
166         _explicitPageSize = new Integer JavaDoc(pageSize);
167     }
168
169     /**
170      * Get the page number given the current page size and current row. The page number is zero based and should be
171      * adjusted by one when being displayed to users.
172      * @return the page number
173      */

174     public int getPage() {
175         int row = getRow();
176         assert row % getPageSize() == 0 : "Invalid current row \"" + row + "\" for page size \"" + getPageSize() + "\"";
177         assert getPageSize() > 0;
178         return row / getPageSize();
179     }
180
181     /**
182      * Set a specific page. This will change the current row to match the given page value.
183      *
184      * @param page the new page
185      * @throws IllegalArgumentException if the given page is less than zero
186      */

187     public void setPage(int page) {
188         if(page < 0)
189             throw new IllegalArgumentException JavaDoc(Bundle.getErrorString("PagerModel_IllegalPage"));
190
191         /* todo: need to check that the new 'current' page is in range given the first/last boundaries */
192         _currentRow = new Integer JavaDoc(page * getPageSize());
193     }
194
195     /**
196      * Get the current row. If no row has been specified, the default row is returned.
197      * @return the current row
198      */

199     public int getRow() {
200         if(_currentRow != null) {
201             int row = _currentRow.intValue();
202
203             /* if the row is out of range, simply adjust to the last row */
204             if(_dataSetSize != null && (row > _dataSetSize.intValue()))
205                 row = _dataSetSize.intValue();
206
207             if(row % getPageSize() != 0) {
208                 int adjustedPage = row - (row % getPageSize());
209                 return adjustedPage;
210             }
211             else return row;
212         }
213         else return DEFAULT_ROW;
214     }
215
216     /**
217      * Set the current row.
218      * @param row the new row
219      * @throws IllegalArgumentException if the given row is less than zero
220      */

221     public void setRow(int row) {
222         if(row < 0)
223             throw new IllegalArgumentException JavaDoc(Bundle.getErrorString("PagerModel_IllegalRow"));
224
225         _currentRow = new Integer JavaDoc(row);
226     }
227
228     /**
229      * <p>
230      * Get the last row for the current page of data. This value is useful when displaying paging UI like:
231      * <pre>
232      * Row 11 through 20 of 60
233      * </pre>
234      * The last row on the page is returned as a zero-based number from the beginning of the data set. In the
235      * case above, the value returned is <code>19</code> and is converted to <code>20</code> for readability
236      * by adding one. If the current page is only partially filled, this method will return the value for a partial page.
237      * For example, with a data set of size 4 on a page of size 10, the value <code>3</code> would be returned.
238      * </p>
239      * @return the last row for the current page
240      */

241     public int getLastRowForPage() {
242         int row = getRow();
243         if(_dataSetSize != null) {
244             if(_dataSetSize.intValue() - row < getPageSize())
245                 return row + (_dataSetSize.intValue() - row) - 1;
246             else return row + getPageSize() - 1;
247         }
248         else return row + getPageSize() - 1;
249     }
250
251     /**
252      * Get the row used to display the first page.
253      * @return the row for the first page
254      */

255     public int getRowForFirstPage() {
256         return DEFAULT_ROW;
257     }
258
259     /**
260      * Get the row used to display the previous page. Note, a return value of less than zero means that the previous
261      * page does not exist as it would scroll off the beginning of the data set and is invalid.
262      * @return the row for the previous page
263      */

264     public int getRowForPreviousPage() {
265         int value = getRow() - getPageSize();
266         return value > -1 ? value : -1;
267     }
268
269     /**
270      * Get the row used to display the next page. Note, if this value is greater than the size of the data set
271      * it would scroll off the end of the data set and is invalid.
272      * @return the row for the previous page
273      */

274     public int getRowForNextPage() {
275         return getRow() + getPageSize();
276     }
277
278     /**
279      * Get the row used to display the last page. This requires tha the data set size has been set via
280      * @return the row for the last page
281      * @throws IllegalStateException when the size of the data set has not been set
282      */

283     public int getRowForLastPage() {
284         Integer JavaDoc lastRow = internalGetLastRow();
285         if(lastRow != null)
286             return lastRow.intValue();
287         else throw new IllegalStateException JavaDoc(Bundle.getErrorString("PagerModel_CantCalculateLastPage"));
288     }
289
290     /**
291      * Get the row needed to jump to the given <code>page</code>
292      * @param page the new page
293      * @return the row used to jump to the new page
294      * @throws IllegalArgumentException if the given page value is less than zero
295      */

296     public int encodeRowForPage(int page) {
297         if(page < 0)
298             throw new IllegalArgumentException JavaDoc(Bundle.getErrorString("PagerModel_IllegalPage"));
299
300         return page * getPageSize();
301     }
302
303     /**
304      * Get the total number of pages. This value is useful when displaying the total number of pages in UI like:
305      * <pre>
306      * Page 4 of 10
307      * </pre>
308      * This method returns an absolute count of the number of pages which could be displayed given the
309      * size of the data set and the current page size. This method requires the PagerModel know the
310      * total size of the data set.
311      * @return the number of pages
312      * @throws IllegalStateException when the size of the data set has not been set
313      */

314     public int getPageCount() {
315         if(_dataSetSize != null)
316             return (int)Math.ceil(_dataSetSize.doubleValue()/(double)getPageSize());
317         else throw new IllegalStateException JavaDoc(Bundle.getErrorString("PagerModel_CantCalculateLastPage"));
318     }
319
320     /**
321      * Get the page number of the first page.
322      * @return the first page
323      */

324     public int getFirstPage() {
325         return 0;
326     }
327
328     /**
329      * Get the page number of the previous page.
330      * @return the previous page
331      */

332     public int getPreviousPage() {
333         int previousPageRow = getRowForPreviousPage();
334         return previousPageRow == -1 ? previousPageRow : (int)(previousPageRow / getPageSize());
335     }
336
337     /**
338      * Get the page number for the next page.
339      * @return the next page
340      */

341     public int getNextPage() {
342         return (int)(getRowForNextPage() / getPageSize());
343     }
344
345     /**
346      * Get the page number for the last page.
347      * @return the last page
348      */

349     public int getLastPage() {
350         return (int)(Math.floor(getRowForLastPage() / getPageSize()));
351     }
352
353     /**
354      * Internal method used to calculate the last row given a data set size.
355      * @return the last row or <code>null</code> if the last row can not be calculated
356      */

357     private Integer JavaDoc internalGetLastRow() {
358         if(_dataSetSize != null) {
359             /*
360               29 / 10: 0-9, 10-19, 20-29 _lastRow = 20
361               30 / 10: 0-9, 10-19, 20-29, 30-39 _lastRow = 30
362               31 / 10: 0-9, 10-19, 20-29, 30-39 _lastRow = 30
363               32 / 10: 0-9, 10-19, 20-29, 30-39 _lastRow = 30
364
365               29 - (29%10) = 20
366               30 - (30%10) = 30
367               30 - (30%10) = 30
368               36 - (36%10) = 30
369
370               12 / 2: 0-1, 2-3, 4-5, 6-7, 8-9, 10-11, 12-13 _lastRow=10
371               12 / 5: 0-4, 5-9, 10-14 _lastRow=5
372              */

373             int lastRow = getPageSize() * (int)Math.floor((double)(_dataSetSize.intValue()-1) / (double)getPageSize());
374             return new Integer JavaDoc(lastRow);
375         }
376         else return null;
377     }
378 }
379
Popular Tags