]> source.dussan.org Git - vaadin-framework.git/commitdiff
Remove HasValue from Grid
authorPekka Hyvönen <pekka@vaadin.com>
Mon, 7 Nov 2016 07:16:37 +0000 (09:16 +0200)
committerIlia Motornyi <elmot@vaadin.com>
Thu, 10 Nov 2016 07:49:08 +0000 (07:49 +0000)
Extracts grid single selection into separate class, which
is an extension like in V7. Using an extension makes it
possible to easily add multiselect and no-select modes back,
and support custom selection models.

Adds Grid:asSingleSelect() SingleSelect so that grid can be
used as a Select in a binder.

Removes all remaining references to SelectionModels in Listings.
Renames SingleSelectionChangeEvent to SingleSelectionEvent, because
then it is unified with selection listener and MultiSelectionEvent.

Fixes vaadin/framework8-issues#424
Fixes vaadin/framework8-issues#425

Change-Id: Ie22bef29cfd4336c3f65d4e63531c578b8dd76a3

27 files changed:
client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java
client/src/main/java/com/vaadin/client/connectors/grid/SingleSelectionModelConnector.java [new file with mode: 0644]
client/src/main/java/com/vaadin/client/connectors/selection/AbstractSelectionConnector.java [deleted file]
client/src/main/java/com/vaadin/client/data/SelectionModel.java
server/src/main/java/com/vaadin/data/SelectionModel.java
server/src/main/java/com/vaadin/data/selection/AbstractSelectionModel.java [deleted file]
server/src/main/java/com/vaadin/event/selection/SingleSelectionChangeEvent.java [deleted file]
server/src/main/java/com/vaadin/event/selection/SingleSelectionEvent.java [new file with mode: 0644]
server/src/main/java/com/vaadin/event/selection/SingleSelectionListener.java
server/src/main/java/com/vaadin/ui/AbstractSingleSelect.java
server/src/main/java/com/vaadin/ui/ComboBox.java
server/src/main/java/com/vaadin/ui/Grid.java
server/src/main/java/com/vaadin/ui/components/colorpicker/ColorPickerSelect.java
server/src/main/java/com/vaadin/ui/components/grid/SingleSelectionModel.java [new file with mode: 0644]
server/src/test/java/com/vaadin/data/BinderSingleSelectTest.java
server/src/test/java/com/vaadin/data/GridAsSingleSelectInBinder.java [new file with mode: 0644]
server/src/test/java/com/vaadin/event/selection/SelectionEventTest.java
server/src/test/java/com/vaadin/tests/components/grid/GridSelectionTest.java [deleted file]
server/src/test/java/com/vaadin/tests/components/grid/GridSingleSelectionModelTest.java [new file with mode: 0644]
server/src/test/java/com/vaadin/ui/AbstractSingleSelectTest.java
server/src/test/java/com/vaadin/ui/RadioButtonGroupTest.java
uitest/src/main/java/com/vaadin/tests/components/abstractlisting/AbstractSingleSelectTestUI.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowed.java
uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java
uitest/src/main/java/com/vaadin/tests/components/nativeselect/NativeSelectInit.java
uitest/src/main/java/com/vaadin/tests/components/radiobutton/RadioButtonGroupTestUI.java
uitest/src/main/java/com/vaadin/tests/data/DummyData.java

index ef715acfad19cc9e8dca5395c7e883eb8ae7d3f4..f5d95dfa801999b7e60d55a2d0455751c20ff68f 100644 (file)
@@ -21,7 +21,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 import com.google.gwt.dom.client.Element;
@@ -40,7 +39,6 @@ import com.vaadin.client.annotations.OnStateChange;
 import com.vaadin.client.connectors.AbstractListingConnector;
 import com.vaadin.client.connectors.grid.ColumnConnector.CustomColumn;
 import com.vaadin.client.data.DataSource;
-import com.vaadin.client.data.SelectionModel;
 import com.vaadin.client.ui.SimpleManagedLayout;
 import com.vaadin.client.widget.grid.CellReference;
 import com.vaadin.client.widget.grid.EventCellReference;
@@ -58,8 +56,6 @@ import com.vaadin.client.widgets.Grid.FooterRow;
 import com.vaadin.client.widgets.Grid.HeaderCell;
 import com.vaadin.client.widgets.Grid.HeaderRow;
 import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.data.DataCommunicatorConstants;
-import com.vaadin.shared.data.selection.SelectionServerRpc;
 import com.vaadin.shared.data.sort.SortDirection;
 import com.vaadin.shared.ui.Connect;
 import com.vaadin.shared.ui.grid.GridConstants;
@@ -204,33 +200,6 @@ public class GridConnector extends AbstractListingConnector
         /* Item click events */
         getWidget().addBodyClickHandler(itemClickHandler);
         getWidget().addBodyDoubleClickHandler(itemClickHandler);
-        getWidget().setSelectionModel(new SelectionModel<JsonObject>() {
-
-            @Override
-            public void select(JsonObject item) {
-                getRpcProxy(SelectionServerRpc.class)
-                        .select(item.getString(DataCommunicatorConstants.KEY));
-            }
-
-            @Override
-            public void deselect(JsonObject item) {
-                getRpcProxy(SelectionServerRpc.class).deselect(
-                        item.getString(DataCommunicatorConstants.KEY));
-            }
-
-            @Override
-            public Set<JsonObject> getSelectedItems() {
-                throw new UnsupportedOperationException(
-                        "Selected item not known on the client side");
-            }
-
-            @Override
-            public boolean isSelected(JsonObject item) {
-                return item.hasKey(DataCommunicatorConstants.SELECTED)
-                        && item.getBoolean(DataCommunicatorConstants.SELECTED);
-            }
-
-        });
 
         layout();
     }
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/SingleSelectionModelConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/SingleSelectionModelConnector.java
new file mode 100644 (file)
index 0000000..0a30dfa
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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.client.connectors.grid;
+
+import java.util.Set;
+
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.data.SelectionModel;
+import com.vaadin.client.extensions.AbstractExtensionConnector;
+import com.vaadin.shared.data.DataCommunicatorConstants;
+import com.vaadin.shared.data.selection.SelectionServerRpc;
+import com.vaadin.shared.ui.Connect;
+
+import elemental.json.JsonObject;
+
+/**
+ * Client side connector for grid single selection model.
+ *
+ * @author Vaadin Ltd.
+ *
+ * @since 8.0
+ */
+@Connect(com.vaadin.ui.components.grid.SingleSelectionModel.class)
+public class SingleSelectionModelConnector extends AbstractExtensionConnector {
+
+    @Override
+    protected void extend(ServerConnector target) {
+        getParent().getWidget()
+                .setSelectionModel(new SelectionModel<JsonObject>() {
+
+                    @Override
+                    public void select(JsonObject item) {
+                        getRpcProxy(SelectionServerRpc.class).select(
+                                item.getString(DataCommunicatorConstants.KEY));
+                    }
+
+                    @Override
+                    public void deselect(JsonObject item) {
+                        getRpcProxy(SelectionServerRpc.class).deselect(
+                                item.getString(DataCommunicatorConstants.KEY));
+                    }
+
+                    @Override
+                    public Set<JsonObject> getSelectedItems() {
+                        throw new UnsupportedOperationException(
+                                "Selected item not known on the client side");
+                    }
+
+                    @Override
+                    public boolean isSelected(JsonObject item) {
+                        return SelectionModel.isItemSelected(item);
+                    }
+
+                });
+    }
+
+    @Override
+    public GridConnector getParent() {
+        return (GridConnector) super.getParent();
+    }
+
+}
diff --git a/client/src/main/java/com/vaadin/client/connectors/selection/AbstractSelectionConnector.java b/client/src/main/java/com/vaadin/client/connectors/selection/AbstractSelectionConnector.java
deleted file mode 100644 (file)
index 55ce2de..0000000
+++ /dev/null
@@ -1,81 +0,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.client.connectors.selection;
-
-import com.vaadin.client.ServerConnector;
-import com.vaadin.client.connectors.AbstractListingConnector;
-import com.vaadin.client.extensions.AbstractExtensionConnector;
-import com.vaadin.shared.data.DataCommunicatorConstants;
-
-import elemental.json.JsonObject;
-
-/**
- * The client-side connector for selection extensions.
- *
- * @author Vaadin Ltd.
- * 
- * @since 8.0
- */
-public abstract class AbstractSelectionConnector
-        extends AbstractExtensionConnector {
-
-    @Override
-    @SuppressWarnings("unchecked")
-    protected void extend(ServerConnector target) {
-        if (!(target instanceof AbstractListingConnector)) {
-            throw new IllegalArgumentException(
-                    "Cannot extend a connector that is not an "
-                            + AbstractListingConnector.class.getSimpleName());
-        }
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public AbstractListingConnector getParent() {
-        return (AbstractListingConnector) super.getParent();
-    }
-
-    /**
-     * Gets the selected state from a given json object. This is a helper method
-     * for selection model connectors.
-     *
-     * @param item
-     *            a json object
-     * @return {@code true} if the json object is marked as selected;
-     *         {@code false} if not
-     */
-    public static boolean isItemSelected(JsonObject item) {
-        return item.hasKey(DataCommunicatorConstants.SELECTED)
-                && item.getBoolean(DataCommunicatorConstants.SELECTED);
-    }
-
-    /**
-     * Gets the item key from given json object. This is a helper method for
-     * selection model connectors.
-     *
-     * @param item
-     *            a json object
-     * @return item key; {@code null} if there is no key
-     */
-    public static String getKey(JsonObject item) {
-        if (item.hasKey(DataCommunicatorConstants.KEY)) {
-            return item.getString(DataCommunicatorConstants.KEY);
-        } else {
-            return null;
-        }
-    }
-
-}
index 80eb20fef15d902415c4efaf7c41c4db8c1a7587..40791401284293412c3fa9ada9f3448e7d8a24ac 100644 (file)
@@ -17,6 +17,10 @@ package com.vaadin.client.data;
 
 import java.util.Set;
 
+import com.vaadin.shared.data.DataCommunicatorConstants;
+
+import elemental.json.JsonObject;
+
 /**
  * Models the selection logic of a {@code Grid} component. Determines how items
  * can be selected and deselected.
@@ -32,7 +36,7 @@ public interface SelectionModel<T> {
     /**
      * Selects the given item. If another item was already selected, that item
      * is deselected.
-     * 
+     *
      * @param item
      *            the item to select, not null
      */
@@ -50,7 +54,7 @@ public interface SelectionModel<T> {
     /**
      * Returns a set of the currently selected items. It is safe to invoke other
      * {@code SelectionModel} methods while iterating over the set.
-     * 
+     *
      * @return the items in the current selection, not null
      */
     Set<T> getSelectedItems();
@@ -70,4 +74,19 @@ public interface SelectionModel<T> {
     default void deselectAll() {
         getSelectedItems().forEach(this::deselect);
     }
+
+    /**
+     * Gets the selected state from a given grid row json object. This is a
+     * helper method for grid selection models.
+     *
+     * @param item
+     *            a json object
+     * @return {@code true} if the json object is marked as selected;
+     *         {@code false} if not
+     */
+    public static boolean isItemSelected(JsonObject item) {
+        return item.hasKey(DataCommunicatorConstants.SELECTED)
+                && item.getBoolean(DataCommunicatorConstants.SELECTED);
+    }
+
 }
index eca43e6c8ddaedbfde7461997c5dcedebcae22ff..98a068993a6b5dff5426ef1c53d15c7ce9845b9a 100644 (file)
@@ -90,6 +90,11 @@ public interface SelectionModel<T> extends Serializable {
             return getSelectedItem().map(Collections::singleton)
                     .orElse(Collections.emptySet());
         }
+
+        @Override
+        default Optional<T> getFirstSelectedItem() {
+            return getSelectedItem();
+        }
     }
 
     /**
@@ -173,6 +178,11 @@ public interface SelectionModel<T> extends Serializable {
          *            the items to remove, not {@code null}
          */
         public void updateSelection(Set<T> addedItems, Set<T> removedItems);
+
+        @Override
+        default Optional<T> getFirstSelectedItem() {
+            return getSelectedItems().stream().findFirst();
+        }
     }
 
     /**
@@ -187,6 +197,17 @@ public interface SelectionModel<T> extends Serializable {
      */
     public Set<T> getSelectedItems();
 
