com.dawg6.gwt.client.widgets.SortableTable.java Source code

Java tutorial

Introduction

Here is the source code for com.dawg6.gwt.client.widgets.SortableTable.java

Source

/*******************************************************************************
 * Copyright (c) 2014, 2015 Scott Clarke (scott@dawg6.com).
 *
 * This file is part of Dawg6's Common GWT Libary.
 *
 * Dawg6's Common GWT Libary is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dawg6's Common GWT Libary is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package com.dawg6.gwt.client.widgets;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlexTable;

public class SortableTable<T> extends FlexTable {

    protected List<T> data;
    protected int numHeaderRows;
    protected Renderer<T> renderer;

    public enum Direction {
        Forward, Reverse;

        public Direction change() {
            return Direction.values()[1 - this.ordinal()];
        }
    }

    public static class Column<T> {
        String title;
        String style;
        Comparator<T> comparator;

        public Column(String title, String style, Comparator<T> comparator) {

            this.title = title;
            this.style = style;
            this.comparator = comparator;
        }
    }

    public interface Renderer<T> {
        void renderHeader(SortableTable<T> table);

        void beforeTable(SortableTable<T> table);

        void renderRow(SortableTable<T> table, int row, T item);

        void afterTable(SortableTable<T> table);

    }

    public static abstract class DefaultRenderer<T> implements Renderer<T> {

        private final List<Column<T>> columns;
        private Column<T> selected;
        private Direction direction;

        public DefaultRenderer(Collection<Column<T>> columns) {
            this(columns, 0);
        }

        public DefaultRenderer(Collection<Column<T>> columns, int selected) {
            this(columns, selected, Direction.Forward);
        }

        public DefaultRenderer(Collection<Column<T>> columns, int selected, Direction direction) {
            this.columns = new ArrayList<Column<T>>(columns);

            this.selected = this.columns.get(selected);
            this.direction = direction;
        }

        @Override
        public void beforeTable(SortableTable<T> table) {

        }

        @Override
        public void afterTable(SortableTable<T> table) {

        }

        @Override
        public void renderHeader(final SortableTable<T> table) {

            int i = 0;

            for (Column<T> c : columns) {
                final Column<T> col = c;
                final Comparator<T> comp = col.comparator;
                String style = col.style;
                String title = col.title;

                if (comp == null) {
                    StyledLabel label = new StyledLabel(title, false, style);
                    table.setWidget(0, i, label);
                } else {
                    Anchor anchor = new Anchor();
                    anchor.setText(title);
                    anchor.setHref("javascript:void(0)");
                    anchor.setTitle("Click to Sort/Reverse");
                    table.setWidget(0, i, anchor);

                    if (style != null)
                        anchor.addStyleName(style);

                    anchor.addClickHandler(new ClickHandler() {

                        @Override
                        public void onClick(ClickEvent event) {
                            sort(table, col, comp);

                        }
                    });
                }

                i++;
            }
        }

        protected void sort(SortableTable<T> table, Column<T> col, final Comparator<T> comp) {
            if ((this.selected != null) && (col == this.selected)) {
                this.direction = this.direction.change();
            } else {
                this.selected = col;
                this.direction = Direction.Forward;
            }

            if (this.direction == Direction.Forward)
                table.sortData(comp);
            else
                table.sortData(new Comparator<T>() {

                    @Override
                    public int compare(T o1, T o2) {
                        return -comp.compare(o1, o2);
                    }
                });
        }
    }

    public SortableTable(Renderer<T> renderer) {
        this(renderer, new Vector<T>());
    }

    public SortableTable(Renderer<T> renderer, List<T> data) {
        this.renderer = renderer;
        renderer.renderHeader(this);
        this.numHeaderRows = this.getRowCount();

        setData(data);
    }

    public void setData(List<T> data) {
        if ((data != null) && !data.isEmpty())
            this.data = new Vector<T>(data);
        else
            this.data = new Vector<T>();
    }

    public List<T> getData() {
        if ((data != null) && !data.isEmpty())
            return Collections.unmodifiableList(data);
        else
            return new Vector<T>();
    }

    public void clearTable() {
        while (this.getRowCount() > numHeaderRows)
            this.removeRow(numHeaderRows);
    }

    public void fillTable() {
        clearTable();

        int row = numHeaderRows;

        renderer.beforeTable(this);

        if ((data != null) && !data.isEmpty()) {
            for (T item : data) {
                renderer.renderRow(this, row++, item);
            }
        }

        renderer.afterTable(this);
    }

    public void sortData(Comparator<? super T> comparator) {
        if ((data != null) && !data.isEmpty()) {
            Collections.sort(data, comparator);
        }

        fillTable();
    }
}