Package org.gwtlib.client.table.ui

Source Code of org.gwtlib.client.table.ui.PagingBar

/*
* Copyright 2008 Sander Berents
*
* Licensed 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.gwtlib.client.table.ui;

import org.gwtlib.client.ui.Messages;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
* Paging bar.
*
* CSS Style Rules:
* <ul>
* <li>.gwtlib-PagingBar { the paging bar itself }</li>
* <li>.gwtlib-PagingBar-position { current position section }</li>
* <li>.gwtlib-PagingBar-browser { browser secion }</li>
* <li>.gwtlib-PagingBar-goto { go to page selection section }</li>
* <li>.gwtlib-PagingBar-gotoButton { go to button of page selection section }</li>
* <li>.gwtlib-PagingBar-gotoButton-up { go to button of page selection section }</li>
* <li>.gwtlib-PagingBar-gotoButton-up-disabled { go to button of page selection section in disabled state }</li>
* <li>.gwtlib-PagingBar-pagesize { page size section }</li>
* <li>.gwtlib-PagingBar-browser-first { first page button }</li>
* <li>.gwtlib-PagingBar-browser-first-up { first page button in enabled state }</li>
* <li>.gwtlib-PagingBar-browser-first-up-disabled { first page button in disabled state }</li>
* <li>.gwtlib-PagingBar-browser-prev { previous page button }</li>
* <li>.gwtlib-PagingBar-browser-prev-up { previous page button in enabled state }</li>
* <li>.gwtlib-PagingBar-browser-prev-up-disabled { previous page button in disabled state }</li>
* <li>.gwtlib-PagingBar-browser-next { next page button }</li>
* <li>.gwtlib-PagingBar-browser-next-up { next page button in enabled state }</li>
* <li>.gwtlib-PagingBar-browser-next-up-disabled { next page button in disabled state }</li>
* <li>.gwtlib-PagingBar-browser-last { last page button }</li>
* <li>.gwtlib-PagingBar-browser-last-up { last page button in enabled state }</li>
* <li>.gwtlib-PagingBar-browser-last-up-disabled { last page button in disabled state }</li>
* <li>.gwtlib-PagingBar-browser-page { currently selected page }</li>
* <li>.gwtlib-PagingBar-browser-page-enabled { other selectable page }</li>
* <li>.gwtlib-PagingBar-loading { data loading status }</li>
* <li>.gwtlib-PagingBar-loading-up { data loading status }</li>
* <li>.gwtlib-PagingBar-loading-up-disabled { data loading status (finished loading) }</li>
* </ul>
*
* @author Sander Berents
*/
public class PagingBar extends Composite implements HasValueChangeHandlers<Integer> {
  private static final String STYLE             = "gwtlib-PagingBar";
  private static final String STYLE_POSITION    = "gwtlib-PagingBar-position";
  private static final String STYLE_BROWSER     = "gwtlib-PagingBar-browser";
  private static final String STYLE_GOTO        = "gwtlib-PagingBar-goto";
  private static final String STYLE_GOTO_BUTTON = "gwtlib-PagingBar-gotoButton";
  private static final String STYLE_PAGESIZE    = "gwtlib-PagingBar-pagesize";
  private static final String STYLE_PAGE        = "gwtlib-PagingBar-browser-page";
  private static final String STYLE_LOADING     = "gwtlib-PagingBar-loading";
  private static final String STYLE_ENABLED     = "enabled";

  private static final String[] STYLES_BROWSER  = {
    "gwtlib-PagingBar-browser-first", "gwtlib-PagingBar-browser-prev",
    "gwtlib-PagingBar-browser-next", "gwtlib-PagingBar-browser-last"
  };

  private static final int FIRST = 0;
  private static final int PREV  = 1;
  private static final int NEXT  = 2;
  private static final int LAST  = 3;

  private static final int DEFAULT_LIMIT = 60000;