+    /**
+     * Get first selected data item.
+     * <p>
+     * This is the same as {@link Single#getSelectedItem()} in case of single
+     * selection and the first selected item from
+     * {@link Multi#getSelectedItems()} in case of multiselection.
+     *
+     * @return the first selected item.
+     */
+    Optional<T> getFirstSelectedItem();
+
     /**
      * Selects the given item. Depending on the implementation, may cause other
      * items to be deselected. If the item is already selected, does nothing.
diff --git a/server/src/main/java/com/vaadin/data/selection/AbstractSelectionModel.java b/server/src/main/java/com/vaadin/data/selection/AbstractSelectionModel.java
deleted file mode 100644 (file)
index 7e60847..0000000
+++ /dev/null
@@ -1,47 +0,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.data.selection;
-
-import com.vaadin.data.SelectionModel;
-import com.vaadin.shared.data.DataCommunicatorConstants;
-import com.vaadin.ui.AbstractListing.AbstractListingExtension;
-
-import elemental.json.JsonObject;
-
-/**
- * An astract base class for {@code SelectionModel}s.
- *
- * @author Vaadin Ltd.
- *
- * @param <T>
- *            type of selected data
- *
- * @since 8.0
- */
-public abstract class AbstractSelectionModel<T> extends
-        AbstractListingExtension<T> implements SelectionModel<T> {
-
-    @Override
-    public void generateData(T data, JsonObject jsonObject) {
-        if (isSelected(data)) {
-            jsonObject.put(DataCommunicatorConstants.SELECTED, true);
-        }
-    }
-
-    @Override
-    public void destroyData(T data) {
-    }
-}
diff --git a/server/src/main/java/com/vaadin/event/selection/SingleSelectionChangeEvent.java b/server/src/main/java/com/vaadin/event/selection/SingleSelectionChangeEvent.java
deleted file mode 100644 (file)
index 7f1acff..0000000
+++ /dev/null
@@ -1,78 +0,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.selection;
-
-import java.util.Optional;
-
-import com.vaadin.data.HasValue.ValueChangeEvent;
-import com.vaadin.ui.AbstractListing;
-import com.vaadin.ui.AbstractSingleSelect;
-
-/**
- * Fired when the selection changes in a listing component.
- * 
- * @author Vaadin Ltd.
- *
- * @param <T>
- *            the type of the selected item
- * @since 8.0
- */
-public class SingleSelectionChangeEvent<T> extends ValueChangeEvent<T>
-        implements SelectionEvent<T> {
-
-    /**
-     * Creates a new selection change event.
-     * 
-     * @param source
-     *            the listing that fired the event
-     * @param userOriginated
-     *            {@code true} if this event originates from the client,
-     *            {@code false} otherwise.
-     */
-    public SingleSelectionChangeEvent(AbstractSingleSelect<T> source,
-            boolean userOriginated) {
-        super(source, userOriginated);
-    }
-
-    /**
-     * Returns an optional of the item that was selected, or an empty optional
-     * if a previously selected item was deselected.
-     * <p>
-     * The result is the current selection of the source
-     * {@link AbstractSingleSelect} object. So it's always exactly the same as
-     * optional describing {@link AbstractSingleSelect#getValue()}.
-     * 
-     * @see #getValue()
-     * 
-     * @return the selected item or an empty optional if deselected
-     *
-     * @see SelectionModel.Single#getSelectedItem()
-     */
-    public Optional<T> getSelectedItem() {
-        return Optional.ofNullable(getValue());
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public AbstractListing<T> getComponent() {
-        return (AbstractListing<T>) super.getComponent();
-    }
-
-    @Override
-    public Optional<T> getFirstSelected() {
-        return getSelectedItem();
-    }
-}
diff --git a/server/src/main/java/com/vaadin/event/selection/SingleSelectionEvent.java b/server/src/main/java/com/vaadin/event/selection/SingleSelectionEvent.java
new file mode 100644 (file)
index 0000000..c6c9ce6
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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.selection;
+
+import java.util.Optional;
+
+import com.vaadin.data.HasValue.ValueChangeEvent;
+import com.vaadin.ui.AbstractSingleSelect;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.SingleSelect;
+
+/**
+ * Fired when the selection changes in a listing component.
+ *
+ * @author Vaadin Ltd.
+ *
+ * @param <T>
+ *            the type of the selected item
+ * @since 8.0
+ */
+public class SingleSelectionEvent<T> extends ValueChangeEvent<T>
+        implements SelectionEvent<T> {
+
+    /**
+     * Creates a new selection change event.
+     *
+     * @param source
+     *            the listing that fired the event
+     * @param userOriginated
+     *            {@code true} if this event originates from the client,
+     *            {@code false} otherwise.
+     */
+    public SingleSelectionEvent(AbstractSingleSelect<T> source,
+            boolean userOriginated) {
+        super(source, userOriginated);
+    }
+
+    /**
+     * Creates a new selection change event in a component.
+     *
+     * @param component
+     *            the component where the event originated
+     * @param source
+     *            the single select source
+     * @param userOriginated
+     *            {@code true} if this event originates from the client,
+     *            {@code false} otherwise.
+     */
+    public SingleSelectionEvent(Component component, SingleSelect<T> source,
+            boolean userOriginated) {
+        super(component, source, userOriginated);
+    }
+
+    /**
+     * Returns an optional of the item that was selected, or an empty optional
+     * if a previously selected item was deselected.
+     * <p>
+     * The result is the current selection of the source
+     * {@link AbstractSingleSelect} object. So it's always exactly the same as
+     * optional describing {@link AbstractSingleSelect#getValue()}.
+     *
+     * @see #getValue()
+     *
+     * @return the selected item or an empty optional if deselected
+     *
+     * @see SelectionModel.Single#getSelectedItem()
+     */
+    public Optional<T> getSelectedItem() {
+        return Optional.ofNullable(getValue());
+    }
+
+    /**
+     * The single select on which the Event initially occurred.
+     *
+     * @return The single select on which the Event initially occurred.
+     */
+    @Override
+    public SingleSelect<T> getSource() {
+        return (SingleSelect<T>) super.getSource();
+    }
+
+    @Override
+    public Optional<T> getFirstSelected() {
+        return getSelectedItem();
+    }
+}
index d36c3ceaf1d95206bc2dd82d3609789012850109..eb054e250be69fbf595b74bd7ce0d0fafb1034e7 100644 (file)
@@ -26,14 +26,14 @@ import java.util.function.Consumer;
  * @param <T>
  *            the type of the selected item
  * 
- * @see SingleSelectionChangeEvent
+ * @see SingleSelectionEvent
  * 
  * @since 8.0
  */
 @FunctionalInterface
 public interface SingleSelectionListener<T>
-        extends Consumer<SingleSelectionChangeEvent<T>>, Serializable {
+        extends Consumer<SingleSelectionEvent<T>>, Serializable {
 
     @Override
-    public void accept(SingleSelectionChangeEvent<T> event);
+    public void accept(SingleSelectionEvent<T> event);
 }
index 7125139d8aa2f49e8c3cd8f369773c7bf1549e21..2ffcedde151dd0698b1e914feab88d444efaee3c 100644 (file)
@@ -22,7 +22,7 @@ import java.util.Optional;
 import com.vaadin.data.HasValue;
 import com.vaadin.data.SelectionModel;
 import com.vaadin.data.SelectionModel.Single;
-import com.vaadin.event.selection.SingleSelectionChangeEvent;
+import com.vaadin.event.selection.SingleSelectionEvent;
 import com.vaadin.event.selection.SingleSelectionListener;
 import com.vaadin.server.data.DataCommunicator;
 import com.vaadin.shared.Registration;
@@ -49,7 +49,7 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
     @Deprecated
     private static final Method SELECTION_CHANGE_METHOD = ReflectTools
             .findMethod(SingleSelectionListener.class, "accept",
-                    SingleSelectionChangeEvent.class);
+                    SingleSelectionEvent.class);
 
     /**
      * Creates a new {@code AbstractListing} with a default data communicator.
@@ -92,11 +92,11 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
      *            the value change listener, not null
      * @return a registration for the listener
      */
-    public Registration addSelectionListener(
+    public Registration addSelectionChangeListener(
             SingleSelectionListener<T> listener) {
-        addListener(SingleSelectionChangeEvent.class, listener,
+        addListener(SingleSelectionEvent.class, listener,
                 SELECTION_CHANGE_METHOD);
-        return () -> removeListener(SingleSelectionChangeEvent.class, listener);
+        return () -> removeListener(SingleSelectionEvent.class, listener);
     }
 
     /**
@@ -158,7 +158,7 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
     @Override
     public Registration addValueChangeListener(
             HasValue.ValueChangeListener<T> listener) {
-        return addSelectionListener(event -> listener.accept(
+        return addSelectionChangeListener(event -> listener.accept(
                 new ValueChangeEvent<>(this, event.isUserOriginated())));
     }
 
@@ -192,18 +192,6 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
         return super.isReadOnly();
     }
 
-    public void deselect(T item) {
-        Objects.requireNonNull(item, "deselected item cannot be null");
-        if (isSelected(item)) {
-            setSelectedFromServer(null);
-        }
-    }
-
-    public void select(T item) {
-        Objects.requireNonNull(item, "selected item cannot be null");
-        setSelectedFromServer(item);
-    }
-
     /**
      * Returns the communication key of the selected item or {@code null} if no
      * item is selected.
@@ -245,7 +233,7 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
         }
 
         doSetSelectedKey(key);
-        fireEvent(new SingleSelectionChangeEvent<>(AbstractSingleSelect.this,
+        fireEvent(new SingleSelectionEvent<>(AbstractSingleSelect.this,
                 true));
     }
 
@@ -266,7 +254,7 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
         }
 
         doSetSelectedKey(key);
-        fireEvent(new SingleSelectionChangeEvent<>(AbstractSingleSelect.this,
+        fireEvent(new SingleSelectionEvent<>(AbstractSingleSelect.this,
                 false));
     }
 
index 097ae30bc70dc71e4cdcb262b83d34e7b4290c61..d4df2236f7e58f366a8b859a7f97f4c6015dcd09 100644 (file)
@@ -524,7 +524,7 @@ public class ComboBox<T> extends AbstractSingleSelect<T> implements HasValue<T>,
     @Override
     public Registration addValueChangeListener(
             HasValue.ValueChangeListener<T> listener) {
-        return addSelectionListener(event -> {
+        return addSelectionChangeListener(event -> {
             listener.accept(new ValueChangeEvent<>(event.getComponent(), this,
                     event.isUserOriginated()));
         });
index 63c8fe3e6f2c8fa52526d16114f1550b63aabf95..42aab6a7e4fa15f407765bdd30095cb4fd576f31 100644 (file)
@@ -30,19 +30,19 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.function.BinaryOperator;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import com.vaadin.data.SelectionModel.Single;
+import com.vaadin.data.Binder;
+import com.vaadin.data.SelectionModel;
 import com.vaadin.event.ConnectorEvent;
 import com.vaadin.event.ContextClickEvent;
 import com.vaadin.event.EventListener;
-import com.vaadin.event.selection.SingleSelectionChangeEvent;
 import com.vaadin.server.EncodeResult;
+import com.vaadin.server.Extension;
 import com.vaadin.server.JsonCodec;
 import com.vaadin.server.SerializableComparator;
 import com.vaadin.server.SerializableFunction;
@@ -50,7 +50,6 @@ import com.vaadin.server.data.SortOrder;
 import com.vaadin.shared.MouseEventDetails;
 import com.vaadin.shared.Registration;
 import com.vaadin.shared.data.DataCommunicatorConstants;
-import com.vaadin.shared.data.selection.SelectionServerRpc;
 import com.vaadin.shared.data.sort.SortDirection;
 import com.vaadin.shared.ui.grid.ColumnState;
 import com.vaadin.shared.ui.grid.GridConstants;
@@ -65,6 +64,7 @@ import com.vaadin.ui.Grid.FooterRow;
 import com.vaadin.ui.components.grid.Footer;
 import com.vaadin.ui.components.grid.Header;
 import com.vaadin.ui.components.grid.Header.Row;
+import com.vaadin.ui.components.grid.SingleSelectionModel;
 import com.vaadin.ui.renderers.AbstractRenderer;
 import com.vaadin.ui.renderers.Renderer;
 import com.vaadin.ui.renderers.TextRenderer;
@@ -83,7 +83,7 @@ import elemental.json.JsonValue;
  * @param <T>
  *            the grid bean type
  */
-public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
+public class Grid<T> extends AbstractListing<T> implements HasComponents {
 
     @Deprecated
     private static final Method COLUMN_REORDER_METHOD = ReflectTools.findMethod(
@@ -120,6 +120,27 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
         void columnReorder(ColumnReorderEvent event);
     }
 
+    /**
+     * The server-side interface that controls Grid's selection state.
+     * SelectionModel should extend {@link AbstractGridExtension}.
+     *
+     * @param <T>
+     *            the grid bean type
+     */
+    public interface GridSelectionModel<T>
+            extends SelectionModel<T>, Extension {
+
+        /**
+         * Removes this selection model from the grid.
+         * <p>
+         * Must call super {@link Extension#remove()} to detach the extension,
+         * and fire an selection change event for the selection model (with an
+         * empty selection).
+         */
+        @Override
+        void remove();
+    }
+
     /**
      * An event listener for column resize events in the Grid.
      */
@@ -602,8 +623,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
                         .hasKey(diffStateKey) : "Field name has changed";
                 Type type = null;
                 try {
-                    type = (getState(false).getClass()
-                            .getDeclaredField(diffStateKey).getGenericType());
+                    type = getState(false).getClass()
+                            .getDeclaredField(diffStateKey).getGenericType();
                 } catch (NoSuchFieldException | SecurityException e) {
                     e.printStackTrace();
                 }
@@ -1488,163 +1509,6 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
         }
     }
 
-    private final class SingleSelection implements Single<T> {
-        private T selectedItem = null;
-
-        SingleSelection() {
-            addDataGenerator((item, json) -> {
-                if (isSelected(item)) {
-                    json.put(DataCommunicatorConstants.SELECTED, true);
-                }
-            });
-            registerRpc(new SelectionServerRpc() {
-
-                @Override
-                public void select(String key) {
-                    setSelectedFromClient(key);
-                }
-
-                @Override
-                public void deselect(String key) {
-                    if (isKeySelected(key)) {
-                        setSelectedFromClient(null);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public Optional<T> getSelectedItem() {
-            return Optional.ofNullable(selectedItem);
-        }
-
-        @Override
-        public void deselect(T item) {
-            Objects.requireNonNull(item, "deselected item cannot be null");
-            if (isSelected(item)) {
-                setSelectedFromServer(null);
-            }
-        }
-
-        @Override
-        public void select(T item) {
-            Objects.requireNonNull(item, "selected item cannot be null");
-            setSelectedFromServer(item);
-        }
-
-        /**
-         * Returns whether the given key maps to the currently selected item.
-         *
-         * @param key
-         *            the key to test or {@code null} to test whether nothing is
-         *            selected
-         * @return {@code true} if the key equals the key of the currently
-         *         selected item (or {@code null} if no selection),
-         *         {@code false} otherwise.
-         */
-        protected boolean isKeySelected(String key) {
-            return Objects.equals(key, getSelectedKey());
-        }
-
-        /**
-         * Returns the communication key of the selected item or {@code null} if
-         * no item is selected.
-         *
-         * @return the key of the selected item if any, {@code null} otherwise.
-         */
-        protected String getSelectedKey() {
-            return itemToKey(selectedItem);
-        }
-
-        /**
-         * Sets the selected item based on the given communication key. If the
-         * key is {@code null}, clears the current selection if any.
-         *
-         * @param key
-         *            the key of the selected item or {@code null} to clear
-         *            selection
-         */
-        protected void doSetSelectedKey(String key) {
-            if (selectedItem != null) {
-                getDataCommunicator().refresh(selectedItem);
-            }
-            selectedItem = keyToItem(key);
-            if (selectedItem != null) {
-                getDataCommunicator().refresh(selectedItem);
-            }
-        }
-
-        /**
-         * Sets the selection based on a client request. Does nothing if the
-         * select component is {@linkplain Component#isReadOnly()} or if the
-         * selection would not change. Otherwise updates the selection and fires
-         * a selection change event with {@code isUserOriginated == true}.
-         *
-         * @param key
-         *            the key of the item to select or {@code null} to clear
-         *            selection
-         */
-        protected void setSelectedFromClient(String key) {
-            if (isReadOnly()) {
-                return;
-            }
-            if (isKeySelected(key)) {
-                return;
-            }
-
-            doSetSelectedKey(key);
-            fireEvent(new SingleSelectionChangeEvent<>(Grid.this, true));
-        }
-
-        /**
-         * Sets the selection based on server API call. Does nothing if the
-         * selection would not change; otherwise updates the selection and fires
-         * a selection change event with {@code isUserOriginated == false}.
-         *
-         * @param item
-         *            the item to select or {@code null} to clear selection
-         */
-        protected void setSelectedFromServer(T item) {
-            // TODO creates a key if item not in data source
-            String key = itemToKey(item);
-
-            if (isKeySelected(key) || isSelected(item)) {
-                return;
-            }
-
-            doSetSelectedKey(key);
-            fireEvent(new SingleSelectionChangeEvent<>(Grid.this, false));
-        }
-
-        /**
-         * Returns the communication key assigned to the given item.
-         *
-         * @param item
-         *            the item whose key to return
-         * @return the assigned key
-         */
-        protected String itemToKey(T item) {
-            if (item == null) {
-                return null;
-            } else {
-                // TODO creates a key if item not in data source
-                return getDataCommunicator().getKeyMapper().key(item);
-            }
-        }
-
-        /**
-         * Returns the item that the given key is assigned to, or {@code null}
-         * if there is no such item.
-         *
-         * @param key
-         *            the key whose item to return
-         * @return the associated item if any, {@code null} otherwise.
-         */
-        protected T keyToItem(String key) {
-            return getDataCommunicator().getKeyMapper().get(key);
-        }
-    }
-
     /**
      * A header row in a Grid.
      */
@@ -1835,17 +1699,18 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
 
     private int counter = 0;
 
-    private Single<T> selectionModel;
+    private GridSelectionModel<T> selectionModel;
 
     /**
      * Constructor for the {@link Grid} component.
      */
     public Grid() {
-        setSelectionModel(new SingleSelection());
         registerRpc(new GridServerRpcImpl());
 
         setDefaultHeaderRow(appendHeaderRow());
 
+        selectionModel = new SingleSelectionModel<>(this);
+
         detailsManager = new DetailsManager<>();
         addExtension(detailsManager);
         addDataGenerator(detailsManager);
@@ -2690,30 +2555,40 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents {
      *
      * @return the selection model, not null
      */
-    public Single<T> getSelectionModel() {
+    public GridSelectionModel<T> getSelectionModel() {
         assert selectionModel != null : "No selection model set by "
                 + getClass().getName() + " constructor";
         return selectionModel;
     }
 
-    @Override
-    public Optional<T> getSelectedItem() {
-        return getSelectionModel().getSelectedItem();
+    /**
+     * Use this grid as a single select in {@link Binder}.
+     * <p>
+     * Sets the grid to single select mode, if not yet so.
+     *
+     * @return the single select wrapper that can be used in binder
+     */
+    public SingleSelect<T> asSingleSelect() {
+        GridSelectionModel<T> model = getSelectionModel();
+        if (!(model instanceof SingleSelectionModel)) {
+            model = new SingleSelectionModel<>(this);
+            setSelectionModel(model);
+        }
+
+        return ((SingleSelectionModel<T>) model).asSingleSelect();
     }
 
     /**
      * Sets the selection model for this listing.
+     * <p>
+     * The default selection model is {@link SingleSelectionModel}.
      *
      * @param model
-     *            the selection model to use, not null
+     *            the selection model to use, not {@code null}
      */
-    protected void setSelectionModel(Single<T> model) {
-        if (selectionModel != null) {
-            throw new IllegalStateException(
-                    "A selection model can't be changed.");
-        }
-
+    protected void setSelectionModel(GridSelectionModel<T> model) {
         Objects.requireNonNull(model, "selection model cannot be null");
+        selectionModel.remove();
         selectionModel = model;
     }
 
index ec200082ab835e4d7fac92482b4a117caa3a84be..f762aae827da6bb3258945f5c210c5f57de0e8c7 100644 (file)
@@ -62,7 +62,7 @@ public class ColorPickerSelect extends CustomField<Color> {
         range.setWidth("100%");
         range.addValueChangeListener(this::valueChange);
 
-        range.select(ColorRange.ALL);
+        range.setValue(ColorRange.ALL);
 
         layout.addComponent(range);
 
@@ -90,20 +90,20 @@ public class ColorPickerSelect extends CustomField<Color> {
 
         for (int row = 0; row < rows; row++) {
             for (int col = 0; col < columns; col++) {
-                if (row < (rows - 1)) {
+                if (row < rows - 1) {
                     // Create the color grid by varying the saturation and value
 
                     // Calculate new hue value
-                    float hue = ((float) col / (float) columns);
+                    float hue = (float) col / (float) columns;
                     float saturation = 1f;
                     float value = 1f;
 
                     // For the upper half use value=1 and variable
                     // saturation
-                    if (row < (rows / 2)) {
-                        saturation = ((row + 1f) / (rows / 2f));
+                    if (row < rows / 2) {
+                        saturation = (row + 1f) / (rows / 2f);
                     } else {
-                        value = 1f - ((row - (rows / 2f)) / (rows / 2f));
+                        value = 1f - (row - rows / 2f) / (rows / 2f);
                     }
 
                     colors[row][col] = new Color(
@@ -112,7 +112,7 @@ public class ColorPickerSelect extends CustomField<Color> {
                     // The last row should have the black&white gradient
                     float hue = 0f;
                     float saturation = 0f;
-                    float value = 1f - ((float) col / (float) columns);
+                    float value = 1f - (float) col / (float) columns;
 
                     colors[row][col] = new Color(
                             Color.HSVtoRGB(hue, saturation, value));
@@ -151,13 +151,11 @@ public class ColorPickerSelect extends CustomField<Color> {
                 saturation = 1f;
                 value = 1f;
 
-                if (index <= ((rows * columns) / 2)) {
-                    saturation = index
-                            / (((float) rows * (float) columns) / 2f);
+                if (index <= rows * columns / 2) {
+                    saturation = index / ((float) rows * (float) columns / 2f);
                 } else {
-                    index -= ((rows * columns) / 2);
-                    value = 1f
-                            - index / (((float) rows * (float) columns) / 2f);
+                    index -= rows * columns / 2;
+                    value = 1f - index / ((float) rows * (float) columns / 2f);
                 }
 
                 colors[row][col] = new Color(
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/SingleSelectionModel.java b/server/src/main/java/com/vaadin/ui/components/grid/SingleSelectionModel.java
new file mode 100644 (file)
index 0000000..bf2f556
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * 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.ui.components.grid;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import com.vaadin.data.SelectionModel;
+import com.vaadin.event.selection.SingleSelectionEvent;
+import com.vaadin.event.selection.SingleSelectionListener;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.data.DataCommunicatorConstants;
+import com.vaadin.shared.data.selection.SelectionServerRpc;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.AbstractGridExtension;
+import com.vaadin.ui.Grid.GridSelectionModel;
+import com.vaadin.ui.SingleSelect;
+import com.vaadin.util.ReflectTools;
+
+import elemental.json.JsonObject;
+
+/**
+ * Single selection model for grid.
+ *
+ * @author Vaadin Ltd.
+ * @since 8.0
+ *
+ * @param <T>
+ *            the type of the selected item in grid.
+ */
+public class SingleSelectionModel<T> extends AbstractGridExtension<T>
+        implements GridSelectionModel<T>, SelectionModel.Single<T> {
+
+    private static final Method SELECTION_CHANGE_METHOD = ReflectTools
+            .findMethod(SingleSelectionListener.class, "accept",
+                    SingleSelectionEvent.class);
+
+    private final Grid<T> grid;
+    private T selectedItem = null;
+
+    /**
+     * Constructs a new single selection model for the given grid.
+     *
+     * @param grid
+     *            the grid to bind the selection model into
+     */
+    public SingleSelectionModel(Grid<T> grid) {
+        this.grid = grid;
+        extend(grid);
+        registerRpc(new SelectionServerRpc() {
+
+            @Override
+            public void select(String key) {
+                setSelectedFromClient(key);
+            }
+
+            @Override
+            public void deselect(String key) {
+                if (isKeySelected(key)) {
+                    setSelectedFromClient(null);
+                }
+            }
+        });
+    }
+
+    /**
+     * Adds a selection change listener to this select. The listener is called
+     * when the value of this select is changed either by the user or
+     * programmatically.
+     *
+     * @param listener
+     *            the value change listener, not null
+     * @return a registration for the listener
+     */
+    public Registration addSelectionChangeListener(
+            SingleSelectionListener<T> listener) {
+        addListener(SingleSelectionEvent.class, listener,
+                SELECTION_CHANGE_METHOD);
+        return () -> removeListener(SingleSelectionEvent.class, listener);
+    }
+
+    @Override
+    public Optional<T> getSelectedItem() {
+        return Optional.ofNullable(selectedItem);
+    }
+
+    @Override
+    public void deselect(T item) {
+        Objects.requireNonNull(item, "deselected item cannot be null");
+        if (isSelected(item)) {
+            setSelectedFromServer(null);
+        }
+    }
+
+    @Override
+    public void select(T item) {
+        Objects.requireNonNull(item, "selected item cannot be null");
+        setSelectedFromServer(item);
+    }
+
+    /**
+     * Returns whether the given key maps to the currently selected item.
+     *
+     * @param key
+     *            the key to test or {@code null} to test whether nothing is
+     *            selected
+     * @return {@code true} if the key equals the key of the currently selected
+     *         item (or {@code null} if no selection), {@code false} otherwise.
+     */
+    protected boolean isKeySelected(String key) {
+        return Objects.equals(key, getSelectedKey());
+    }
+
+    /**
+     * Returns the communication key of the selected item or {@code null} if no
+     * item is selected.
+     *
+     * @return the key of the selected item if any, {@code null} otherwise.
+     */
+    protected String getSelectedKey() {
+        return itemToKey(selectedItem);
+    }
+
+    /**
+     * Sets the selected item based on the given communication key. If the key
+     * is {@code null}, clears the current selection if any.
+     *
+     * @param key
+     *            the key of the selected item or {@code null} to clear
+     *            selection
+     */
+    protected void doSetSelectedKey(String key) {
+        if (selectedItem != null) {
+            grid.getDataCommunicator().refresh(selectedItem);
+        }
+        selectedItem = getData(key);
+        if (selectedItem != null) {
+            grid.getDataCommunicator().refresh(selectedItem);
+        }
+    }
+
+    /**
+     * Sets the selection based on a client request. Does nothing if the select
+     * component is {@linkplain Component#isReadOnly()} or if the selection
+     * would not change. Otherwise updates the selection and fires a selection
+     * change event with {@code isUserOriginated == true}.
+     *
+     * @param key
+     *            the key of the item to select or {@code null} to clear
+     *            selection
+     */
+    protected void setSelectedFromClient(String key) {
+        if (isKeySelected(key)) {
+            return;
+        }
+
+        doSetSelectedKey(key);
+        fireEvent(
+                new SingleSelectionEvent<>(grid, asSingleSelect(), true));
+    }
+
+    /**
+     * Sets the selection based on server API call. Does nothing if the
+     * selection would not change; otherwise updates the selection and fires a
+     * selection change event with {@code isUserOriginated == false}.
+     *
+     * @param item
+     *            the item to select or {@code null} to clear selection
+     */
+    protected void setSelectedFromServer(T item) {
+        // TODO creates a key if item not in data source
+        String key = itemToKey(item);
+
+        if (isSelected(item) || isKeySelected(key)) {
+            return;
+        }
+
+        doSetSelectedKey(key);
+        fireEvent(new SingleSelectionEvent<>(grid, asSingleSelect(),
+                false));
+    }
+
+    /**
+     * Returns the communication key assigned to the given item.
+     *
+     * @param item
+     *            the item whose key to return
+     * @return the assigned key
+     */
+    protected String itemToKey(T item) {
+        if (item == null) {
+            return null;
+        } else {
+            // TODO creates a key if item not in data source
+            return grid.getDataCommunicator().getKeyMapper().key(item);
+        }
+    }
+
+    @Override
+    public Set<T> getSelectedItems() {
+        if (selectedItem != null) {
+            return new HashSet<>(Arrays.asList(selectedItem));
+        } else {
+            return Collections.emptySet();
+        }
+    }
+
+    @Override
+    public void generateData(T item, JsonObject jsonObject) {
+        if (isSelected(item)) {
+            jsonObject.put(DataCommunicatorConstants.SELECTED, true);
+        }
+    }
+
+    @Override
+    public void remove() {
+        // when selection model changes, firing an event for selection change
+        // event fired before removing so that parent is still intact (in case
+        // needed)
+        selectedItem = null;
+        fireEvent(new SingleSelectionEvent<>(grid, asSingleSelect(),
+                false));
+
+        super.remove();
+    }
+
+    /**
+     * Gets a wrapper for using this grid as a single select in a binder.
+     *
+     * @return a single select wrapper for grid
+     */
+    public SingleSelect<T> asSingleSelect() {
+        return new SingleSelect<T>() {
+
+            @Override
+            public void setValue(T value) {
+                SingleSelectionModel.this.setSelectedFromServer(value);
+            }
+
+            @Override
+            public T getValue() {
+                return SingleSelectionModel.this.getSelectedItem().orElse(null);
+            }
+
+            @Override
+            public Registration addValueChangeListener(
+                    com.vaadin.data.HasValue.ValueChangeListener<T> listener) {
+                return SingleSelectionModel.this.addSelectionChangeListener(
+                        event -> listener.accept(event));
+            }
+
+            @Override
+            public void setRequiredIndicatorVisible(
+                    boolean requiredIndicatorVisible) {
+                // TODO support required indicator when grid is used in binder ?
+                throw new UnsupportedOperationException(
+                        "Required indicator is not supported for Grid.");
+            }
+
+            @Override
+            public boolean isRequiredIndicatorVisible() {
+                throw new UnsupportedOperationException(
+                        "Required indicator is not supported for Grid.");
+            }
+
+            @Override
+            public void setReadOnly(boolean readOnly) {
+                // TODO support read only when grid is used in binder ?
+                throw new UnsupportedOperationException(
+                        "Read only is not supported for Grid.");
+            }
+
+            @Override
+            public boolean isReadOnly() {
+                throw new UnsupportedOperationException(
+                        "Read only is not supported for Grid.");
+            }
+        };
+    }
+}
\ No newline at end of file
index 00a946247d79389f301ae518d0127e23f938f3ff..a0ebe374fb8bab5a0f6385fc819b897a2af99a33 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -76,7 +76,7 @@ public class BinderSingleSelectTest
     public void bound_setSelection_beanValueUpdated() {
         bindSex();
 
-        select.select(Sex.MALE);
+        select.setValue(Sex.MALE);
 
         assertSame(Sex.MALE, item.getSex());
     }
@@ -86,7 +86,7 @@ public class BinderSingleSelectTest
         item.setSex(Sex.MALE);
         bindSex();
 
-        select.deselect(Sex.MALE);
+        select.setValue(null);
 
         assertNull(item.getSex());
     }
@@ -97,7 +97,7 @@ public class BinderSingleSelectTest
         bindSex();
         binder.removeBean();
 
-        select.select(Sex.FEMALE);
+        select.setValue(Sex.FEMALE);
 
         assertSame(Sex.UNKNOWN, item.getSex());
     }
diff --git a/server/src/test/java/com/vaadin/data/GridAsSingleSelectInBinder.java b/server/src/test/java/com/vaadin/data/GridAsSingleSelectInBinder.java
new file mode 100644 (file)
index 0000000..7b34c78
--- /dev/null
@@ -0,0 +1,157 @@
+package com.vaadin.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.tests.data.bean.Sex;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.SingleSelect;
+import com.vaadin.ui.components.grid.SingleSelectionModel;
+
+public class GridAsSingleSelectInBinder
+        extends BinderTestBase<Binder<Person>, Person> {
+
+    private class GridWithCustomSingleSelectionModel extends Grid<Sex> {
+        @Override
+        public void setSelectionModel(
+                com.vaadin.ui.Grid.GridSelectionModel<Sex> model) {
+            super.setSelectionModel(model);
+        }
+    }
+
+    private class CustomSingleSelectModel extends SingleSelectionModel<Sex> {
+
+        public CustomSingleSelectModel(Grid<Sex> grid) {
+            super(grid);
+        }
+
+        public void setSelectedFromClient(Sex item) {
+            setSelectedFromClient(itemToKey(item));
+        }
+    }
+
+    private Grid<Sex> grid;
+    private SingleSelect<Sex> select;
+
+    @Before
+    public void setup() {
+        binder = new Binder<>();
+        item = new Person();
+        grid = new Grid<>();
+        grid.setItems(Sex.values());
+        select = grid.asSingleSelect();
+    }
+
+    @Test
+    public void personBound_bindSelectByShortcut_selectionUpdated() {
+        item.setSex(Sex.FEMALE);
+        binder.setBean(item);
+        binder.bind(select, Person::getSex, Person::setSex);
+
+        assertSame(Sex.FEMALE, select.getValue());
+    }
+
+    @Test
+    public void personBound_bindSelect_selectionUpdated() {
+        item.setSex(Sex.MALE);
+        binder.setBean(item);
+        binder.forField(select).bind(Person::getSex, Person::setSex);
+
+        assertSame(Sex.MALE, select.getValue());
+    }
+
+    @Test
+    public void selectBound_bindPersonWithNullSex_selectedItemNotPresent() {
+        bindSex();
+
+        assertFalse(select.getValue() != null);
+    }
+
+    @Test
+    public void selectBound_bindPerson_selectionUpdated() {
+        item.setSex(Sex.FEMALE);
+        bindSex();
+
+        assertSame(Sex.FEMALE, select.getValue());
+    }
+
+    @Test
+    public void bound_setSelection_beanValueUpdated() {
+        bindSex();
+
+        select.setValue(Sex.MALE);
+
+        assertSame(Sex.MALE, item.getSex());
+    }
+
+    @Test
+    public void bound_deselect_beanValueUpdatedToNull() {
+        item.setSex(Sex.MALE);
+        bindSex();
+
+        select.setValue(null);
+
+        assertNull(item.getSex());
+    }
+
+    @Test
+    public void unbound_changeSelection_beanValueNotUpdated() {
+        item.setSex(Sex.UNKNOWN);
+        bindSex();
+        binder.removeBean();
+
+        select.setValue(Sex.FEMALE);
+
+        assertSame(Sex.UNKNOWN, item.getSex());
+    }
+
+    @Test
+    public void addValueChangeListener_selectionUpdated_eventTriggeredForSelect() {
+        binder = new Binder<>();
+        item = new Person();
+        GridWithCustomSingleSelectionModel grid = new GridWithCustomSingleSelectionModel();
+        CustomSingleSelectModel model = new CustomSingleSelectModel(grid);
+        grid.setSelectionModel(model);
+        grid.setItems(Sex.values());
+        select = grid.asSingleSelect();
+
+        List<Sex> selected = new ArrayList<>();
+        List<Boolean> userOriginated = new ArrayList<>();
+        select.addValueChangeListener(event -> {
+            selected.add(event.getValue());
+            userOriginated.add(event.isUserOriginated());
+            assertSame(grid, event.getComponent());
+            // cannot compare that the event source is the select since a new
+            // SingleSelect wrapper object has been created for the event
+            assertSame(select.getValue(), event.getValue());
+        });
+
+        grid.getSelectionModel().select(Sex.UNKNOWN);
+        model.setSelectedFromClient(Sex.MALE); // simulates client side
+                                               // selection
+        grid.getSelectionModel().select(Sex.MALE); // NOOP
+        grid.getSelectionModel().deselect(Sex.UNKNOWN); // NOOP
+        model.setSelectedFromClient(null); // simulates deselect from client
+                                           // side
+        grid.getSelectionModel().select(Sex.FEMALE);
+
+        assertEquals(Arrays.asList(Sex.UNKNOWN, Sex.MALE, null, Sex.FEMALE),
+                selected);
+        assertEquals(Arrays.asList(false, true, true, false), userOriginated);
+    }
+
+    protected void bindSex() {
+        binder.forField(select).bind(Person::getSex, Person::setSex);
+        binder.setBean(item);
+    }
+}
index 006025c197dee5331bbf326a7a9bd11d2853634a..97a6ed03d15ae1d0ec49d7336b708bcf594e33ed 100644 (file)
@@ -51,8 +51,8 @@ public class SelectionEventTest {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Test
     public void getFirstSelected_singleSelectEvent() {
-        SingleSelectionChangeEvent event = Mockito
-                .mock(SingleSelectionChangeEvent.class);
+        SingleSelectionEvent event = Mockito
+                .mock(SingleSelectionEvent.class);
         Mockito.doCallRealMethod().when(event).getFirstSelected();
 
         Mockito.when(event.getSelectedItem()).thenReturn(Optional.of("foo"));
diff --git a/server/src/test/java/com/vaadin/tests/components/grid/GridSelectionTest.java b/server/src/test/java/com/vaadin/tests/components/grid/GridSelectionTest.java
deleted file mode 100644 (file)
index 572413b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.vaadin.tests.components.grid;
-
-import java.util.Optional;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.vaadin.ui.Grid;
-
-public class GridSelectionTest {
-
-    Grid<String> grid;
-
-    @Before
-    public void setUp() {
-        grid = new Grid<>();
-        grid.setItems("Foo", "Bar");
-    }
-
-    @Test
-    public void testGridWithSingleSelection() {
-        Assert.assertFalse(grid.getSelectionModel().isSelected("Foo"));
-        grid.getSelectionModel().select("Foo");
-        Assert.assertTrue(grid.getSelectionModel().isSelected("Foo"));
-        Assert.assertEquals(Optional.of("Foo"), grid.getSelectedItem());
-        grid.getSelectionModel().select("Bar");
-        Assert.assertFalse(grid.getSelectionModel().isSelected("Foo"));
-        Assert.assertTrue(grid.getSelectionModel().isSelected("Bar"));
-        grid.getSelectionModel().deselect("Bar");
-        Assert.assertFalse(grid.getSelectionModel().isSelected("Bar"));
-        Assert.assertFalse(
-                grid.getSelectionModel().getSelectedItem().isPresent());
-    }
-
-}
diff --git a/server/src/test/java/com/vaadin/tests/components/grid/GridSingleSelectionModelTest.java b/server/src/test/java/com/vaadin/tests/components/grid/GridSingleSelectionModelTest.java
new file mode 100644 (file)
index 0000000..9746e2e
--- /dev/null
@@ -0,0 +1,244 @@
+package com.vaadin.tests.components.grid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.vaadin.data.HasValue.ValueChangeEvent;
+import com.vaadin.event.selection.SingleSelectionEvent;
+import com.vaadin.event.selection.SingleSelectionListener;
+import com.vaadin.server.data.datasource.bov.Person;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.data.DataCommunicatorClientRpc;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.GridSelectionModel;
+import com.vaadin.ui.components.grid.SingleSelectionModel;
+
+public class GridSingleSelectionModelTest {
+
+    public static final Person PERSON_C = new Person("c", 3);
+    public static final Person PERSON_B = new Person("b", 2);
+    public static final Person PERSON_A = new Person("a", 1);
+    public static final String RPC_INTERFACE = DataCommunicatorClientRpc.class
+            .getName();
+
+    private class CustomSelectionModelGrid extends Grid<String> {
+        public void switchSelectionModel() {
+            // just switch selection model to cause event
+            setSelectionModel(new SingleSelectionModel(this));
+        }
+    }
+
+    private List<Person> selectionChanges;
+    private Grid<Person> grid;
+    private SingleSelectionModel<Person> selectionModel;
+
+    @Before
+    public void setUp() {
+        grid = new Grid<>();
+        grid.setItems(PERSON_A, PERSON_B, PERSON_C);
+        selectionModel = (SingleSelectionModel<Person>) grid
+                .getSelectionModel();
+
+        selectionChanges = new ArrayList<>();
+        selectionModel.addSelectionChangeListener(
+                e -> selectionChanges.add(e.getValue()));
+    }
+
+    @Test
+    public void testGridChangingSelectionModel_firesSelectionChangeEvent() {
+        CustomSelectionModelGrid customGrid = new CustomSelectionModelGrid();
+        customGrid.setItems("Foo", "Bar", "Baz");
+
+        List<String> selectionChanges = new ArrayList<>();
+        ((SingleSelectionModel<String>) customGrid.getSelectionModel())
+                .addSelectionChangeListener(
+                        e -> selectionChanges.add(e.getValue()));
+
+        customGrid.getSelectionModel().select("Foo");
+        assertEquals("Foo",
+                customGrid.getSelectionModel().getFirstSelectedItem().get());
+        assertEquals(Arrays.asList("Foo"), selectionChanges);
+
+        customGrid.switchSelectionModel();
+        assertEquals(Arrays.asList("Foo", null), selectionChanges);
+    }
+
+    @Test
+    public void testGridWithSingleSelection() {
+        Grid<String> gridWithStrings = new Grid<>();
+        gridWithStrings.setItems("Foo", "Bar", "Baz");
+
+        GridSelectionModel<String> model = gridWithStrings.getSelectionModel();
+        Assert.assertFalse(model.isSelected("Foo"));
+
+        model.select("Foo");
+        Assert.assertTrue(model.isSelected("Foo"));
+        Assert.assertEquals(Optional.of("Foo"), model.getFirstSelectedItem());
+
+        model.select("Bar");
+        Assert.assertFalse(model.isSelected("Foo"));
+        Assert.assertTrue(model.isSelected("Bar"));
+
+        model.deselect("Bar");
+        Assert.assertFalse(model.isSelected("Bar"));
+        Assert.assertFalse(model.getFirstSelectedItem().isPresent());
+    }
+
+    @Test
+    public void select_isSelected() {
+        selectionModel.select(PERSON_B);
+
+        assertTrue(selectionModel.getSelectedItem().isPresent());
+
+        assertEquals(PERSON_B, selectionModel.getSelectedItem().orElse(null));
+
+        assertFalse(selectionModel.isSelected(PERSON_A));
+        assertTrue(selectionModel.isSelected(PERSON_B));
+        assertFalse(selectionModel.isSelected(PERSON_C));
+
+        assertEquals(Optional.of(PERSON_B), selectionModel.getSelectedItem());
+
+        assertEquals(Arrays.asList(PERSON_B), selectionChanges);
+    }
+
+    @Test
+    public void selectDeselect() {
+
+        selectionModel.select(PERSON_B);
+        selectionModel.deselect(PERSON_B);
+
+        assertFalse(selectionModel.getSelectedItem().isPresent());
+
+        assertFalse(selectionModel.isSelected(PERSON_A));
+        assertFalse(selectionModel.isSelected(PERSON_B));
+        assertFalse(selectionModel.isSelected(PERSON_C));
+
+        assertFalse(selectionModel.getSelectedItem().isPresent());
+
+        assertEquals(Arrays.asList(PERSON_B, null), selectionChanges);
+    }
+
+    @Test
+    public void reselect() {
+        selectionModel.select(PERSON_B);
+        selectionModel.select(PERSON_C);
+
+        assertEquals(PERSON_C, selectionModel.getSelectedItem().orElse(null));
+
+        assertFalse(selectionModel.isSelected(PERSON_A));
+        assertFalse(selectionModel.isSelected(PERSON_B));
+        assertTrue(selectionModel.isSelected(PERSON_C));
+
+        assertEquals(Optional.of(PERSON_C), selectionModel.getSelectedItem());
+
+        assertEquals(Arrays.asList(PERSON_B, PERSON_C), selectionChanges);
+    }
+
+    @Test
+    public void selectTwice() {
+
+        selectionModel.select(PERSON_C);
+        selectionModel.select(PERSON_C);
+
+        assertEquals(PERSON_C, selectionModel.getSelectedItem().orElse(null));
+
+        assertFalse(selectionModel.isSelected(PERSON_A));
+        assertFalse(selectionModel.isSelected(PERSON_B));
+        assertTrue(selectionModel.isSelected(PERSON_C));
+
+        assertEquals(Optional.of(PERSON_C), selectionModel.getSelectedItem());
+
+        assertEquals(Arrays.asList(PERSON_C), selectionChanges);
+    }
+
+    @Test
+    public void deselectTwice() {
+
+        selectionModel.select(PERSON_C);
+        selectionModel.deselect(PERSON_C);
+        selectionModel.deselect(PERSON_C);
+
+        assertFalse(selectionModel.getSelectedItem().isPresent());
+
+        assertFalse(selectionModel.isSelected(PERSON_A));
+        assertFalse(selectionModel.isSelected(PERSON_B));
+        assertFalse(selectionModel.isSelected(PERSON_C));
+
+        assertFalse(selectionModel.getSelectedItem().isPresent());
+
+        assertEquals(Arrays.asList(PERSON_C, null), selectionChanges);
+    }
+
+    @Test
+    public void getSelectedItem() {
+        selectionModel.setSelectedItem(PERSON_B);
+
+        Assert.assertEquals(PERSON_B, selectionModel.getSelectedItem().get());
+
+        selectionModel.deselect(PERSON_B);
+        Assert.assertFalse(selectionModel.getSelectedItem().isPresent());
+    }
+
+    @Test
+    public void select_deselect_getSelectedItem() {
+        selectionModel.select(PERSON_C);
+
+        Assert.assertEquals(PERSON_C, selectionModel.getSelectedItem().get());
+
+        selectionModel.deselect(PERSON_C);
+
+        Assert.assertFalse(selectionModel.getSelectedItem().isPresent());
+    }
+
+    @SuppressWarnings({ "serial" })
+    @Test
+    public void addValueChangeListener() {
+        AtomicReference<SingleSelectionListener<String>> selectionListener = new AtomicReference<>();
+        Registration registration = Mockito.mock(Registration.class);
+        Grid<String> grid = new Grid<>();
+        grid.setItems("foo", "bar");
+        String value = "foo";
+        SingleSelectionModel<String> select = new SingleSelectionModel<String>(
+                grid) {
+            @Override
+            public Registration addSelectionChangeListener(
+                    SingleSelectionListener<String> listener) {
+                selectionListener.set(listener);
+                return registration;
+            }
+
+            @Override
+            public Optional<String> getSelectedItem() {
+                return Optional.of(value);
+            }
+        };
+
+        AtomicReference<ValueChangeEvent<?>> event = new AtomicReference<>();
+        Registration actualRegistration = select
+                .addSelectionChangeListener(evt -> {
+                    Assert.assertNull(event.get());
+                    event.set(evt);
+                });
+        Assert.assertSame(registration, actualRegistration);
+
+        selectionListener.get().accept(new SingleSelectionEvent<>(grid,
+                select.asSingleSelect(), true));
+
+        Assert.assertEquals(grid, event.get().getComponent());
+        Assert.assertEquals(value, event.get().getValue());
+        Assert.assertTrue(event.get().isUserOriginated());
+    }
+
+}
index 47f5fbc81d70daf7211319c384526857096c2ef4..b429afb600278f57380574380ef5f5f443601050 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * Copyright 2000-2014 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
@@ -21,10 +21,8 @@ import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Optional;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.junit.Assert;
@@ -33,7 +31,7 @@ import org.junit.Test;
 import org.mockito.Mockito;
 
 import com.vaadin.data.HasValue.ValueChangeEvent;
-import com.vaadin.event.selection.SingleSelectionChangeEvent;
+import com.vaadin.event.selection.SingleSelectionEvent;
 import com.vaadin.event.selection.SingleSelectionListener;
 import com.vaadin.server.data.datasource.bov.Person;
 import com.vaadin.shared.Registration;
@@ -56,7 +54,8 @@ public class AbstractSingleSelectTest {
         listing = new PersonListing();
         listing.setItems(PERSON_A, PERSON_B, PERSON_C);
         selectionChanges = new ArrayList<>();
-        listing.addSelectionListener(e -> selectionChanges.add(e.getValue()));
+        listing.addSelectionChangeListener(
+                e -> selectionChanges.add(e.getValue()));
     }
 
     public static final Person PERSON_C = new Person("c", 3);
@@ -69,7 +68,7 @@ public class AbstractSingleSelectTest {
     @Test
     public void select() {
 
-        listing.select(PERSON_B);
+        listing.setValue(PERSON_B);
 
         assertTrue(listing.getSelectedItem().isPresent());
 
@@ -87,8 +86,8 @@ public class AbstractSingleSelectTest {
     @Test
     public void selectDeselect() {
 
-        listing.select(PERSON_B);
-        listing.deselect(PERSON_B);
+        listing.setValue(PERSON_B);
+        listing.setValue(null);
 
         assertFalse(listing.getSelectedItem().isPresent());
 
@@ -104,8 +103,8 @@ public class AbstractSingleSelectTest {
     @Test
     public void reselect() {
 
-        listing.select(PERSON_B);
-        listing.select(PERSON_C);
+        listing.setValue(PERSON_B);
+        listing.setValue(PERSON_C);
 
         assertEquals(PERSON_C, listing.getSelectedItem().orElse(null));
 
@@ -118,28 +117,11 @@ public class AbstractSingleSelectTest {
         assertEquals(Arrays.asList(PERSON_B, PERSON_C), selectionChanges);
     }
 
-    @Test
-    public void deselectNoOp() {
-
-        listing.select(PERSON_C);
-        listing.deselect(PERSON_B);
-
-        assertEquals(PERSON_C, listing.getSelectedItem().orElse(null));
-
-        assertFalse(listing.isSelected(PERSON_A));
-        assertFalse(listing.isSelected(PERSON_B));
-        assertTrue(listing.isSelected(PERSON_C));
-
-        assertEquals(Optional.of(PERSON_C), listing.getSelectedItem());
-
-        assertEquals(Arrays.asList(PERSON_C), selectionChanges);
-    }
-
     @Test
     public void selectTwice() {
 
-        listing.select(PERSON_C);
-        listing.select(PERSON_C);
+        listing.setValue(PERSON_C);
+        listing.setValue(PERSON_C);
 
         assertEquals(PERSON_C, listing.getSelectedItem().orElse(null));
 
@@ -155,9 +137,9 @@ public class AbstractSingleSelectTest {
     @Test
     public void deselectTwice() {
 
-        listing.select(PERSON_C);
-        listing.deselect(PERSON_C);
-        listing.deselect(PERSON_C);
+        listing.setValue(PERSON_C);
+        listing.setValue(null);
+        listing.setValue(null);
 
         assertFalse(listing.getSelectedItem().isPresent());
 
@@ -176,7 +158,7 @@ public class AbstractSingleSelectTest {
 
         Assert.assertEquals(PERSON_B, listing.getValue());
 
-        listing.deselect(PERSON_B);
+        listing.setValue(null);
         Assert.assertNull(listing.getValue());
     }
 
@@ -220,7 +202,7 @@ public class AbstractSingleSelectTest {
         Mockito.verify(select).setSelectedItem(null);
     }
 
-    @SuppressWarnings({ "unchecked", "serial" })
+    @SuppressWarnings("serial")
     @Test
     public void addValueChangeListener() {
         AtomicReference<SingleSelectionListener<String>> selectionListener = new AtomicReference<>();
@@ -228,7 +210,7 @@ public class AbstractSingleSelectTest {
         String value = "foo";
         AbstractSingleSelect<String> select = new AbstractSingleSelect<String>() {
             @Override
-            public Registration addSelectionListener(
+            public Registration addSelectionChangeListener(
                     SingleSelectionListener<String> listener) {
                 selectionListener.set(listener);
                 return registration;
@@ -248,32 +230,11 @@ public class AbstractSingleSelectTest {
         Assert.assertSame(registration, actualRegistration);
 
         selectionListener.get()
-                .accept(new SingleSelectionChangeEvent<>(select, true));
+                .accept(new SingleSelectionEvent<>(select, true));
 
         Assert.assertEquals(select, event.get().getComponent());
         Assert.assertEquals(value, event.get().getValue());
         Assert.assertTrue(event.get().isUserOriginated());
     }
 
-    @Test
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public void setValue_isDelegatedToDeselectAndUpdateSelection() {
-        AbstractMultiSelect<String> select = Mockito
-                .mock(AbstractMultiSelect.class);
-
-        Set set = new LinkedHashSet<>();
-        set.add("foo1");
-        set.add("foo");
-        Set selected = new LinkedHashSet<>();
-        selected.add("bar1");
-        selected.add("bar");
-        selected.add("bar2");
-        Mockito.when(select.getSelectedItems()).thenReturn(selected);
-        Mockito.doCallRealMethod().when(select).setValue(Mockito.anySet());
-
-        select.setValue(set);
-
-        Mockito.verify(select).updateSelection(set, selected);
-    }
-
 }
index ea1cf393510ecc1e7eab2d1fc728995bd462308e..ec48a7479971acb3e64178c10c034602eafa45b2 100644 (file)
@@ -42,16 +42,16 @@ public class RadioButtonGroupTest {
     public void apiSelectionChange_notUserOriginated() {
         AtomicInteger listenerCount = new AtomicInteger(0);
 
-        radioButtonGroup.addSelectionListener(event -> {
+        radioButtonGroup.addSelectionChangeListener(event -> {
             listenerCount.incrementAndGet();
             Assert.assertFalse(event.isUserOriginated());
         });
 
-        radioButtonGroup.select("First");
-        radioButtonGroup.select("Second");
+        radioButtonGroup.setValue("First");
+        radioButtonGroup.setValue("Second");
 
-        radioButtonGroup.deselect("Second");
-        radioButtonGroup.deselect("Second");
+        radioButtonGroup.setValue(null);
+        radioButtonGroup.setValue(null);
 
         Assert.assertEquals(3, listenerCount.get());
     }
@@ -60,7 +60,7 @@ public class RadioButtonGroupTest {
     public void rpcSelectionChange_userOriginated() {
         AtomicInteger listenerCount = new AtomicInteger(0);
 
-        radioButtonGroup.addSelectionListener(event -> {
+        radioButtonGroup.addSelectionChangeListener(event -> {
             listenerCount.incrementAndGet();
             Assert.assertTrue(event.isUserOriginated());
         });
index a3c43adc1f0b4073ad62c7a74be6f701967697f6..2fa6abced839121234a876144862b3f5fdc527b2 100644 (file)
@@ -32,7 +32,7 @@ public abstract class AbstractSingleSelectTestUI<T extends AbstractSingleSelect<
 
     protected void createListenerMenu() {
         createListenerAction("Selection listener", "Listeners", c -> c
-                .addSelectionListener(e -> log("Selected: " + e.getValue())));
+                .addSelectionChangeListener(e -> log("Selected: " + e.getValue())));
     }
 
     protected void createSelectionMenu() {
@@ -46,12 +46,7 @@ public abstract class AbstractSingleSelectTestUI<T extends AbstractSingleSelect<
 
         createSelectAction("Select", "Selection", options, "None",
                 (component, selected, data) -> {
-                    if (selected != null) {
-                        component.select(selected);
-                    } else {
-                        component.getSelectedItem()
-                                .ifPresent(component::deselect);
-                    }
+                    component.setValue(selected);
                 });
     }
 
index cbd3c4ebcf1d42e12fb75e9774e8b6e2bcfa760a..dc87ee59e541e874964d3da29d236ac055c6ca95 100644 (file)
@@ -31,7 +31,7 @@ public class ComboBoxSelectingWithNewItemsAllowed extends ComboBoxSelecting {
         comboBox.setNewItemHandler(text -> {
             items.add(text);
             comboBox.setItems(items);
-            comboBox.select(text);
+            comboBox.setValue(text);
             label.setValue(String.valueOf(items.size()));
         });
 
index 96a2f313b9657d6950de22d7ad2ea326fcb4b832..59368b198b0d1769face501712d7a7c70d548f35 100644 (file)
@@ -30,6 +30,7 @@ import com.vaadin.ui.Notification;
 import com.vaadin.ui.Panel;
 import com.vaadin.ui.StyleGenerator;
 import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.components.grid.SingleSelectionModel;
 import com.vaadin.ui.renderers.DateRenderer;
 import com.vaadin.ui.renderers.HtmlRenderer;
 import com.vaadin.ui.renderers.NumberRenderer;
@@ -150,7 +151,7 @@ public class GridBasics extends AbstractTestUIWithLog {
                 .put("\"Watching\"",
                         dataObj -> new Label("You are watching item id "
                                 + dataObj.getRowNumber() + " ("
-                                + (watchingCount++) + ")"));
+                                + watchingCount++ + ")"));
         persistingDetails = new PersistingDetailsGenerator();
         generators.put("Persisting", persistingDetails);
     }
@@ -185,7 +186,8 @@ public class GridBasics extends AbstractTestUIWithLog {
         grid.addColumn(data -> data.getSmallRandom() / 5d,
                 new ProgressBarRenderer()).setCaption(COLUMN_CAPTIONS[7]);
 
-        grid.addSelectionListener(e -> log("Selected: " + e.getValue()));
+        ((SingleSelectionModel<DataObject>) grid.getSelectionModel())
+                .addSelectionChangeListener(e -> log("Selected: " + e.getValue()));
 
         layout.addComponent(createMenu());
         layout.addComponent(grid);
index 28c2e2035d8f2d000ee0bc74aa884e1e57cbad44..af5ecbf3a0c9d29f96948e139ab8dd5551795e91 100644 (file)
@@ -29,7 +29,7 @@ public class NativeSelectInit extends AbstractReindeerTestUI {
     protected void setup(VaadinRequest request) {
         NativeSelect<String> select = new NativeSelect<>();
         select.setItems("Foo", "Bar");
-        select.select("Bar");
+        select.setValue("Bar");
         addComponent(select);
     }
 
index 7230eb9017c9b5b5542a667b71a23bf94cd2d61f..246441598b3565be43a4e58c66c81cfdd9a0749a 100644 (file)
@@ -51,7 +51,7 @@ public class RadioButtonGroupTestUI
     protected void createSelectionMenu() {
         createClickAction("Clear selection", selectionCategory,
                 (component, item, data) -> component.getSelectedItem()
-                        .ifPresent(component::deselect),
+                        .ifPresent(value -> component.setValue(null)),
                 "");
 
         Command<RadioButtonGroup<Object>, String> toggleSelection = (component,
@@ -94,15 +94,15 @@ public class RadioButtonGroupTestUI
 
     private void toggleSelection(String item) {
         if (getComponent().isSelected(item)) {
-            getComponent().deselect(item);
+            getComponent().setValue(null);
         } else {
-            getComponent().select(item);
+            getComponent().setValue(item);
         }
     }
 
     protected void createListenerMenu() {
         createListenerAction("Selection listener", "Listeners",
-                c -> c.addSelectionListener(
+                c -> c.addSelectionChangeListener(
                         e -> log("Selected: " + e.getSelectedItem())));
     }
 
index 7157a205f41a132f718c27a024e06e75d80dc020..cc1e60e7b09a445aa133c290a272b94a98f3e7de 100644 (file)
@@ -33,7 +33,7 @@ public class DummyData extends AbstractTestUIWithLog {
 
         @Override
         public Stream<String> fetch(Query query) {
-            log("Backend request #" + (count++));
+            log("Backend request #" + count++);
             return super.fetch(query);
         }
     }
@@ -61,7 +61,7 @@ public class DummyData extends AbstractTestUIWithLog {
         }
 
         @Override
-        public void select(String item) {
+        public void setValue(String item) {
             if (selected != null) {
                 getDataCommunicator().refresh(selected);
             }
@@ -71,12 +71,6 @@ public class DummyData extends AbstractTestUIWithLog {
             }
         }
 
-        @Override
-        public void deselect(String item) {
-            if (item == selected) {
-                select(null);
-            }
-        }
     }
 
     @Override
@@ -87,12 +81,12 @@ public class DummyData extends AbstractTestUIWithLog {
             items.add("Foo " + i);
         }
         dummy.setDataSource(new LoggingDataSource(items));
-        dummy.select("Foo 200");
+        dummy.setValue("Foo 200");
 
         HorizontalLayout controls = new HorizontalLayout();
         addComponent(controls);
         controls.addComponent(new Button("Select Foo 20", e -> {
-            dummy.select("Foo " + 20);
+            dummy.setValue("Foo " + 20);
         }));
         controls.addComponent(new Button("Reset data source", e -> {
             dummy.setDataSource(new LoggingDataSource(items));