/** * */ package org.gcube.portlets.user.geoportaldataentry.client.ui.table; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.gcube.portlets.user.geoportaldataentry.client.resource.CellTableResources; import com.github.gwtbootstrap.client.ui.CellTable; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.cellview.client.ColumnSortEvent; import com.google.gwt.user.cellview.client.ColumnSortEvent.AsyncHandler; import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo; import com.google.gwt.user.cellview.client.Header; import com.google.gwt.view.client.AbstractDataProvider; import com.google.gwt.view.client.AsyncDataProvider; import com.google.gwt.view.client.ListDataProvider; /** * The Class SortedCellTable. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Jun 15, 2021 * @param the generic type */ public class SortedCellTable extends CellTable { /** * To keep track of the currently sorted column */ private Column currentlySortedColumn; /** * Tells us which way to sort a column initially */ private Map, Boolean> defaultSortOrderMap = new HashMap, Boolean>(); /** * Comparators associated with their columns */ private Map, Comparator> comparators = new HashMap, Comparator>(); /** * Column to sort when the data provider's list is refreshed using * {@link SortedCellTable#setList(List)} */ private Column initialSortColumn; /** * Data provider we will attach to this table */ private AbstractDataProvider dataProvider; /** * Special column sorting handler that will allow us to do more controlled * sorting */ private ColumnSortEvent.Handler columnSortHandler; /** * Instantiates a new sorted cell table. * * @param pageSize the page size * @param dataProv the data prov */ public SortedCellTable(int pageSize, AbstractDataProvider dataProv) { super(pageSize, CellTableResources.INSTANCE); this.dataProvider = dataProv; if (this.dataProvider instanceof ListDataProvider) { ListDataProvider listDataProvider = (ListDataProvider) this.dataProvider; ListHandler listSortHandler = new ListHandler((listDataProvider).getList()) { @Override public void onColumnSort(ColumnSortEvent event) { @SuppressWarnings("unchecked") Column column = (Column) event.getColumn(); if (column == null) { return; } if (column.equals(currentlySortedColumn)) { // Default behavior super.onColumnSort(event); } else { // Initial sort; look up which direction we need final Comparator comparator = comparators.get(column); if (comparator == null) { return; } Boolean ascending = defaultSortOrderMap.get(column); if (ascending == null || ascending) { // Default behavior super.onColumnSort(event); } else { // Sort the column descending Collections.sort(getList(), new Comparator() { public int compare(T o1, T o2) { return -comparator.compare(o1, o2); } }); // Set the proper arrow in the header getColumnSortList().push(new ColumnSortInfo(column, false)); } currentlySortedColumn = column; } } @Override public void setComparator(Column column, Comparator comparator) { comparators.put(column, comparator); super.setComparator(column, comparator); } }; addColumnSortHandler(listSortHandler); columnSortHandler = listSortHandler; } else if (this.dataProvider instanceof AsyncDataProvider) { // AsyncDataProvider asyncDataProvider = ((AsyncDataProvider) // this.dataProvider); // asyncDataProvider.get AsyncHandler asyncSortHandler = new AsyncHandler(this) { @Override public void onColumnSort(ColumnSortEvent event) { @SuppressWarnings("unchecked") Column column = (Column) event.getColumn(); if (column == null) { return; } if (column.equals(currentlySortedColumn)) { // Default behavior super.onColumnSort(event); } else { // Initial sort; look up which direction we need final Comparator comparator = comparators.get(column); if (comparator == null) { return; } Boolean ascending = defaultSortOrderMap.get(column); if (ascending == null || ascending) { // Default behavior super.onColumnSort(event); } else { // Sort the column descending Collections.sort(getVisibleItems(), new Comparator() { public int compare(T o1, T o2) { return -comparator.compare(o1, o2); } }); // Set the proper arrow in the header getColumnSortList().push(new ColumnSortInfo(column, false)); } currentlySortedColumn = column; } } }; // addColumnSortHandler(asyncSortHandler); // columnSortHandler = asyncSortHandler; } } /** * Adds a column to the table and sets its sortable state. * * @param column the column * @param headerName the header name * @param sortable the sortable */ public void addColumn(Column column, String headerName, boolean sortable) { addColumn(column, headerName); column.setSortable(sortable); if (sortable) { defaultSortOrderMap.put(column, true); } } /** * Adds the column. * * @param column the column * @param headerName the header name */ /* * (non-Javadoc) * * @see * com.google.gwt.user.cellview.client.AbstractCellTable#addColumn(com.google. * gwt.user.cellview.client.Column, java.lang.String) */ public void addColumn(Column column, String headerName) { super.addColumn(column, headerName); } /** * Adds a column to the table and sets its sortable state. * * @param column the column * @param header the header * @param sortable the sortable */ public void addColumn(Column column, Header header, boolean sortable) { addColumn(column, header); column.setSortable(sortable); if (sortable) { defaultSortOrderMap.put(column, true); } } /** * Sets the column to sort when the data list is reset using * {@link SortedCellTable#setList(List)}. * * @param column the column */ public void setInitialSortColumn(Column column) { initialSortColumn = column; } /** * Set the comparator used to sort the specified column in ascending order. * * @param column the {@link Column} * @param comparator the {@link Comparator} to use for the {@link Column} */ public void setComparator(Column column, Comparator comparator) { comparators.put(column, comparator); } /** * Sets the sort order to use when this column is clicked and it was not * previously sorted. * * @param column the column * @param ascending the ascending */ public void setDefaultSortOrder(Column column, boolean ascending) { defaultSortOrderMap.put(column, ascending); } /** * Sets the table's data provider list and sorts the table based on the column * given in {@link SortedCellTable#setInitialSortColumn(Column)}. * * @param list the new list */ public void setList(List list) { if (dataProvider instanceof ListDataProvider) { List myData = ((ListDataProvider) dataProvider).getList(); myData.clear(); if (list != null) { /* * for (T t : list) { dataProvider.getList().add(t); } */ myData.addAll(list); } // Do a first-time sort based on which column was set in // setInitialSortColumn() if (initialSortColumn != null) { Collections.sort(myData, new Comparator() { @Override public int compare(T o1, T o2) { return (defaultSortOrderMap.get(initialSortColumn) ? 1 : -1) * comparators.get(initialSortColumn).compare(o1, o2); } }); // Might as well get the little arrow on the header to make it // official getColumnSortList() .push(new ColumnSortInfo(initialSortColumn, defaultSortOrderMap.get(initialSortColumn))); currentlySortedColumn = initialSortColumn; } } } /** * Gets the data provider. * * @return the data provider */ public AbstractDataProvider getDataProvider() { return dataProvider; } }