  private int _page; // Zero based current page
  private int _size; // Total number of results
  private int _limit = DEFAULT_LIMIT;
  private int _pageSize;
  private int[] _pageSizes;
  private int _pages;    // Number of pages, computed from size/limit/pageSize
  private boolean _loading;

  private Widget _positionWidget;
  private Widget _loadingWidget;
  private Widget _browserWidget;
  private Widget _gotoWidget;
  private Widget _pageSizesWidget;
  protected Messages _messages = (Messages)GWT.create(Messages.class);

  public PagingBar(int size, int pageSize) {
    this(0, size, pageSize, null);
  }

  @Deprecated
  public PagingBar(Messages messages, int size, int pageSize) {
    this(0, size, pageSize, null);
    _messages = messages;
  }

  public PagingBar(int page, int size, int pageSize, int[] pageSizes) {
    _page = page;
    _size = size;
    _pageSize = pageSize;
    _pageSizes = pageSizes;
    _pages = computeNumPages();

    // Create widgets in protected methods to provide customization hooks
    _positionWidget = createPositionWidget();
    if(_positionWidget != null) updatePositionWidget(_positionWidget);
    _loadingWidget = createLoadingWidget();
    if(_loadingWidget != null) updateLoadingWidget(_loadingWidget);
    _browserWidget = createBrowserWidget();
    if(_browserWidget != null) updateBrowserWidget(_browserWidget);
    _gotoWidget = createGotoWidget();
    if(_gotoWidget != null) updateGotoWidget(_gotoWidget);
    _pageSizesWidget = createPageSizeWidget();
    if(_pageSizesWidget != null) updatePageSizeWidget(_pageSizesWidget);
    // Combine all the above created widgets
    Widget panel = create();
    initWidget(panel);
    setStyleName(STYLE);
  }

  public PagingBar(Messages messages, int page, int size, int pageSize, int[] pageSizes) {
    this(page, size, pageSize, pageSizes);
    _messages = messages;
  }

  protected Widget create() {
    HorizontalPanel panel = new HorizontalPanel();
    panel.setSpacing(0);
    panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    if(_positionWidget != null) panel.add(_positionWidget);
    if(_loadingWidget != null) panel.add(_loadingWidget);
    if(_browserWidget != null) panel.add(_browserWidget);
    panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
    if(_gotoWidget != null) panel.add(_gotoWidget);
    if(_pageSizesWidget != null) panel.add(_pageSizesWidget);
    return panel;
  }

  protected Widget createPositionWidget() {
    Label label = new Label();
    label.setStylePrimaryName(STYLE_POSITION);
    return label;
  }

  protected void updatePositionWidget(Widget widget) {
    int pos = getPosition();
    int pos1 = pos + 1;
    String s;

    if(_pageSize > 1) {
      int pos2 = pos + _pageSize > _size ? _size : pos + _pageSize;
      if(_size > _limit) {
        s = _messages.rangelimit(pos1, pos2, _size, _limit);
      } else {
        s = _messages.range(pos1, pos2, _size);
      }
    } else {
      if(_size > _limit) {
        s = _messages.poslimit(pos1, _size, _limit);
      } else {
        s = _messages.pos(pos1, _size);
      }
    }
    ((Label)widget).setText(s);
    widget.setVisible(_size > 0);
  }

  protected Widget createLoadingWidget() {
    PushButton loading = new PushButton();
    loading.setStylePrimaryName(STYLE_LOADING);
    return loading;
  }

  protected void updateLoadingWidget(Widget widget) {
    ((PushButton)widget).setEnabled(_loading);
  }

  protected Widget createBrowserWidget() {
    HorizontalPanel panel = new HorizontalPanel();
    panel.setStylePrimaryName(STYLE_BROWSER);
    return panel;
  }

