001: /* Paging.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Thu Aug 17 15:26:06 2006, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2006 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: }}IS_RIGHT
016: */
017: package org.zkoss.zul;
018:
019: import org.zkoss.mesg.Messages;
020: import org.zkoss.zk.ui.WrongValueException;
021: import org.zkoss.zk.au.Command;
022: import org.zkoss.zk.ui.event.Events;
023:
024: import org.zkoss.zul.mesg.MZul;
025: import org.zkoss.zul.event.ZulEvents;
026: import org.zkoss.zul.event.PagingEvent;
027: import org.zkoss.zul.impl.XulElement;
028: import org.zkoss.zul.ext.Paginal;
029:
030: /**
031: * Paging of long content.
032: *
033: * <p>Default {@link #getSclass}: paging.
034: *
035: * @author tomyeh
036: */
037: public class Paging extends XulElement implements Paginal {
038: /** # of items per page. */
039: private int _pgsz = 20;
040: /** total # of items. */
041: private int _ttsz = 0;
042: /** # of pages. */
043: private int _npg = 1;
044: /** the active page. */
045: private int _actpg = 0;
046: /** # of page anchors are visible */
047: private int _pginc = 10;
048: /** Whether to hide automatically if only one page is available. */
049: private boolean _autohide;
050: /** Whether to show detailed info. */
051: private boolean _detailed;
052:
053: public Paging() {
054: setSclass("paging");
055: }
056:
057: /** Contructor.
058: *
059: * @param totalsz the total # of items
060: * @param pagesz the # of items per page
061: */
062: public Paging(int totalsz, int pagesz) {
063: this ();
064: setTotalSize(totalsz);
065: setPageSize(pagesz);
066: }
067:
068: //Paginal//
069: public int getPageSize() {
070: return _pgsz;
071: }
072:
073: public void setPageSize(int size) throws WrongValueException {
074: if (size <= 0)
075: throw new WrongValueException("positive only");
076:
077: if (_pgsz != size) {
078: _pgsz = size;
079: updatePageNum();
080: Events.postEvent(new PagingEvent("onPagingImpl", this ,
081: _actpg));
082: //onPagingImpl is used for implementation purpose only
083: }
084: }
085:
086: public int getTotalSize() {
087: return _ttsz;
088: }
089:
090: public void setTotalSize(int size) throws WrongValueException {
091: if (size < 0)
092: throw new WrongValueException("non-negative only");
093:
094: if (_ttsz != size) {
095: _ttsz = size;
096: updatePageNum();
097: if (_detailed)
098: invalidate();
099: }
100: }
101:
102: private void updatePageNum() {
103: int v = (_ttsz - 1) / _pgsz + 1;
104: if (v == 0)
105: v = 1;
106: if (v != _npg) {
107: _npg = v;
108: if (_actpg >= _npg)
109: _actpg = _npg - 1;
110:
111: invalidate();
112: }
113: }
114:
115: public int getPageCount() {
116: return _npg;
117: }
118:
119: public int getActivePage() {
120: return _actpg;
121: }
122:
123: public void setActivePage(int pg) throws WrongValueException {
124: if (pg >= _npg || pg < 0)
125: throw new WrongValueException(
126: "Unable to set active page to " + pg
127: + " since only " + _npg + " pages");
128: if (_actpg != pg) {
129: _actpg = pg;
130: invalidate();
131: Events.postEvent(new PagingEvent("onPagingImpl", this ,
132: _actpg));
133: //onPagingImpl is used for implementation purpose only
134: }
135: }
136:
137: public int getPageIncrement() {
138: return _pginc;
139: }
140:
141: public void setPageIncrement(int pginc) throws WrongValueException {
142: if (pginc <= 0)
143: throw new WrongValueException(
144: "Nonpositive is not allowed: " + pginc);
145: if (_pginc != pginc) {
146: _pginc = pginc;
147: invalidate();
148: }
149: }
150:
151: public boolean isDetailed() {
152: return _detailed;
153: }
154:
155: public void setDetailed(boolean detailed) {
156: if (_detailed != detailed) {
157: _detailed = detailed;
158: invalidate();
159: }
160: }
161:
162: //extra//
163: /** Returns whether to automatically hide this component if
164: * there is only one page available.
165: * <p>Default: false.
166: */
167: public boolean isAutohide() {
168: return _autohide;
169: }
170:
171: /** Sets whether to automatically hide this component if
172: * there is only one page available.
173: */
174: public void setAutohide(boolean autohide) {
175: if (_autohide != autohide) {
176: _autohide = autohide;
177: if (_npg == 1)
178: invalidate();
179: }
180: }
181:
182: /** Returns the inner HTML tags of this component.
183: * <p>Used only for component development. Not accessible by
184: * application developers.
185: */
186: public String getInnerTags() {
187: final StringBuffer sb = new StringBuffer(512);
188:
189: int half = _pginc / 2;
190: int begin, end = _actpg + half - 1;
191: if (end >= _npg) {
192: end = _npg - 1;
193: begin = end - _pginc + 1;
194: if (begin < 0)
195: begin = 0;
196: } else {
197: begin = _actpg - half;
198: if (begin < 0)
199: begin = 0;
200: end = begin + _pginc - 1;
201: if (end >= _npg)
202: end = _npg - 1;
203: }
204:
205: if (_actpg > 0) {
206: if (begin > 0) //show first
207: appendAnchor(sb, Messages.get(MZul.FIRST), 0);
208: appendAnchor(sb, Messages.get(MZul.PREV), _actpg - 1);
209: }
210:
211: boolean bNext = _actpg < _npg - 1;
212: for (; begin <= end; ++begin) {
213: if (begin == _actpg) {
214: sb.append(begin + 1).append(" ");
215: } else {
216: appendAnchor(sb, Integer.toString(begin + 1), begin);
217: }
218: }
219:
220: if (bNext) {
221: appendAnchor(sb, Messages.get(MZul.NEXT), _actpg + 1);
222: if (end < _npg - 1) //show last
223: appendAnchor(sb, Messages.get(MZul.LAST), _npg - 1);
224: }
225: if (_detailed)
226: sb.append("<span>[").append(_actpg * _pgsz + 1).append('/')
227: .append(_ttsz).append("]</span>");
228: return sb.toString();
229: }
230:
231: private static final void appendAnchor(StringBuffer sb,
232: String label, int val) {
233: sb.append("<a href=\"javascript:;\" onclick=\"zkPg.go(this,")
234: .append(val).append(")\">").append(label).append(
235: "</a> ");
236: }
237:
238: //-- Component --//
239: public boolean isVisible() {
240: return super .isVisible() && (_npg > 1 || !_autohide);
241: }
242:
243: public boolean isChildable() {
244: return false;
245: }
246: }
|