*/
package com.vaadin.ui;
-
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.shared.ui.grid.SectionState;
import com.vaadin.shared.util.SharedUtil;
+import com.vaadin.ui.Grid.FooterRow;
import com.vaadin.ui.components.grid.AbstractSelectionModel;
import com.vaadin.ui.components.grid.EditorComponentGenerator;
import com.vaadin.ui.components.grid.EditorImpl;
void columnResize(ColumnResizeEvent event);
}
+ /**
+ * Generates the sort orders when rows are sorted by a column.
+ *
+ * @see Column#setSortOrderProvider
+ *
+ * @since 8.0
+ * @author Vaadin Ltd
+ */
+ @FunctionalInterface
+ public interface SortOrderProvider extends
+ SerializableFunction<SortDirection, Stream<SortOrder<String>>> {
+
+ /**
+ * Generates the sort orders when rows are sorted by a column.
+ *
+ * @param sortDirection
+ * desired sort direction
+ *
+ * @return sort information
+ */
+ @Override
+ public Stream<SortOrder<String>> apply(SortDirection sortDirection);
+
+ }
+
/**
* An event that is fired when the columns are reordered.
*/
public void sort(String[] columnIds, SortDirection[] directions,
boolean isUserOriginated) {
assert columnIds.length == directions.length : "Column and sort direction counts don't match.";
- sortOrder.clear();
- if (columnIds.length == 0) {
- // Grid is not sorted anymore.
- getDataCommunicator()
- .setBackEndSorting(Collections.emptyList());
- getDataCommunicator().setInMemorySorting(null);
- return;
- }
+ List<SortOrder<Column<T, ?>>> list = new ArrayList<>(
+ directions.length);
for (int i = 0; i < columnIds.length; ++i) {
Column<T, ?> column = columnKeys.get(columnIds[i]);
- sortOrder.add(new SortOrder<>(column, directions[i]));
- }
-
- // Set sort orders
- // In-memory comparator
- BinaryOperator<SerializableComparator<T>> operator = (comparator1,
- comparator2) -> SerializableComparator.asInstance(
- (Comparator<T> & Serializable) comparator1
- .thenComparing(comparator2));
- SerializableComparator<T> comparator = sortOrder.stream()
- .map(order -> order.getSorted()
- .getComparator(order.getDirection()))
- .reduce((x, y) -> 0, operator);
- getDataCommunicator().setInMemorySorting(comparator);
-
- // Back-end sort properties
- List<SortOrder<String>> sortProperties = new ArrayList<>();
- sortOrder.stream()
- .map(order -> order.getSorted()
- .getSortOrder(order.getDirection()))
- .forEach(s -> s.forEach(sortProperties::add));
- getDataCommunicator().setBackEndSorting(sortProperties);
-
- // Close grid editor if it's open.
- if (getEditor().isOpen()) {
- getEditor().cancel();
+ list.add(new SortOrder<>(column, directions[i]));
}
+ setSortOrder(list, isUserOriginated);
}
@Override
*
* @return the new column
*/
- public Column<T, String> addColumn(
- ValueProvider<T, String> valueProvider) {
+ public Column<T, String> addColumn(ValueProvider<T, String> valueProvider) {
return addColumn(getGeneratedIdentifier(),
t -> String.valueOf(valueProvider.apply(t)),
new TextRenderer());
return getSelectionModel().addSelectionListener(listener);
}
+ /**
+ * Sort this Grid in ascending order by a specified column.
+ *
+ * @param column
+ * a column to sort against
+ *
+ */
+ public void sort(Column<T, ?> column) {
+ sort(column, SortDirection.ASCENDING);
+ }
+
+ /**
+ * Sort this Grid in user-specified {@link SortOrder} by a column.
+ *
+ * @param column
+ * a column to sort against
+ * @param direction
+ * a sort order value (ascending/descending)
+ *
+ */
+ public void sort(Column<T, ?> column, SortDirection direction) {
+ setSortOrder(
+ Collections.singletonList(new SortOrder<>(column, direction)));
+ }
+
+ /**
+ * Clear the current sort order, and re-sort the grid.
+ */
+ public void clearSortOrder() {
+ sortOrder.clear();
+ sort(false);
+ }
+
+ /**
+ * Sets the sort order to use.
+ *
+ * @param order
+ * a sort order list.
+ *
+ * @throws IllegalArgumentException
+ * if order is null
+ */
+ public void setSortOrder(List<SortOrder<Column<T, ?>>> order) {
+ setSortOrder(order, false);
+ }
+
+ /**
+ * Get the current sort order list.
+ *
+ * @return a sort order list
+ */
+ public List<SortOrder<Column<T, ?>>> getSortOrder() {
+ return Collections.unmodifiableList(sortOrder);
+ }
+
@Override
protected GridState getState() {
return getState(true);
return result;
}
- /**
- * Generates the sort orders when rows are sorted by a column.
- * @see Column#setSortOrderProvider
- *
- * @since 8.0
- * @author Vaadin Ltd
- */
- @FunctionalInterface
- public interface SortOrderProvider extends SerializableFunction<SortDirection, Stream<SortOrder<String>>> {
+ private void setSortOrder(List<SortOrder<Column<T, ?>>> order,
+ boolean userOriginated) {
+ Objects.requireNonNull(order, "Sort order list cannot be null");
+ sortOrder.clear();
+ if (order.isEmpty()) {
+ // Grid is not sorted anymore.
+ getDataCommunicator().setBackEndSorting(Collections.emptyList());
+ getDataCommunicator().setInMemorySorting(null);
+ return;
+ }
- /**
- * Generates the sort orders when rows are sorted by a column.
- *
- * @param sortDirection desired sort direction
- *
- * @return sort information
- */
- @Override
- public Stream<SortOrder<String>> apply(SortDirection sortDirection);
+ sortOrder.addAll(order);
+ sort(userOriginated);
+ }
+
+ private void sort(boolean userOriginated) {
+ // Set sort orders
+ // In-memory comparator
+ BinaryOperator<SerializableComparator<T>> operator = (comparator1,
+ comparator2) -> SerializableComparator
+ .asInstance((Comparator<T> & Serializable) comparator1
+ .thenComparing(comparator2));
+ SerializableComparator<T> comparator = sortOrder.stream().map(
+ order -> order.getSorted().getComparator(order.getDirection()))
+ .reduce((x, y) -> 0, operator);
+ getDataCommunicator().setInMemorySorting(comparator);
+
+ // Back-end sort properties
+ List<SortOrder<String>> sortProperties = new ArrayList<>();
+ sortOrder.stream().map(
+ order -> order.getSorted().getSortOrder(order.getDirection()))
+ .forEach(s -> s.forEach(sortProperties::add));
+ getDataCommunicator().setBackEndSorting(sortProperties);
+ // Close grid editor if it's open.
+ if (getEditor().isOpen()) {
+ getEditor().cancel();
+ }
}
+
}
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import java.util.Arrays;
+import java.util.List;
import java.util.Optional;
import org.easymock.Capture;
import com.vaadin.data.ValueProvider;
import com.vaadin.event.selection.SelectionEvent;
+import com.vaadin.server.data.SortOrder;
+import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.renderers.NumberRenderer;
grid.addSelectionListener(
event -> Assert.fail("never ever happens (tm)"));
}
+
+ @Test
+ public void sortByColumn_sortOrderIsAscendingOneColumn() {
+ Column<String, ?> column = grid.getColumns().get(1);
+ grid.sort(column);
+
+ SortOrder<Column<String, ?>> sortOrder = grid.getSortOrder().get(0);
+ Assert.assertEquals(column, sortOrder.getSorted());
+ Assert.assertEquals(SortDirection.ASCENDING, sortOrder.getDirection());
+ }
+
+ @Test
+ public void sortByColumnDesc_sortOrderIsDescendingOneColumn() {
+ Column<String, ?> column = grid.getColumns().get(1);
+ grid.sort(column, SortDirection.DESCENDING);
+
+ SortOrder<Column<String, ?>> sortOrder = grid.getSortOrder().get(0);
+ Assert.assertEquals(column, sortOrder.getSorted());
+ Assert.assertEquals(SortDirection.DESCENDING, sortOrder.getDirection());
+ }
+
+ @Test
+ public void setSortOrder() {
+ Column<String, ?> column1 = grid.getColumns().get(1);
+ Column<String, ?> column2 = grid.getColumns().get(2);
+ List<SortOrder<Column<String, ?>>> order = Arrays.asList(
+ new SortOrder<>(column2, SortDirection.DESCENDING),
+ new SortOrder<>(column1, SortDirection.ASCENDING));
+ grid.setSortOrder(order);
+
+ List<SortOrder<Column<String, ?>>> sortOrder = grid.getSortOrder();
+ Assert.assertEquals(column2, sortOrder.get(0).getSorted());
+ Assert.assertEquals(SortDirection.DESCENDING,
+ sortOrder.get(0).getDirection());
+
+ Assert.assertEquals(column1, sortOrder.get(1).getSorted());
+ Assert.assertEquals(SortDirection.ASCENDING,
+ sortOrder.get(1).getDirection());
+ }
+
+ @Test
+ public void clearSortOrder() {
+ Column<String, ?> column = grid.getColumns().get(1);
+ grid.sort(column);
+
+ grid.clearSortOrder();
+
+ assertEquals(0, grid.getSortOrder().size());
+ }
}
import java.util.Collections;
import java.util.Comparator;
+import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
getGridElement().getCell(i++, 3).getText());
}
}
+
+ @Test
+ public void serverSideOrderByColumn0() {
+ selectMenuPath("Component", "Columns", "Column 0", "Sort ASC");
+
+ Comparator<String> comparator = Comparator.naturalOrder();
+
+ int i = 0;
+ for (String coord : getTestData().map(DataObject::getCoordinates)
+ .sorted(comparator).limit(5).collect(Collectors.toList())) {
+ Assert.assertEquals(
+ "Grid was not sorted as expected, row number mismatch",
+ coord, getGridElement().getCell(i++, 0).getText());
+ }
+ // self-verification
+ Assert.assertTrue(i > 0);
+
+ selectMenuPath("Component", "Columns", "Column 0", "Sort DESC");
+
+ i = 0;
+ for (String coord : getTestData().map(DataObject::getCoordinates)
+ .sorted(comparator.reversed()).limit(5)
+ .collect(Collectors.toList())) {
+ Assert.assertEquals(
+ "Grid was not sorted as expected, row number mismatch",
+ coord, getGridElement().getCell(i++, 0).getText());
+ }
+ }
+
+ @Test
+ public void serverSideOrderByDate() {
+ selectMenuPath("Component", "Columns", "Date", "Sort ASC");
+
+ Comparator<Date> comparator = Comparator.naturalOrder();
+
+ int i = 0;
+ for (Date date : getTestData().map(DataObject::getDate)
+ .sorted(comparator).limit(5).collect(Collectors.toList())) {
+ Assert.assertEquals(
+ "Grid was not sorted as expected, row number mismatch",
+ date.toString(),
+ getGridElement().getCell(i++, 4).getText());
+ }
+ // self-verification
+ Assert.assertTrue(i > 0);
+
+ selectMenuPath("Component", "Columns", "Date", "Sort DESC");
+
+ i = 0;
+ for (Date date : getTestData().map(DataObject::getDate)
+ .sorted(comparator.reversed()).limit(5)
+ .collect(Collectors.toList())) {
+ Assert.assertEquals(
+ "Grid was not sorted as expected, row number mismatch",
+ date.toString(),
+ getGridElement().getCell(i++, 4).getText());
+ }
+ }
+
+ @Test
+ public void serverSideClearOrder() {
+ selectMenuPath("Component", "Columns", "Column 0", "Sort ASC");
+ selectMenuPath("Component", "Columns", "Clear sort");
+
+ int i = 0;
+ for (String coord : getTestData().map(DataObject::getCoordinates)
+ .limit(5).collect(Collectors.toList())) {
+ Assert.assertEquals(
+ "Grid was not sorted as expected, row number mismatch",
+ coord, getGridElement().getCell(i++, 0).getText());
+ }
+ // self-verification
+ Assert.assertTrue(i > 0);
+ }
+
}