  protected void updateBrowserWidget(Widget widget) {
    HorizontalPanel panel = (HorizontalPanel)widget;
    int minpage = _page > 2 ? _page - 2 : 0;
    int maxpage = minpage + 4;
    if(maxpage >= _pages) {
      maxpage = _pages - 1;
      minpage = _pages > 4 ? _pages - 4 : 0;
    }
    panel.clear();
    panel.add(createBrowserItemWidget(FIRST, _page > 0));
    panel.add(createBrowserItemWidget(PREV, _page > 0));
    for(int i = minpage; i <= maxpage; ++i) {
      panel.add(createBrowserItemWidget(String.valueOf(i + 1), i != _page));
    }
    panel.add(createBrowserItemWidget(NEXT, _page < _pages - 1));
    panel.add(createBrowserItemWidget(LAST, _page < _pages - 1));
    widget.setVisible(_size > 0);
  }

  protected Widget createBrowserItemWidget(final int type, boolean enabled) {
    final ClickHandler clickHandler = new ClickHandler() {
      public void onClick(ClickEvent event) {
        switch(type) {
          case FIRST:
            _page = 0;
            break;
          case PREV:
            --_page;
            break;
          case NEXT:
            ++_page;
            break;
          case LAST:
            _page = _pages - 1;
            break;
        }
        fireChange();
      }
    };
    PushButton button = new PushButton();
    button.setStylePrimaryName(STYLES_BROWSER[type]);
    button.setEnabled(enabled);
    if(enabled) button.addClickHandler(clickHandler);
    return button;
  }

