001: /*
002: * MyGWT Widget Library
003: * Copyright(c) 2007, MyGWT.
004: * licensing@mygwt.net
005: *
006: * http://mygwt.net/license
007: */
008: package net.mygwt.ui.client.widget;
009:
010: import net.mygwt.ui.client.MyGWT;
011: import net.mygwt.ui.client.Style;
012: import net.mygwt.ui.client.data.DataLoader;
013: import net.mygwt.ui.client.data.LoadConfig;
014: import net.mygwt.ui.client.data.LoadEvent;
015: import net.mygwt.ui.client.data.LoadResult;
016: import net.mygwt.ui.client.data.Loader;
017: import net.mygwt.ui.client.event.BaseEvent;
018: import net.mygwt.ui.client.event.Listener;
019: import net.mygwt.ui.client.event.SelectionListener;
020: import net.mygwt.ui.client.util.Util;
021:
022: import com.google.gwt.user.client.ui.ChangeListener;
023: import com.google.gwt.user.client.ui.HorizontalPanel;
024: import com.google.gwt.user.client.ui.KeyboardListener;
025: import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
026: import com.google.gwt.user.client.ui.Label;
027: import com.google.gwt.user.client.ui.TextBox;
028: import com.google.gwt.user.client.ui.Widget;
029: import com.google.gwt.user.client.ui.WidgetHelper;
030:
031: /**
032: * A specialized toolbar that is bound to a {@link DataLoader} and provides
033: * automatic paging controls.
034: */
035: public class PagingToolBar extends Component implements Listener {
036:
037: /**
038: * True to use the last load config which allows state data to persist load
039: * requests (defaults to false).
040: */
041: public boolean useLastConfig;
042:
043: protected Loader loader;
044: protected int cursor, pageSize;
045: protected int activePage, pages;
046: protected HorizontalPanel panel;
047: protected ToolItem first, prev, next, last, refresh;
048: protected Label afterText;
049: protected Label displayText;
050: protected TextBox pageText;
051:
052: /**
053: * Creates a new paging tool bar with the given page size.
054: *
055: * @param pageSize the page size
056: */
057: public PagingToolBar(final int pageSize) {
058: this .pageSize = pageSize;
059: baseStyle = "my-paging-toolbar";
060: }
061:
062: /**
063: * Binds the toolbar to the loader.
064: *
065: * @param loader the loader
066: */
067: public void bind(Loader loader) {
068: if (this .loader != null) {
069: this .loader.removeListener(Loader.BeforeLoad, this );
070: this .loader.removeListener(Loader.Load, this );
071: this .loader.removeListener(Loader.LoadException, this );
072: }
073: this .loader = loader;
074: loader.addListener(Loader.BeforeLoad, this );
075: loader.addListener(Loader.Load, this );
076: loader.addListener(Loader.LoadException, this );
077: }
078:
079: /**
080: * Returns the active page.
081: *
082: * @return the active page
083: */
084: public int getActivePage() {
085: return activePage;
086: }
087:
088: /**
089: * Returns the current page size.
090: *
091: * @return the page size
092: */
093: public int getPageSize() {
094: return pageSize;
095: }
096:
097: /**
098: * Returns the total number of pages.
099: *
100: * @return the
101: */
102: public int getTotalPages() {
103: return pages;
104: }
105:
106: public void handleEvent(BaseEvent be) {
107: switch (be.type) {
108: case DataLoader.BeforeLoad:
109: refresh.setIconStyle("icon-wait");
110: break;
111: case DataLoader.Load:
112: onLoad((LoadEvent) be);
113: refresh.setIconStyle("icon-done");
114: break;
115: case DataLoader.LoadException:
116: refresh.setIconStyle("icon-done");
117: break;
118: }
119: }
120:
121: /**
122: * Sets the active page.
123: *
124: * @param page the page
125: */
126: public void setActivePage(int page) {
127: if (page != activePage && page > 0 && page <= pages) {
128: LoadConfig config = new LoadConfig();
129: config.start = --page * pageSize;
130: config.limit = pageSize;
131: loader.load(config);
132: } else {
133: pageText.setText(String.valueOf((int) activePage));
134: }
135: }
136:
137: /**
138: * Sets the current page size. This method does not effect the data currently
139: * being displayed. The new page size will not be used until the next load
140: * request.
141: *
142: * @param pageSize the new page size
143: */
144: public void setPageSize(int pageSize) {
145: this .pageSize = pageSize;
146: }
147:
148: protected void doAttachChildren() {
149: WidgetHelper.doAttach(panel);
150: }
151:
152: protected void doDetachChildren() {
153: WidgetHelper.doDetach(panel);
154: }
155:
156: protected LoadConfig getLoadConfig() {
157: if (useLastConfig && loader.getLastConfig() != null) {
158: return loader.getLastConfig();
159: } else {
160: return new LoadConfig();
161: }
162: }
163:
164: protected void onFirst() {
165: LoadConfig config = getLoadConfig();
166: config.start = 0;
167: config.limit = pageSize;
168: loader.load(config);
169: }
170:
171: protected void onLast() {
172: int total = loader.getTotalLength();
173: int extra = total % pageSize;
174: int lastStart = extra > 0 ? (total - extra) : total - pageSize;
175: LoadConfig config = getLoadConfig();
176: config.start = lastStart;
177: config.limit = pageSize;
178: loader.load(config);
179: }
180:
181: protected void onLoad(LoadEvent event) {
182: LoadResult result = event.result;
183: cursor = result.cursor;
184: int total = loader.getTotalLength();
185: activePage = (int) Math.ceil((double) (cursor + pageSize)
186: / pageSize);
187: pageText.setText(String.valueOf((int) activePage));
188: pages = total < pageSize ? 1 : (int) Math.ceil((double) total
189: / pageSize);
190: afterText.setText(MyGWT.MESSAGES.afterPage((int) pages));
191: first.setEnabled(activePage != 1);
192: prev.setEnabled(activePage != 1);
193: next.setEnabled(activePage != pages);
194: last.setEnabled(activePage != pages);
195: int temp = activePage == pages ? total : cursor + pageSize;
196: String msg = MyGWT.MESSAGES.displaying(cursor + 1, (int) temp,
197: (int) total);
198: if (total == 0) {
199: msg = MyGWT.MESSAGES.emptyMsg();
200: }
201: displayText.setText(msg);
202: }
203:
204: protected void onNext() {
205: LoadConfig config = getLoadConfig();
206: config.start = cursor + pageSize;
207: config.limit = pageSize;
208: loader.load(config);
209: }
210:
211: protected void onPageChange() {
212: String value = pageText.getText();
213: if (value.equals("") || !Util.isInteger(value)) {
214: pageText.setText(String.valueOf((int) activePage));
215: return;
216: }
217: int p = Integer.parseInt(value);
218: setActivePage(p);
219: }
220:
221: protected void onPrevious() {
222: LoadConfig config = getLoadConfig();
223: config.start = Math.max(0, cursor - pageSize);
224: config.limit = pageSize;
225: loader.load(config);
226: }
227:
228: protected void onRefresh() {
229: LoadConfig config = getLoadConfig();
230: config.start = cursor;
231: config.limit = pageSize;
232: loader.load(config);
233: }
234:
235: protected void onRender() {
236: panel = new HorizontalPanel();
237: panel.setSpacing(3);
238: panel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
239: setElement(panel.getElement());
240: setStyleName(baseStyle);
241:
242: first = new ToolItem();
243: first.setIconStyle("page-first");
244: first.setToolTip(MyGWT.MESSAGES.firstPage());
245: first.addSelectionListener(new SelectionListener() {
246: public void widgetSelected(BaseEvent be) {
247: onFirst();
248: }
249: });
250:
251: prev = new ToolItem();
252: prev.setIconStyle("page-prev");
253: prev.setToolTip(MyGWT.MESSAGES.previousPage());
254: prev.addSelectionListener(new SelectionListener() {
255: public void widgetSelected(BaseEvent be) {
256: onPrevious();
257: }
258: });
259:
260: next = new ToolItem();
261: next.setIconStyle("page-next");
262: next.setToolTip(MyGWT.MESSAGES.nextPage());
263: next.addSelectionListener(new SelectionListener() {
264: public void widgetSelected(BaseEvent be) {
265: onNext();
266: }
267: });
268:
269: last = new ToolItem();
270: last.setIconStyle("page-last");
271: last.setToolTip(MyGWT.MESSAGES.lastPage());
272: last.addSelectionListener(new SelectionListener() {
273: public void widgetSelected(BaseEvent be) {
274: onLast();
275: }
276: });
277:
278: refresh = new ToolItem();
279: refresh.setIconStyle("icon-done");
280: refresh.setToolTip(MyGWT.MESSAGES.refresh());
281: refresh.addSelectionListener(new SelectionListener() {
282: public void widgetSelected(BaseEvent be) {
283: onRefresh();
284: }
285: });
286:
287: Label beforePage = new Label(MyGWT.MESSAGES.beforePage());
288: beforePage.setStyleName("my-paging-text");
289: afterText = new Label();
290: afterText.setStyleName("my-paging-text");
291: pageText = new TextBox();
292: if (!MyGWT.isGecko && !MyGWT.isSafari) {
293: pageText.addKeyboardListener(new KeyboardListenerAdapter() {
294: public void onKeyDown(Widget sender, char keyCode,
295: int modifiers) {
296: if (keyCode == KeyboardListener.KEY_ENTER) {
297: onPageChange();
298: }
299: }
300: });
301: }
302: pageText.setWidth("30px");
303: pageText.addChangeListener(new ChangeListener() {
304: public void onChange(Widget sender) {
305: onPageChange();
306: }
307: });
308:
309: displayText = new Label();
310: displayText.setStyleName("my-paging-display");
311:
312: panel.add(first);
313: panel.add(prev);
314: panel.add(new ToolItem(Style.SEPARATOR));
315: panel.add(beforePage);
316: panel.add(pageText);
317: panel.add(afterText);
318: panel.add(new ToolItem(Style.SEPARATOR));
319: panel.add(next);
320: panel.add(last);
321: panel.add(new ToolItem(Style.SEPARATOR));
322: panel.add(refresh);
323: panel.add(displayText);
324: panel.setCellWidth(displayText, "100%");
325: panel.setCellHorizontalAlignment(displayText,
326: HorizontalPanel.ALIGN_RIGHT);
327: }
328:
329: }
|