| package org.tepi.filtertable.paged; |
| |
| import java.io.Serializable; |
| import java.text.NumberFormat; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Locale; |
| |
| import org.tepi.filtertable.FilterTable; |
| |
| import com.vaadin.data.Container; |
| import com.vaadin.data.util.converter.StringToIntegerConverter; |
| import com.vaadin.shared.ui.label.ContentMode; |
| import com.vaadin.ui.Alignment; |
| import com.vaadin.ui.Button; |
| import com.vaadin.ui.Button.ClickEvent; |
| import com.vaadin.ui.Button.ClickListener; |
| import com.vaadin.ui.ComboBox; |
| import com.vaadin.ui.HorizontalLayout; |
| import com.vaadin.ui.Label; |
| import com.vaadin.ui.TextField; |
| import com.vaadin.ui.UI; |
| import com.vaadin.ui.themes.Reindeer; |
| |
| @SuppressWarnings("serial") |
| public class PagedFilterTable<T extends Container.Indexed & Container.Filterable & Container.ItemSetChangeNotifier> |
| extends FilterTable { |
| |
| public interface PageChangeListener extends Serializable { |
| public void pageChanged(PagedTableChangeEvent event); |
| } |
| |
| private List<PageChangeListener> listeners = null; |
| |
| private PagedFilterTableContainer<T> container; |
| |
| public PagedFilterTable() { |
| this(null); |
| } |
| |
| public PagedFilterTable(String caption) { |
| super(caption); |
| setPageLength(25); |
| addStyleName("pagedtable"); |
| } |
| |
| public HorizontalLayout createControls(PagedFilterControlConfig config) { |
| Label itemsPerPageLabel = new Label(config.getItemsPerPage(), |
| ContentMode.HTML); |
| itemsPerPageLabel.setSizeUndefined(); |
| final ComboBox itemsPerPageSelect = new ComboBox(); |
| |
| for (Integer i : config.getPageLengths()) { |
| itemsPerPageSelect.addItem(i); |
| itemsPerPageSelect.setItemCaption(i, String.valueOf(i)); |
| } |
| itemsPerPageSelect.setImmediate(true); |
| itemsPerPageSelect.setNullSelectionAllowed(false); |
| itemsPerPageSelect.setWidth(null); |
| itemsPerPageSelect.addValueChangeListener(new ValueChangeListener() { |
| private static final long serialVersionUID = -2255853716069800092L; |
| |
| @Override |
| public void valueChange( |
| com.vaadin.data.Property.ValueChangeEvent event) { |
| setPageLength((Integer) event.getProperty().getValue()); |
| } |
| }); |
| if (itemsPerPageSelect.containsId(getPageLength())) { |
| itemsPerPageSelect.select(getPageLength()); |
| } else { |
| itemsPerPageSelect.select(itemsPerPageSelect.getItemIds() |
| .iterator().next()); |
| } |
| Label pageLabel = new Label(config.getPage(), ContentMode.HTML); |
| final TextField currentPageTextField = new TextField(); |
| currentPageTextField.setValue(String.valueOf(getCurrentPage())); |
| currentPageTextField.setConverter(new StringToIntegerConverter() { |
| @Override |
| protected NumberFormat getFormat(Locale locale) { |
| NumberFormat result = super.getFormat(UI.getCurrent() |
| .getLocale()); |
| result.setGroupingUsed(false); |
| return result; |
| } |
| }); |
| Label separatorLabel = new Label(" / ", ContentMode.HTML); |
| final Label totalPagesLabel = new Label( |
| String.valueOf(getTotalAmountOfPages()), ContentMode.HTML); |
| currentPageTextField.setStyleName(Reindeer.TEXTFIELD_SMALL); |
| currentPageTextField.setImmediate(true); |
| currentPageTextField.addValueChangeListener(new ValueChangeListener() { |
| private static final long serialVersionUID = -2255853716069800092L; |
| |
| @Override |
| public void valueChange( |
| com.vaadin.data.Property.ValueChangeEvent event) { |
| if (currentPageTextField.isValid() |
| && currentPageTextField.getValue() != null) { |
| int page = Integer.valueOf(String |
| .valueOf(currentPageTextField.getValue())); |
| setCurrentPage(page); |
| } |
| } |
| }); |
| pageLabel.setWidth(null); |
| currentPageTextField.setColumns(3); |
| separatorLabel.setWidth(null); |
| totalPagesLabel.setWidth(null); |
| |
| HorizontalLayout controlBar = new HorizontalLayout(); |
| HorizontalLayout pageSize = new HorizontalLayout(); |
| HorizontalLayout pageManagement = new HorizontalLayout(); |
| final Button first = new Button(config.getFirst(), new ClickListener() { |
| private static final long serialVersionUID = -355520120491283992L; |
| |
| @Override |
| public void buttonClick(ClickEvent event) { |
| setCurrentPage(0); |
| } |
| }); |
| final Button previous = new Button(config.getPrevious(), |
| new ClickListener() { |
| private static final long serialVersionUID = -355520120491283992L; |
| |
| @Override |
| public void buttonClick(ClickEvent event) { |
| previousPage(); |
| } |
| }); |
| final Button next = new Button(config.getNext(), new ClickListener() { |
| private static final long serialVersionUID = -1927138212640638452L; |
| |
| @Override |
| public void buttonClick(ClickEvent event) { |
| nextPage(); |
| } |
| }); |
| final Button last = new Button(config.getLast(), new ClickListener() { |
| private static final long serialVersionUID = -355520120491283992L; |
| |
| @Override |
| public void buttonClick(ClickEvent event) { |
| setCurrentPage(getTotalAmountOfPages()); |
| } |
| }); |
| first.setStyleName(Reindeer.BUTTON_LINK); |
| previous.setStyleName(Reindeer.BUTTON_LINK); |
| next.setStyleName(Reindeer.BUTTON_LINK); |
| last.setStyleName(Reindeer.BUTTON_LINK); |
| |
| itemsPerPageLabel.addStyleName("pagedtable-itemsperpagecaption"); |
| itemsPerPageSelect.addStyleName("pagedtable-itemsperpagecombobox"); |
| pageLabel.addStyleName("pagedtable-pagecaption"); |
| currentPageTextField.addStyleName("pagedtable-pagefield"); |
| separatorLabel.addStyleName("pagedtable-separator"); |
| totalPagesLabel.addStyleName("pagedtable-total"); |
| first.addStyleName("pagedtable-first"); |
| previous.addStyleName("pagedtable-previous"); |
| next.addStyleName("pagedtable-next"); |
| last.addStyleName("pagedtable-last"); |
| |
| itemsPerPageLabel.addStyleName("pagedtable-label"); |
| itemsPerPageSelect.addStyleName("pagedtable-combobox"); |
| pageLabel.addStyleName("pagedtable-label"); |
| currentPageTextField.addStyleName("pagedtable-label"); |
| separatorLabel.addStyleName("pagedtable-label"); |
| totalPagesLabel.addStyleName("pagedtable-label"); |
| first.addStyleName("pagedtable-button"); |
| previous.addStyleName("pagedtable-button"); |
| next.addStyleName("pagedtable-button"); |
| last.addStyleName("pagedtable-button"); |
| |
| pageSize.addComponent(itemsPerPageLabel); |
| pageSize.addComponent(itemsPerPageSelect); |
| pageSize.setComponentAlignment(itemsPerPageLabel, Alignment.MIDDLE_LEFT); |
| pageSize.setComponentAlignment(itemsPerPageSelect, |
| Alignment.MIDDLE_LEFT); |
| pageSize.setSpacing(true); |
| pageManagement.addComponent(first); |
| pageManagement.addComponent(previous); |
| pageManagement.addComponent(pageLabel); |
| pageManagement.addComponent(currentPageTextField); |
| pageManagement.addComponent(separatorLabel); |
| pageManagement.addComponent(totalPagesLabel); |
| pageManagement.addComponent(next); |
| pageManagement.addComponent(last); |
| pageManagement.setComponentAlignment(first, Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(previous, Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(pageLabel, Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(currentPageTextField, |
| Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(separatorLabel, |
| Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(totalPagesLabel, |
| Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(next, Alignment.MIDDLE_LEFT); |
| pageManagement.setComponentAlignment(last, Alignment.MIDDLE_LEFT); |
| pageManagement.setWidth(null); |
| pageManagement.setSpacing(true); |
| controlBar.addComponent(pageSize); |
| controlBar.addComponent(pageManagement); |
| controlBar.setComponentAlignment(pageManagement, |
| Alignment.MIDDLE_CENTER); |
| controlBar.setWidth(100, Unit.PERCENTAGE); |
| controlBar.setExpandRatio(pageSize, 1); |
| |
| if (container != null) { |
| first.setEnabled(container.getStartIndex() > 0); |
| previous.setEnabled(container.getStartIndex() > 0); |
| next.setEnabled(container.getStartIndex() < container.getRealSize() |
| - getPageLength()); |
| last.setEnabled(container.getStartIndex() < container.getRealSize() |
| - getPageLength()); |
| } |
| |
| addListener(new PageChangeListener() { |
| private boolean inMiddleOfValueChange; |
| |
| @Override |
| public void pageChanged(PagedTableChangeEvent event) { |
| if (!inMiddleOfValueChange) { |
| inMiddleOfValueChange = true; |
| first.setEnabled(container.getStartIndex() > 0); |
| previous.setEnabled(container.getStartIndex() > 0); |
| next.setEnabled(container.getStartIndex() < container |
| .getRealSize() - getPageLength()); |
| last.setEnabled(container.getStartIndex() < container |
| .getRealSize() - getPageLength()); |
| currentPageTextField.setValue(String |
| .valueOf(getCurrentPage())); |
| totalPagesLabel.setValue(Integer |
| .toString(getTotalAmountOfPages())); |
| itemsPerPageSelect |
| .setValue(getPageLength()); |
| inMiddleOfValueChange = false; |
| } |
| } |
| }); |
| return controlBar; |
| } |
| |
| @Override |
| public PagedFilterTableContainer<T> getContainerDataSource() { |
| return container; |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public void setContainerDataSource(Container newDataSource) { |
| if (!(newDataSource instanceof Container.Indexed) |
| || !(newDataSource instanceof Container.Filterable)) { |
| throw new IllegalArgumentException( |
| "PagedFilteringTable can only use containers that implement Container.Indexed AND Container.Filterable"); |
| } |
| PagedFilterTableContainer<T> pagedFilteringTableContainer = new PagedFilterTableContainer<T>( |
| (T) newDataSource); |
| pagedFilteringTableContainer.setPageLength(getPageLength()); |
| container = pagedFilteringTableContainer; |
| super.setContainerDataSource(pagedFilteringTableContainer); |
| firePagedChangedEvent(); |
| } |
| |
| private void setPageFirstIndex(int firstIndex) { |
| if (container != null) { |
| if (firstIndex <= 0) { |
| firstIndex = 0; |
| } |
| if (firstIndex > container.getRealSize() - 1) { |
| int size = container.getRealSize() - 1; |
| int pages = 0; |
| if (getPageLength() != 0) { |
| pages = (int) Math.floor(0.0 + size / getPageLength()); |
| } |
| firstIndex = pages * getPageLength(); |
| } |
| container.setStartIndex(firstIndex); |
| containerItemSetChange(new Container.ItemSetChangeEvent() { |
| private static final long serialVersionUID = -5083660879306951876L; |
| |
| @Override |
| public Container getContainer() { |
| return container; |
| } |
| }); |
| if (alwaysRecalculateColumnWidths) { |
| for (Object columnId : container.getContainerPropertyIds()) { |
| setColumnWidth(columnId, -1); |
| } |
| } |
| firePagedChangedEvent(); |
| } |
| } |
| |
| private void firePagedChangedEvent() { |
| if (listeners != null) { |
| PagedTableChangeEvent event = new PagedTableChangeEvent(this); |
| for (PageChangeListener listener : listeners) { |
| listener.pageChanged(event); |
| } |
| } |
| } |
| |
| @Override |
| public void setPageLength(int pageLength) { |
| if (pageLength >= 0 && getPageLength() != pageLength) { |
| container.setPageLength(pageLength); |
| super.setPageLength(pageLength); |
| firePagedChangedEvent(); |
| } |
| } |
| |
| public void nextPage() { |
| setPageFirstIndex(container.getStartIndex() + getPageLength()); |
| } |
| |
| public void previousPage() { |
| setPageFirstIndex(container.getStartIndex() - getPageLength()); |
| } |
| |
| public int getCurrentPage() { |
| double pageLength = getPageLength(); |
| int page = (int) Math.floor(container.getStartIndex() / pageLength) + 1; |
| if (page < 1) { |
| page = 1; |
| } |
| return page; |
| } |
| |
| public void setCurrentPage(int page) { |
| int newIndex = (page - 1) * getPageLength(); |
| if (newIndex < 0) { |
| newIndex = 0; |
| } |
| setPageFirstIndex(newIndex); |
| } |
| |
| public int getTotalAmountOfPages() { |
| int size = container.getContainer().size(); |
| double pageLength = getPageLength(); |
| int pageCount = (int) Math.ceil(size / pageLength); |
| if (pageCount < 1) { |
| pageCount = 1; |
| } |
| return pageCount; |
| } |
| |
| public void addListener(PageChangeListener listener) { |
| if (listeners == null) { |
| listeners = new ArrayList<PageChangeListener>(); |
| } |
| listeners.add(listener); |
| } |
| |
| public void removeListener(PageChangeListener listener) { |
| if (listeners == null) { |
| listeners = new ArrayList<PageChangeListener>(); |
| } |
| listeners.remove(listener); |
| } |
| |
| @Override |
| public void resetFilters() { |
| super.resetFilters(); |
| setCurrentPage(1); |
| } |
| } |