  protected Widget createBrowserItemWidget(String text, boolean enabled) {
    Label label = new Label(text);
    label.setStylePrimaryName(STYLE_PAGE);
    if(enabled) {
      label.addStyleDependentName(STYLE_ENABLED);
      label.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
          String text = ((Label) event.getSource()).getText();
          _page = Integer.parseInt(text) - 1;
          fireChange();
        }
      });
    }
    return label;
  }

  protected Widget createGotoWidget() {
    final TextBox gotoPage = new TextBox();
    int maxlen = String.valueOf(computeNumPages()).length();
    gotoPage.setMaxLength(maxlen);
    gotoPage.setVisibleLength(maxlen);
    final PushButton go = new PushButton();
    go.setStylePrimaryName(STYLE_GOTO_BUTTON);
    go.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        setPage(Integer.parseInt(gotoPage.getText()) - 1);
        gotoPage.setText("");
        go.setEnabled(false);
        fireChange();
      }
    });
    go.setEnabled(false);
    gotoPage.addKeyDownHandler(new KeyDownHandler() {
      public void onKeyDown(final KeyDownEvent event) {
        final int keyCode = event.getNativeKeyCode();
        DeferredCommand.addCommand(new Command() {
          public void execute() {
            int page = -1;
            try {
              page = Integer.parseInt(gotoPage.getText()) - 1;
            } catch(NumberFormatException e) {
            }
            go.setEnabled(page >= 0 && page < computeNumPages());
            if(keyCode == KeyCodes.KEY_ENTER && go.isEnabled()) {
              setPage(Integer.parseInt(gotoPage.getText()) - 1);
              gotoPage.setText("");
              go.setEnabled(false);
              fireChange();
            }
          }
        });
      }
    });

    HorizontalPanel panel = new HorizontalPanel();
    panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    panel.add(new HTML(_messages.go()));
    panel.add(gotoPage);
    panel.add(go);
    panel.setStylePrimaryName(STYLE_GOTO);
    return panel;
  }

  protected void updateGotoWidget(Widget widget) {
    widget.setVisible(computeNumPages() > 1);
    // Update allowed number of characters in the goto page textbox in case page size has changed (Yuck!)
    if(widget instanceof HorizontalPanel) {
      HorizontalPanel panel = (HorizontalPanel)widget;
      if(panel.getWidgetCount() == 3 && panel.getWidget(1) instanceof TextBox) {
        TextBox gotoPage = (TextBox)panel.getWidget(1);
        int maxlen = String.valueOf(computeNumPages()).length();
        gotoPage.setMaxLength(maxlen);
        gotoPage.setVisibleLength(maxlen);
      }
    }
  }

  protected Widget createPageSizeWidget() {
    HorizontalPanel panel = new HorizontalPanel();
    panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    panel.add(new HTML(_messages.pagesize1()));
    panel.add(new ListBox());
    panel.add(new HTML(_messages.pagesize2()));
    panel.setStylePrimaryName(STYLE_PAGESIZE);
    return panel;
  }

  protected void updatePageSizeWidget(Widget widget) {
    if(_pageSizes != null) {
      final ListBox sizes = (ListBox)((HorizontalPanel)_pageSizesWidget).getWidget(1);
      sizes.clear();
      for(int i = 0; i < _pageSizes.length; ++i) {
        sizes.addItem(String.valueOf(_pageSizes[i]));
        if(_pageSize == _pageSizes[i]) sizes.setSelectedIndex(i);
      }
      sizes.addChangeHandler(new ChangeHandler() {
        public void onChange(ChangeEvent event) {
          int i = sizes.getSelectedIndex();
          if(i >= 0) {
            setPageSize(Integer.parseInt(sizes.getItemText(i)));
            setPage(0);
            fireChange();
          }
        }
      });
    }
    widget.setVisible(_size > 0 && _pageSizes != null && _pageSizes.length > 1);
  }

  /**
   * Returns the offset of the first item.
   * @return Zero based offset.
   */
  public int getPosition() {
    int pos = _page * _pageSize;
    pos = Math.min(pos, getLimitedSize() - (_size % _pageSize));
    return pos < 0 ? 0 : pos;
  }

  /**
   * Sets the page number
   * @param page
   */
  public void setPage(int page) {
    _page = page;
  }

  public int getPageSize() {
    return _pageSize;
  }

  /**
   * Sets the Page size (Records per page)
   * @param pageSize
   */
  public void setPageSize(int pageSize) {
    _pageSize = pageSize;
    _pages = computeNumPages();
    update();
  }

  /**
   * Sets the total size of items
   * @param size
   */
  public void setSize(int size) {
    _size = size;
    _pages = computeNumPages();
    update();
  }

  public int getSize() {
    return _size;
  }

  /**
   * Sets the limits for total number items and number of pages
   * @param limit
   */
  public void setLimit(int limit) {
    _limit = limit;
    _pages = computeNumPages();
  }

  /**
   * Sets loading status.
   * @param loading
   */
  public void setLoading(boolean loading) {
    _loading = loading;
    updateLoadingWidget(_loadingWidget);
  }

  /**
   * Updates the status of the PagingBar.
   */
  public void update() {
    if(_positionWidget != null) updatePositionWidget(_positionWidget);
    if(_browserWidget != null) {
      updateBrowserWidget(_browserWidget);
      _browserWidget.setVisible(computeNumPages() > 1);
    }
    if(_gotoWidget != null) updateGotoWidget(_gotoWidget);
    if(_pageSizesWidget != null) _pageSizesWidget.setVisible(_size > 0 && _pageSizes != null && _pageSizes.length > 1);
    setVisible(computeNumPages() > 0);
  }

  /**
   * The fireChange method is invoked when any click event or change event
   * occurs. It fires a change event for all listeners and updates the PagingBar.
   */
  protected void fireChange() {
    ValueChangeEvent.fire(this, getPosition());
    update();
  }

  @Override
  public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Integer> handler) {
    return this.addHandler(handler, ValueChangeEvent.getType());
  }

  /**
   * Returns the computed number of pages
   * @return Number of pages.
   */
  protected int computeNumPages() {
    return (getLimitedSize() + _pageSize - 1) / _pageSize;
  }

  /**
   * Returns the limit or number of items.
   */
  protected int getLimitedSize() {
    return _size > _limit ? _limit : _size;
  }
}
TOP

Related Classes of org.gwtlib.client.table.ui.PagingBar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.