aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java')
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java280
1 files changed, 125 insertions, 155 deletions
diff --git a/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java b/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
index 779cd959dd..fc6ce4f0a4 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
@@ -52,158 +52,16 @@ import elemental.json.JsonObject;
* @author Vaadin Ltd
* @since 8.0
*/
-public abstract class AbstractMultiSelect<T>
- extends AbstractListing<T, Multi<T>> implements HasValue<Set<T>> {
+public abstract class AbstractMultiSelect<T> extends AbstractListing<T>
+ implements MultiSelect<T> {
- /**
- * Simple implementation of multiselectmodel.
- */
- protected class SimpleMultiSelectModel implements SelectionModel.Multi<T> {
-
- private Set<T> selection = new LinkedHashSet<>();
-
- @Override
- public void select(T item) {
- // Not user originated
- select(item, false);
- }
-
- /**
- * Selects the given item. Depending on the implementation, may cause
- * other items to be deselected. If the item is already selected, does
- * nothing.
- *
- * @param item
- * the item to select, not null
- * @param userOriginated
- * {@code true} if this was used originated, {@code false} if
- * not
- */
- protected void select(T item, boolean userOriginated) {
- if (selection.contains(item)) {
- return;
- }
-
- updateSelection(set -> set.add(item), userOriginated);
- }
-
- @Override
- public void updateSelection(Set<T> addedItems, Set<T> removedItems) {
- updateSelection(addedItems, removedItems, false);
- }
-
- /**
- * Updates the selection by adding and removing the given items.
- *
- * @param addedItems
- * the items added to selection, not {@code} null
- * @param removedItems
- * the items removed from selection, not {@code} null
- * @param userOriginated
- * {@code true} if this was used originated, {@code false} if
- * not
- */
- protected void updateSelection(Set<T> addedItems, Set<T> removedItems,
- boolean userOriginated) {
- Objects.requireNonNull(addedItems);
- Objects.requireNonNull(removedItems);
-
- // if there are duplicates, some item is both added & removed, just
- // discard that and leave things as was before
- addedItems.removeIf(item -> removedItems.remove(item));
-
- if (selection.containsAll(addedItems)
- && Collections.disjoint(selection, removedItems)) {
- return;
- }
-
- updateSelection(set -> {
- // order of add / remove does not matter since no duplicates
- set.removeAll(removedItems);
- set.addAll(addedItems);
- }, userOriginated);
- }
-
- @Override
- public Set<T> getSelectedItems() {
- return Collections.unmodifiableSet(new LinkedHashSet<>(selection));
- }
-
- @Override
- public void deselect(T item) {
- // Not user originated
- deselect(item, false);
- }
-
- /**
- * Deselects the given item. If the item is not currently selected, does
- * nothing.
- *
- * @param item
- * the item to deselect, not null
- * @param userOriginated
- * {@code true} if this was used originated, {@code false} if
- * not
- */
- protected void deselect(T item, boolean userOriginated) {
- if (!selection.contains(item)) {
- return;
- }
-
- updateSelection(set -> set.remove(item), userOriginated);
- }
-
- /**
- * Removes the given items. Any item that is not currently selected, is
- * ignored. If none of the items are selected, does nothing.
- *
- * @param items
- * the items to deselect, not {@code null}
- * @param userOriginated
- * {@code true} if this was used originated, {@code false} if
- * not
- */
- protected void deselect(Set<T> items, boolean userOriginated) {
- Objects.requireNonNull(items);
- if (items.stream().noneMatch(i -> isSelected(i))) {
- return;
- }
-
- updateSelection(set -> set.removeAll(items), userOriginated);
- }
-
- @Override
- public void deselectAll() {
- if (selection.isEmpty()) {
- return;
- }
-
- updateSelection(Set::clear, false);
- }
-
- private void updateSelection(Consumer<Set<T>> handler,
- boolean userOriginated) {
- LinkedHashSet<T> oldSelection = new LinkedHashSet<>(selection);
- handler.accept(selection);
- LinkedHashSet<T> newSelection = new LinkedHashSet<>(selection);
-
- fireEvent(new MultiSelectionEvent<>(AbstractMultiSelect.this,
- oldSelection, userOriginated));
-
- getDataCommunicator().reset();
- }
-
- @Override
- public boolean isSelected(T item) {
- return selection.contains(item);
- }
- }
+ private Set<T> selection = new LinkedHashSet<>();
private class MultiSelectServerRpcImpl implements MultiSelectServerRpc {
@Override
public void updateSelection(Set<String> selectedItemKeys,
Set<String> deselectedItemKeys) {
- getSelectionModel().updateSelection(
+ AbstractMultiSelect.this.updateSelection(
getItemsForSelectionChange(selectedItemKeys),
getItemsForSelectionChange(deselectedItemKeys), true);
}
@@ -223,10 +81,6 @@ public abstract class AbstractMultiSelect<T>
return Optional.of(item);
}
- private SimpleMultiSelectModel getSelectionModel() {
- return (SimpleMultiSelectModel) AbstractMultiSelect.this
- .getSelectionModel();
- }
}
private class MultiSelectDataGenerator implements DataGenerator<T> {
@@ -250,7 +104,7 @@ public abstract class AbstractMultiSelect<T>
true);
}
- if (getSelectionModel().isSelected(data)) {
+ if (isSelected(data)) {
jsonObject.put(ListingJsonConstants.JSONKEY_ITEM_SELECTED,
true);
}
@@ -287,8 +141,6 @@ public abstract class AbstractMultiSelect<T>
* Creates a new multi select with an empty data source.
*/
protected AbstractMultiSelect() {
- setSelectionModel(new SimpleMultiSelectModel());
-
registerRpc(new MultiSelectServerRpcImpl());
// #FIXME it should be the responsibility of the SelectionModel
@@ -304,6 +156,7 @@ public abstract class AbstractMultiSelect<T>
* the value change listener, not {@code null}
* @return a registration for the listener
*/
+ @Override
public Registration addSelectionListener(
MultiSelectionListener<T> listener) {
addListener(MultiSelectionEvent.class, listener,
@@ -376,8 +229,7 @@ public abstract class AbstractMultiSelect<T>
Set<T> copy = value.stream().map(Objects::requireNonNull)
.collect(Collectors.toCollection(LinkedHashSet::new));
- getSelectionModel().updateSelection(copy,
- new LinkedHashSet<>(getSelectionModel().getSelectedItems()));
+ updateSelection(copy, new LinkedHashSet<>(getSelectedItems()));
}
@Override
@@ -502,4 +354,122 @@ public abstract class AbstractMultiSelect<T>
public boolean isReadOnly() {
return super.isReadOnly();
}
+
+ @Override
+ public void updateSelection(Set<T> addedItems, Set<T> removedItems) {
+ updateSelection(addedItems, removedItems, false);
+ }
+
+ /**
+ * Updates the selection by adding and removing the given items.
+ *
+ * @param addedItems
+ * the items added to selection, not {@code} null
+ * @param removedItems
+ * the items removed from selection, not {@code} null
+ * @param userOriginated
+ * {@code true} if this was used originated, {@code false} if not
+ */
+ protected void updateSelection(Set<T> addedItems, Set<T> removedItems,
+ boolean userOriginated) {
+ Objects.requireNonNull(addedItems);
+ Objects.requireNonNull(removedItems);
+
+ // if there are duplicates, some item is both added & removed, just
+ // discard that and leave things as was before
+ addedItems.removeIf(item -> removedItems.remove(item));
+
+ if (selection.containsAll(addedItems)
+ && Collections.disjoint(selection, removedItems)) {
+ return;
+ }
+
+ updateSelection(set -> {
+ // order of add / remove does not matter since no duplicates
+ set.removeAll(removedItems);
+ set.addAll(addedItems);
+ }, userOriginated);
+ }
+
+ @Override
+ public Set<T> getSelectedItems() {
+ return Collections.unmodifiableSet(new LinkedHashSet<>(selection));
+ }
+
+ @Override
+ public void deselectAll() {
+ if (selection.isEmpty()) {
+ return;
+ }
+
+ updateSelection(Set::clear, false);
+ }
+
+ @Override
+ public boolean isSelected(T item) {
+ return selection.contains(item);
+ }
+
+ /**
+ * Deselects the given item. If the item is not currently selected, does
+ * nothing.
+ *
+ * @param item
+ * the item to deselect, not null
+ * @param userOriginated
+ * {@code true} if this was used originated, {@code false} if not
+ */
+ protected void deselect(T item, boolean userOriginated) {
+ if (!selection.contains(item)) {
+ return;
+ }
+
+ updateSelection(set -> set.remove(item), userOriginated);
+ }
+
+ /**
+ * Removes the given items. Any item that is not currently selected, is
+ * ignored. If none of the items are selected, does nothing.
+ *
+ * @param items
+ * the items to deselect, not {@code null}
+ * @param userOriginated
+ * {@code true} if this was used originated, {@code false} if not
+ */
+ protected void deselect(Set<T> items, boolean userOriginated) {
+ Objects.requireNonNull(items);
+ if (items.stream().noneMatch(i -> isSelected(i))) {
+ return;
+ }
+
+ updateSelection(set -> set.removeAll(items), userOriginated);
+ }
+
+ /**
+ * Selects the given item. Depending on the implementation, may cause other
+ * items to be deselected. If the item is already selected, does nothing.
+ *
+ * @param item
+ * the item to select, not null
+ * @param userOriginated
+ * {@code true} if this was used originated, {@code false} if not
+ */
+ protected void select(T item, boolean userOriginated) {
+ if (selection.contains(item)) {
+ return;
+ }
+
+ updateSelection(set -> set.add(item), userOriginated);
+ }
+
+ private void updateSelection(Consumer<Set<T>> handler,
+ boolean userOriginated) {
+ LinkedHashSet<T> oldSelection = new LinkedHashSet<>(selection);
+ handler.accept(selection);
+
+ fireEvent(new MultiSelectionEvent<>(AbstractMultiSelect.this,
+ oldSelection, userOriginated));
+
+ getDataCommunicator().reset();
+ }
}