Fixes vaadin/framework8-issues#568tags/8.0.0.alpha10^0
/* | |||||
* Copyright 2000-2016 Vaadin Ltd. | |||||
* | |||||
* 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 com.vaadin.event; | |||||
import java.io.Serializable; | |||||
import java.util.List; | |||||
import com.vaadin.data.provider.SortOrder; | |||||
import com.vaadin.shared.Registration; | |||||
import com.vaadin.ui.Component; | |||||
/** | |||||
* Event describing a change in sorting of a {@link Container}. Fired by | |||||
* {@link SortNotifier SortNotifiers}. | |||||
* | |||||
* @see SortListener | |||||
* @see SortOrder | |||||
* @param <T> | |||||
* the type of the sorting information, usually a String (field id) | |||||
* or a {@link java.util.Comparator}. | |||||
* | |||||
* @since 8.0 | |||||
* @author Vaadin Ltd | |||||
*/ | |||||
public class SortEvent<T> extends Component.Event { | |||||
private final List<SortOrder<T>> sortOrder; | |||||
private final boolean userOriginated; | |||||
/** | |||||
* Creates a new sort order change event with a sort order list. | |||||
* | |||||
* @param source | |||||
* the component from which the event originates | |||||
* @param sortOrder | |||||
* the new sort order list | |||||
* @param userOriginated | |||||
* <code>true</code> if event is a result of user interaction, | |||||
* <code>false</code> if from API call | |||||
*/ | |||||
public SortEvent(Component source, List<SortOrder<T>> sortOrder, | |||||
boolean userOriginated) { | |||||
super(source); | |||||
this.sortOrder = sortOrder; | |||||
this.userOriginated = userOriginated; | |||||
} | |||||
/** | |||||
* Gets the sort order list. | |||||
* | |||||
* @return the sort order list | |||||
*/ | |||||
public List<SortOrder<T>> getSortOrder() { | |||||
return sortOrder; | |||||
} | |||||
/** | |||||
* Returns whether this event originated from actions done by the user. | |||||
* | |||||
* @return true if sort event originated from user interaction | |||||
*/ | |||||
public boolean isUserOriginated() { | |||||
return userOriginated; | |||||
} | |||||
/** | |||||
* Listener for sort order change events. | |||||
* | |||||
* @param <T> | |||||
* the type of the sorting information, usually a String (field | |||||
* id) or a {@link java.util.Comparator}. | |||||
*/ | |||||
@FunctionalInterface | |||||
public interface SortListener<T> extends Serializable { | |||||
/** | |||||
* Called when the sort order has changed. | |||||
* | |||||
* @param event | |||||
* the sort order change event | |||||
*/ | |||||
public void sort(SortEvent<T> event); | |||||
} | |||||
/** | |||||
* The interface for adding and removing listeners for {@link SortEvent | |||||
* SortEvents}. | |||||
* | |||||
* @param <T> | |||||
* the type of the sorting information, usually a String (field | |||||
* id) or a {@link java.util.Comparator}. | |||||
*/ | |||||
public interface SortNotifier<T> extends Serializable { | |||||
/** | |||||
* Adds a sort order change listener that gets notified when the sort | |||||
* order changes. | |||||
* | |||||
* @param listener | |||||
* the sort order change listener to add | |||||
* @return a registration object for removing the listener | |||||
*/ | |||||
public Registration addSortListener(SortListener<T> listener); | |||||
} | |||||
} |
import com.vaadin.data.provider.SortOrder; | import com.vaadin.data.provider.SortOrder; | ||||
import com.vaadin.event.ConnectorEvent; | import com.vaadin.event.ConnectorEvent; | ||||
import com.vaadin.event.ContextClickEvent; | import com.vaadin.event.ContextClickEvent; | ||||
import com.vaadin.event.SortEvent; | |||||
import com.vaadin.event.SortEvent.SortListener; | |||||
import com.vaadin.event.SortEvent.SortNotifier; | |||||
import com.vaadin.event.selection.MultiSelectionListener; | import com.vaadin.event.selection.MultiSelectionListener; | ||||
import com.vaadin.event.selection.SelectionListener; | import com.vaadin.event.selection.SelectionListener; | ||||
import com.vaadin.event.selection.SingleSelectionListener; | import com.vaadin.event.selection.SingleSelectionListener; | ||||
import com.vaadin.shared.ui.grid.GridStaticCellType; | import com.vaadin.shared.ui.grid.GridStaticCellType; | ||||
import com.vaadin.shared.ui.grid.HeightMode; | import com.vaadin.shared.ui.grid.HeightMode; | ||||
import com.vaadin.shared.ui.grid.SectionState; | import com.vaadin.shared.ui.grid.SectionState; | ||||
import com.vaadin.ui.Grid.SelectionMode; | |||||
import com.vaadin.ui.components.grid.ColumnReorderListener; | import com.vaadin.ui.components.grid.ColumnReorderListener; | ||||
import com.vaadin.ui.components.grid.ColumnResizeListener; | import com.vaadin.ui.components.grid.ColumnResizeListener; | ||||
import com.vaadin.ui.components.grid.ColumnVisibilityChangeListener; | import com.vaadin.ui.components.grid.ColumnVisibilityChangeListener; | ||||
* @param <T> | * @param <T> | ||||
* the grid bean type | * the grid bean type | ||||
*/ | */ | ||||
public class Grid<T> extends AbstractListing<T> | |||||
implements HasComponents, Listing<T, DataProvider<T, ?>> { | |||||
public class Grid<T> extends AbstractListing<T> implements HasComponents, | |||||
Listing<T, DataProvider<T, ?>>, SortNotifier<Grid.Column<T, ?>> { | |||||
@Deprecated | @Deprecated | ||||
private static final Method COLUMN_REORDER_METHOD = ReflectTools.findMethod( | private static final Method COLUMN_REORDER_METHOD = ReflectTools.findMethod( | ||||
ColumnReorderListener.class, "columnReorder", | ColumnReorderListener.class, "columnReorder", | ||||
ColumnReorderEvent.class); | ColumnReorderEvent.class); | ||||
private static final Method SORT_ORDER_CHANGE_METHOD = ReflectTools | |||||
.findMethod(SortListener.class, "sort", SortEvent.class); | |||||
@Deprecated | @Deprecated | ||||
private static final Method COLUMN_RESIZE_METHOD = ReflectTools.findMethod( | private static final Method COLUMN_RESIZE_METHOD = ReflectTools.findMethod( | ||||
ColumnResizeListener.class, "columnResize", | ColumnResizeListener.class, "columnResize", | ||||
setSortOrder(order, false); | setSortOrder(order, false); | ||||
} | } | ||||
/** | |||||
* Adds a sort order change listener that gets notified when the sort order | |||||
* changes. | |||||
* | |||||
* @param listener | |||||
* the sort order change listener to add | |||||
*/ | |||||
@Override | |||||
public Registration addSortListener(SortListener<Column<T, ?>> listener) { | |||||
return addListener(SortEvent.class, listener, SORT_ORDER_CHANGE_METHOD); | |||||
} | |||||
/** | /** | ||||
* Get the current sort order list. | * Get the current sort order list. | ||||
* | * | ||||
// Grid is not sorted anymore. | // Grid is not sorted anymore. | ||||
getDataCommunicator().setBackEndSorting(Collections.emptyList()); | getDataCommunicator().setBackEndSorting(Collections.emptyList()); | ||||
getDataCommunicator().setInMemorySorting(null); | getDataCommunicator().setInMemorySorting(null); | ||||
fireEvent(new SortEvent<>(this, new ArrayList<>(sortOrder), | |||||
userOriginated)); | |||||
return; | return; | ||||
} | } | ||||
sortOrder.addAll(order); | sortOrder.addAll(order); | ||||
if (getEditor().isOpen()) { | if (getEditor().isOpen()) { | ||||
getEditor().cancel(); | getEditor().cancel(); | ||||
} | } | ||||
fireEvent(new SortEvent<>(this, new ArrayList<>(sortOrder), | |||||
userOriginated)); | |||||
} | } | ||||
} | } |
import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertFalse; | ||||
import static org.junit.Assert.assertNotNull; | import static org.junit.Assert.assertNotNull; | ||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Optional; | import java.util.Optional; | ||||
import java.util.concurrent.atomic.AtomicReference; | |||||
import org.easymock.Capture; | import org.easymock.Capture; | ||||
import org.junit.Assert; | import org.junit.Assert; | ||||
assertEquals(0, grid.getSortOrder().size()); | assertEquals(0, grid.getSortOrder().size()); | ||||
} | } | ||||
@Test | |||||
public void sortListener_eventIsFired() { | |||||
Column<String, ?> column1 = grid.getColumns().get(1); | |||||
Column<String, ?> column2 = grid.getColumns().get(2); | |||||
List<SortOrder<Column<String, ?>>> list = new ArrayList<>(); | |||||
AtomicReference<Boolean> fired = new AtomicReference<>(); | |||||
grid.addSortListener(event -> { | |||||
Assert.assertTrue(list.isEmpty()); | |||||
fired.set(true); | |||||
list.addAll(event.getSortOrder()); | |||||
}); | |||||
grid.sort(column1, SortDirection.DESCENDING); | |||||
Assert.assertEquals(column1, list.get(0).getSorted()); | |||||
Assert.assertEquals(SortDirection.DESCENDING, | |||||
list.get(0).getDirection()); | |||||
List<SortOrder<Column<String, ?>>> order = Arrays.asList( | |||||
new SortOrder<>(column2, SortDirection.DESCENDING), | |||||
new SortOrder<>(column1, SortDirection.ASCENDING)); | |||||
list.clear(); | |||||
grid.setSortOrder(order); | |||||
Assert.assertEquals(column2, list.get(0).getSorted()); | |||||
Assert.assertEquals(SortDirection.DESCENDING, | |||||
list.get(0).getDirection()); | |||||
Assert.assertEquals(column1, list.get(1).getSorted()); | |||||
Assert.assertEquals(SortDirection.ASCENDING, | |||||
list.get(1).getDirection()); | |||||
list.clear(); | |||||
fired.set(false); | |||||
grid.clearSortOrder(); | |||||
Assert.assertEquals(0, list.size()); | |||||
Assert.assertTrue(fired.get()); | |||||
} | |||||
} | } |
event -> log("ColumnResizeEvent: isUserOriginated? " | event -> log("ColumnResizeEvent: isUserOriginated? " | ||||
+ event.isUserOriginated())); | + event.isUserOriginated())); | ||||
layout.addComponent(createMenu()); | |||||
grid.addSortListener(event -> log( | |||||
"SortEvent: isUserOriginated? " + event.isUserOriginated())); | |||||
layout.addComponent( | |||||
createMenu()); | |||||
layout.addComponent(grid); | layout.addComponent(grid); | ||||
addComponent(layout); | addComponent(layout); | ||||
} | } |
import com.vaadin.v7.event.SelectionEvent; | import com.vaadin.v7.event.SelectionEvent; | ||||
import com.vaadin.v7.event.SelectionEvent.SelectionListener; | import com.vaadin.v7.event.SelectionEvent.SelectionListener; | ||||
import com.vaadin.v7.event.SortEvent; | import com.vaadin.v7.event.SortEvent; | ||||
import com.vaadin.v7.event.SortEvent.SortListener; | |||||
import com.vaadin.v7.shared.ui.grid.ColumnResizeMode; | import com.vaadin.v7.shared.ui.grid.ColumnResizeMode; | ||||
import com.vaadin.v7.shared.ui.grid.GridStaticCellType; | import com.vaadin.v7.shared.ui.grid.GridStaticCellType; | ||||
import com.vaadin.v7.shared.ui.grid.HeightMode; | import com.vaadin.v7.shared.ui.grid.HeightMode; | ||||
column.setHidable(isColumnHidableByDefault(col)); | column.setHidable(isColumnHidableByDefault(col)); | ||||
} | } | ||||
grid.addSortListener(new SortListener() { | |||||
grid.addSortListener(new SortEvent.SortListener() { | |||||
@Override | @Override | ||||
public void sort(SortEvent event) { | public void sort(SortEvent event) { | ||||
log("SortEvent: isUserOriginated? " + event.isUserOriginated()); | log("SortEvent: isUserOriginated? " + event.isUserOriginated()); |
public void serverSideOrderByColumn0() { | public void serverSideOrderByColumn0() { | ||||
selectMenuPath("Component", "Columns", "Column 0", "Sort ASC"); | selectMenuPath("Component", "Columns", "Column 0", "Sort ASC"); | ||||
Assert.assertEquals("1. SortEvent: isUserOriginated? false", | |||||
getLogRow(0)); | |||||
Comparator<String> comparator = Comparator.naturalOrder(); | Comparator<String> comparator = Comparator.naturalOrder(); | ||||
int i = 0; | int i = 0; | ||||
Assert.assertTrue(i > 0); | Assert.assertTrue(i > 0); | ||||
selectMenuPath("Component", "Columns", "Column 0", "Sort DESC"); | selectMenuPath("Component", "Columns", "Column 0", "Sort DESC"); | ||||
Assert.assertEquals("2. SortEvent: isUserOriginated? false", | |||||
getLogRow(0)); | |||||
i = 0; | i = 0; | ||||
for (String coord : getTestData().map(DataObject::getCoordinates) | for (String coord : getTestData().map(DataObject::getCoordinates) | ||||
public void serverSideOrderByDate() { | public void serverSideOrderByDate() { | ||||
selectMenuPath("Component", "Columns", "Date", "Sort ASC"); | selectMenuPath("Component", "Columns", "Date", "Sort ASC"); | ||||
Assert.assertEquals("1. SortEvent: isUserOriginated? false", | |||||
getLogRow(0)); | |||||
Comparator<Date> comparator = Comparator.naturalOrder(); | Comparator<Date> comparator = Comparator.naturalOrder(); | ||||
int i = 0; | int i = 0; | ||||
Assert.assertTrue(i > 0); | Assert.assertTrue(i > 0); | ||||
selectMenuPath("Component", "Columns", "Date", "Sort DESC"); | selectMenuPath("Component", "Columns", "Date", "Sort DESC"); | ||||
Assert.assertEquals("2. SortEvent: isUserOriginated? false", | |||||
getLogRow(0)); | |||||
i = 0; | i = 0; | ||||
for (Date date : getTestData().map(DataObject::getDate) | for (Date date : getTestData().map(DataObject::getDate) | ||||
selectMenuPath("Component", "Columns", "Column 0", "Sort ASC"); | selectMenuPath("Component", "Columns", "Column 0", "Sort ASC"); | ||||
selectMenuPath("Component", "Columns", "Clear sort"); | selectMenuPath("Component", "Columns", "Clear sort"); | ||||
Assert.assertEquals("2. SortEvent: isUserOriginated? false", | |||||
getLogRow(0)); | |||||
int i = 0; | int i = 0; | ||||
for (String coord : getTestData().map(DataObject::getCoordinates) | for (String coord : getTestData().map(DataObject::getCoordinates) | ||||
.limit(5).collect(Collectors.toList())) { | .limit(5).collect(Collectors.toList())) { |