]> source.dussan.org Git - vaadin-framework.git/commitdiff
Update ComboBox for new DataSource and communication mechanism
authorHenri Sara <hesara@vaadin.com>
Thu, 25 Aug 2016 09:57:37 +0000 (12:57 +0300)
committerVaadin Code Review <review@vaadin.com>
Mon, 12 Sep 2016 10:26:25 +0000 (10:26 +0000)
This simplifies the client side state machine.

This change does not modify the CSS class name v-filterselect.

Change-Id: I2f4a6e5252045cb7698d582be90693e00961b342

99 files changed:
client/src/main/java/com/vaadin/client/ui/JsniMousewheelHandler.java [new file with mode: 0644]
client/src/main/java/com/vaadin/client/ui/VComboBox.java [new file with mode: 0644]
client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java [new file with mode: 0644]
server/src/main/java/com/vaadin/ui/ComboBox.java [new file with mode: 0644]
shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxClientRpc.java [new file with mode: 0644]
shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxConstants.java [new file with mode: 0644]
shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxServerRpc.java [new file with mode: 0644]
shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxState.java [new file with mode: 0644]
uitest-common/src/main/java/com/vaadin/testbench/customelements/ComboBoxElement.java [new file with mode: 0644]
uitest/src/main/java/com/vaadin/tests/components/ErrorMessages.java
uitest/src/main/java/com/vaadin/tests/components/FocusAndBlurListeners.java
uitest/src/main/java/com/vaadin/tests/components/caption/IconsInCaption.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxBorder.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxClickIcon.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxCursorPositionReset.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxDuplicateCaption.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxEmptyItemsKeyboardNavigation.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxEnablesComboBox.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxInPopup.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxInputPrompt.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxInvalidNullSelection.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxItemIcon.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxLargeIcons.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxMouseSelectEnter.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxMousewheel.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxNavigation.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxParentDisable.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxPopupWhenBodyScrolls.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabled.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrows.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSelecting.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowed.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionOnDetach.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPageLength.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupClose.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidth.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacy.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentage.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixels.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxValoDoubleClick.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxValueUpdate.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboSelectedValueBeyondTheFirstDropdownPage.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboboxInPopupViewWithItems.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopen.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboboxPopupScrolling.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboboxPrimaryStyleNames.java
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboboxStyleChangeWidth.java
uitest/src/main/java/com/vaadin/tests/components/combobox/Comboboxes.java
uitest/src/main/java/com/vaadin/tests/components/combobox/EscapeClosesComboboxNotWindow.java [deleted file]
uitest/src/main/java/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java
uitest/src/main/java/com/vaadin/tests/components/combobox/GridLayoutComboBoxZoomOut.java
uitest/src/main/java/com/vaadin/tests/components/combobox/PopUpWidth.java
uitest/src/main/java/com/vaadin/tests/components/combobox/WidthToggleReadOnly.java
uitest/src/main/java/com/vaadin/tests/components/formlayout/CaptionEnableDisable.java
uitest/src/main/java/com/vaadin/tests/components/notification/NotificationsWaiAria.java
uitest/src/main/java/com/vaadin/tests/components/orderedlayout/InsertComponentInHorizontalLayout.java
uitest/src/main/java/com/vaadin/tests/components/orderedlayout/VaadinTunesLayout.java
uitest/src/main/java/com/vaadin/tests/components/panel/UndefinedSizeScrollbars.java
uitest/src/main/java/com/vaadin/tests/components/select/EnumSelect.java
uitest/src/main/java/com/vaadin/tests/components/select/SelectTest.java [deleted file]
uitest/src/main/java/com/vaadin/tests/components/select/StylingPopupOpener.java
uitest/src/main/java/com/vaadin/tests/components/table/DoublesInTable.java
uitest/src/main/java/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java
uitest/src/main/java/com/vaadin/tests/components/upload/DragAndDropUploadAndInteractions.java
uitest/src/main/java/com/vaadin/tests/components/window/ComboboxScrollableWindow.java
uitest/src/main/java/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.java
uitest/src/main/java/com/vaadin/tests/layouts/CaptionsInLayoutsWaiAria.java
uitest/src/main/java/com/vaadin/tests/layouts/MovingComponentsWhileOldParentInvisible.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxBorderTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxClickIconTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxEmptyItemsKeyboardNavigationTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxItemIconTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxLargeIconsTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxMouseSelectEnterTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxNoTextInputTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxPopupWhenBodyScrollsTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabledTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSelectingTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowedTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPageLengthTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupCloseTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthLegacyTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPercentageTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthPixelsTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupWidthTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboSelectedValueBeyondTheFirstDropdownPageTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopenTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboboxPopupScrollingTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboboxStyleChangeWidthTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java
uitest/src/test/java/com/vaadin/tests/components/select/EnumSelectTest.java
uitest/src/test/java/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java
uitest/src/test/java/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java

diff --git a/client/src/main/java/com/vaadin/client/ui/JsniMousewheelHandler.java b/client/src/main/java/com/vaadin/client/ui/JsniMousewheelHandler.java
new file mode 100644 (file)
index 0000000..7911b39
--- /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.ui;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.widgets.Escalator;
+
+/**
+ * A mousewheel handling class to get around the limits of
+ * {@link Event#ONMOUSEWHEEL}.
+ *
+ * For internal use only. May be removed or replaced in the future.
+ *
+ * @see Escalator.JsniWorkaround
+ */
+// FIXME remove the copy in v7 package
+abstract class JsniMousewheelHandler {
+
+    /**
+     * A JavaScript function that handles the mousewheel DOM event, and passes
+     * it on to Java code.
+     *
+     * @see #createMousewheelListenerFunction(Widget)
+     */
+    protected final JavaScriptObject mousewheelListenerFunction;
+
+    protected JsniMousewheelHandler(final Widget widget) {
+        mousewheelListenerFunction = createMousewheelListenerFunction(widget);
+    }
+
+    /**
+     * A method that constructs the JavaScript function that will be stored into
+     * {@link #mousewheelListenerFunction}.
+     *
+     * @param widget
+     *            a reference to the current instance of {@link Widget}
+     */
+    protected abstract JavaScriptObject createMousewheelListenerFunction(
+            Widget widget);
+
+    public native void attachMousewheelListener(Element element)
+    /*-{
+        if (element.addEventListener) {
+            // FireFox likes "wheel", while others use "mousewheel"
+            var eventName = 'onmousewheel' in element ? 'mousewheel' : 'wheel';
+            element.addEventListener(eventName, this.@com.vaadin.client.ui.JsniMousewheelHandler::mousewheelListenerFunction);
+        }
+    }-*/;
+
+    public native void detachMousewheelListener(Element element)
+    /*-{
+        if (element.addEventListener) {
+            // FireFox likes "wheel", while others use "mousewheel"
+            var eventName = element.onwheel===undefined?"mousewheel":"wheel";
+            element.removeEventListener(eventName, this.@com.vaadin.client.ui.JsniMousewheelHandler::mousewheelListenerFunction);
+        }
+    }-*/;
+
+}
diff --git a/client/src/main/java/com/vaadin/client/ui/VComboBox.java b/client/src/main/java/com/vaadin/client/ui/VComboBox.java
new file mode 100644 (file)
index 0000000..623393f
--- /dev/null
@@ -0,0 +1,2766 @@
+/*
+ * 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.ui;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.google.gwt.aria.client.Roles;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.dom.client.Style.Visibility;
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
+import com.google.gwt.event.dom.client.LoadEvent;
+import com.google.gwt.event.dom.client.LoadHandler;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.i18n.client.HasDirection.Direction;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
+import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.ComputedStyle;
+import com.vaadin.client.DeferredWorker;
+import com.vaadin.client.Focusable;
+import com.vaadin.client.VConsole;
+import com.vaadin.client.WidgetUtil;
+import com.vaadin.client.ui.aria.AriaHelper;
+import com.vaadin.client.ui.aria.HandlesAriaCaption;
+import com.vaadin.client.ui.aria.HandlesAriaInvalid;
+import com.vaadin.client.ui.aria.HandlesAriaRequired;
+import com.vaadin.client.ui.combobox.ComboBoxConnector;
+import com.vaadin.client.ui.menubar.MenuBar;
+import com.vaadin.client.ui.menubar.MenuItem;
+import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.ui.ComponentStateUtil;
+import com.vaadin.shared.util.SharedUtil;
+
+/**
+ * Client side implementation of the ComboBox component.
+ *
+ * TODO needs major refactoring (to be extensible etc)
+ */
+@SuppressWarnings("deprecation")
+public class VComboBox extends Composite implements Field, KeyDownHandler,
+        KeyUpHandler, ClickHandler, FocusHandler, BlurHandler, Focusable,
+        SubPartAware, HandlesAriaCaption, HandlesAriaInvalid,
+        HandlesAriaRequired, DeferredWorker, MouseDownHandler {
+
+    /**
+     * Represents a suggestion in the suggestion popup box.
+     */
+    public class ComboBoxSuggestion implements Suggestion, Command {
+
+        private final String key;
+        private final String caption;
+        private String untranslatedIconUri;
+        private String style;
+
+        /**
+         * Constructor for a single suggestion.
+         *
+         * @param key
+         *            item key, empty string for a special null item not in
+         *            container
+         * @param caption
+         *            item caption
+         * @param style
+         *            item style name, can be empty string
+         * @param untranslatedIconUri
+         *            icon URI or null
+         */
+        public ComboBoxSuggestion(String key, String caption, String style,
+                String untranslatedIconUri) {
+            this.key = key;
+            this.caption = caption;
+            this.style = style;
+            this.untranslatedIconUri = untranslatedIconUri;
+        }
+
+        /**
+         * Gets the visible row in the popup as a HTML string. The string
+         * contains an image tag with the rows icon (if an icon has been
+         * specified) and the caption of the item
+         */
+
+        @Override
+        public String getDisplayString() {
+            final StringBuffer sb = new StringBuffer();
+            ApplicationConnection client = connector.getConnection();
+            final Icon icon = client
+                    .getIcon(client.translateVaadinUri(untranslatedIconUri));
+            if (icon != null) {
+                sb.append(icon.getElement().getString());
+            }
+            String content;
+            if ("".equals(caption)) {
+                // Ensure that empty options use the same height as other
+                // options and are not collapsed (#7506)
+                content = "&nbsp;";
+            } else {
+                content = WidgetUtil.escapeHTML(caption);
+            }
+            sb.append("<span>" + content + "</span>");
+            return sb.toString();
+        }
+
+        /**
+         * Get a string that represents this item. This is used in the text box.
+         */
+
+        @Override
+        public String getReplacementString() {
+            return caption;
+        }
+
+        /**
+         * Get the option key which represents the item on the server side.
+         *
+         * @return The key of the item
+         */
+        public String getOptionKey() {
+            return key;
+        }
+
+        /**
+         * Get the URI of the icon. Used when constructing the displayed option.
+         *
+         * @return real (translated) icon URI or null if none
+         */
+        public String getIconUri() {
+            ApplicationConnection client = connector.getConnection();
+            return client.translateVaadinUri(untranslatedIconUri);
+        }
+
+        /**
+         * Gets the style set for this suggestion item. Styles are typically set
+         * by a server-side {@link com.vaadin.ui.ComboBox.ItemStyleProvider}.
+         * The returned style is prefixed by <code>v-filterselect-item-</code>.
+         *
+         * @since 7.5.6
+         * @return the style name to use, or <code>null</code> to not apply any
+         *         custom style.
+         */
+        public String getStyle() {
+            return style;
+        }
+
+        /**
+         * Executes a selection of this item.
+         */
+
+        @Override
+        public void execute() {
+            onSuggestionSelected(this);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof ComboBoxSuggestion)) {
+                return false;
+            }
+            ComboBoxSuggestion other = (ComboBoxSuggestion) obj;
+            if ((key == null && other.key != null)
+                    || (key != null && !key.equals(other.key))) {
+                return false;
+            }
+            if ((caption == null && other.caption != null)
+                    || (caption != null && !caption.equals(other.caption))) {
+                return false;
+            }
+            if (!SharedUtil.equals(untranslatedIconUri,
+                    other.untranslatedIconUri)) {
+                return false;
+            }
+            if (!SharedUtil.equals(style, other.style)) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    /** An inner class that handles all logic related to mouse wheel. */
+    private class MouseWheeler extends JsniMousewheelHandler {
+
+        public MouseWheeler() {
+            super(VComboBox.this);
+        }
+
+        @Override
+        protected native JavaScriptObject createMousewheelListenerFunction(
+                Widget widget)
+        /*-{
+            return $entry(function(e) {
+                var deltaX = e.deltaX ? e.deltaX : -0.5*e.wheelDeltaX;
+                var deltaY = e.deltaY ? e.deltaY : -0.5*e.wheelDeltaY;
+        
+                // IE8 has only delta y
+                if (isNaN(deltaY)) {
+                    deltaY = -0.5*e.wheelDelta;
+                }
+        
+                @com.vaadin.client.ui.VComboBox.JsniUtil::moveScrollFromEvent(*)(widget, deltaX, deltaY, e, e.deltaMode);
+            });
+        }-*/;
+
+    }
+
+    /**
+     * A utility class that contains utility methods that are usually called
+     * from JSNI.
+     * <p>
+     * The methods are moved in this class to minimize the amount of JSNI code
+     * as much as feasible.
+     */
+    static class JsniUtil {
+        private static final int DOM_DELTA_PIXEL = 0;
+        private static final int DOM_DELTA_LINE = 1;
+        private static final int DOM_DELTA_PAGE = 2;
+
+        // Rough estimation of item height
+        private static final int SCROLL_UNIT_PX = 25;
+
+        private static double deltaSum = 0;
+
+        public static void moveScrollFromEvent(final Widget widget,
+                final double deltaX, final double deltaY,
+                final NativeEvent event, final int deltaMode) {
+
+            if (!Double.isNaN(deltaY)) {
+                VComboBox filterSelect = (VComboBox) widget;
+
+                switch (deltaMode) {
+                case DOM_DELTA_LINE:
+                    if (deltaY >= 0) {
+                        filterSelect.suggestionPopup.selectNextItem();
+                    } else {
+                        filterSelect.suggestionPopup.selectPrevItem();
+                    }
+                    break;
+                case DOM_DELTA_PAGE:
+                    if (deltaY >= 0) {
+                        filterSelect.selectNextPage();
+                    } else {
+                        filterSelect.selectPrevPage();
+                    }
+                    break;
+                case DOM_DELTA_PIXEL:
+                default:
+                    // Accumulate dampened deltas
+                    deltaSum += Math.pow(Math.abs(deltaY), 0.7)
+                            * Math.signum(deltaY);
+
+                    // "Scroll" if change exceeds item height
+                    while (Math.abs(deltaSum) >= SCROLL_UNIT_PX) {
+                        if (!filterSelect.dataReceivedHandler
+                                .isWaitingForFilteringResponse()) {
+                            // Move selection if page flip is not in progress
+                            if (deltaSum < 0) {
+                                filterSelect.suggestionPopup.selectPrevItem();
+                            } else {
+                                filterSelect.suggestionPopup.selectNextItem();
+                            }
+                        }
+                        deltaSum -= SCROLL_UNIT_PX * Math.signum(deltaSum);
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Represents the popup box with the selection options. Wraps a suggestion
+     * menu.
+     */
+    public class SuggestionPopup extends VOverlay
+            implements PositionCallback, CloseHandler<PopupPanel> {
+
+        private static final int Z_INDEX = 30000;
+
+        /** For internal use only. May be removed or replaced in the future. */
+        public final SuggestionMenu menu;
+
+        private final Element up = DOM.createDiv();
+        private final Element down = DOM.createDiv();
+        private final Element status = DOM.createDiv();
+
+        private boolean isPagingEnabled = true;
+
+        private long lastAutoClosed;
+
+        private int popupOuterPadding = -1;
+
+        private int topPosition;
+
+        private final MouseWheeler mouseWheeler = new MouseWheeler();
+
+        /**
+         * Default constructor
+         */
+        SuggestionPopup() {
+            super(true, false);
+            debug("VComboBox.SP: constructor()");
+            setOwner(VComboBox.this);
+            menu = new SuggestionMenu();
+            setWidget(menu);
+
+            getElement().getStyle().setZIndex(Z_INDEX);
+
+            final Element root = getContainerElement();
+
+            up.setInnerHTML("<span>Prev</span>");
+            DOM.sinkEvents(up, Event.ONCLICK);
+
+            down.setInnerHTML("<span>Next</span>");
+            DOM.sinkEvents(down, Event.ONCLICK);
+
+            root.insertFirst(up);
+            root.appendChild(down);
+            root.appendChild(status);
+
+            DOM.sinkEvents(root, Event.ONMOUSEDOWN | Event.ONMOUSEWHEEL);
+            addCloseHandler(this);
+
+            Roles.getListRole().set(getElement());
+
+            setPreviewingAllNativeEvents(true);
+        }
+
+        @Override
+        protected void onLoad() {
+            super.onLoad();
+
+            // Register mousewheel listener on paged select
+            if (pageLength > 0) {
+                mouseWheeler.attachMousewheelListener(getElement());
+            }
+        }
+
+        @Override
+        protected void onUnload() {
+            mouseWheeler.detachMousewheelListener(getElement());
+            super.onUnload();
+        }
+
+        /**
+         * Shows the popup where the user can see the filtered options that have
+         * been set with a call to
+         * {@link SuggestionMenu#setSuggestions(Collection)}.
+         *
+         * @param currentPage
+         *            The current page number
+         * @param totalSuggestions
+         *            The total amount of suggestions
+         */
+        public void showSuggestions(final int currentPage,
+                final int totalSuggestions) {
+
+            debug("VComboBox.SP: showSuggestions(" + currentPage + ", "
+                    + totalSuggestions + ")");
+
+            final SuggestionPopup popup = this;
+            // Add TT anchor point
+            getElement().setId("VAADIN_COMBOBOX_OPTIONLIST");
+
+            final int x = VComboBox.this.getAbsoluteLeft();
+
+            topPosition = tb.getAbsoluteTop();
+            topPosition += tb.getOffsetHeight();
+
+            setPopupPosition(x, topPosition);
+
+            int nullOffset = (nullSelectionAllowed && "".equals(lastFilter) ? 1
+                    : 0);
+            boolean firstPage = (currentPage == 0);
+            final int first = currentPage * pageLength + 1
+                    - (firstPage ? 0 : nullOffset);
+            final int last = first + currentSuggestions.size() - 1
+                    - (firstPage && "".equals(lastFilter) ? nullOffset : 0);
+            final int matches = totalSuggestions - nullOffset;
+            if (last > 0) {
+                // nullsel not counted, as requested by user
+                status.setInnerText((matches == 0 ? 0 : first) + "-" + last
+                        + "/" + matches);
+            } else {
+                status.setInnerText("");
+            }
+            // We don't need to show arrows or statusbar if there is
+            // only one page
+            if (totalSuggestions <= pageLength || pageLength == 0) {
+                setPagingEnabled(false);
+            } else {
+                setPagingEnabled(true);
+            }
+            setPrevButtonActive(first > 1);
+            setNextButtonActive(last < matches);
+
+            // clear previously fixed width
+            menu.setWidth("");
+            menu.getElement().getFirstChildElement().getStyle().clearWidth();
+
+            setPopupPositionAndShow(popup);
+        }
+
+        /**
+         * Should the next page button be visible to the user?
+         *
+         * @param active
+         */
+        private void setNextButtonActive(boolean active) {
+            if (enableDebug) {
+                debug("VComboBox.SP: setNextButtonActive(" + active + ")");
+            }
+            if (active) {
+                DOM.sinkEvents(down, Event.ONCLICK);
+                down.setClassName(
+                        VComboBox.this.getStylePrimaryName() + "-nextpage");
+            } else {
+                DOM.sinkEvents(down, 0);
+                down.setClassName(
+                        VComboBox.this.getStylePrimaryName() + "-nextpage-off");
+            }
+        }
+
+        /**
+         * Should the previous page button be visible to the user
+         *
+         * @param active
+         */
+        private void setPrevButtonActive(boolean active) {
+            if (enableDebug) {
+                debug("VComboBox.SP: setPrevButtonActive(" + active + ")");
+            }
+
+            if (active) {
+                DOM.sinkEvents(up, Event.ONCLICK);
+                up.setClassName(
+                        VComboBox.this.getStylePrimaryName() + "-prevpage");
+            } else {
+                DOM.sinkEvents(up, 0);
+                up.setClassName(
+                        VComboBox.this.getStylePrimaryName() + "-prevpage-off");
+            }
+
+        }
+
+        /**
+         * Selects the next item in the filtered selections.
+         */
+        public void selectNextItem() {
+            debug("VComboBox.SP: selectNextItem()");
+
+            final int index = menu.getSelectedIndex() + 1;
+            if (menu.getItems().size() > index) {
+                selectItem(menu.getItems().get(index));
+
+            } else {
+                selectNextPage();
+            }
+        }
+
+        /**
+         * Selects the previous item in the filtered selections.
+         */
+        public void selectPrevItem() {
+            debug("VComboBox.SP: selectPrevItem()");
+
+            final int index = menu.getSelectedIndex() - 1;
+            if (index > -1) {
+                selectItem(menu.getItems().get(index));
+
+            } else if (index == -1) {
+                selectPrevPage();
+
+            } else {
+                if (!menu.getItems().isEmpty()) {
+                    selectLastItem();
+                }
+            }
+        }
+
+        /**
+         * Select the first item of the suggestions list popup.
+         *
+         * @since 7.2.6
+         */
+        public void selectFirstItem() {
+            debug("VComboBox.SP: selectFirstItem()");
+            selectItem(menu.getFirstItem());
+        }
+
+        /**
+         * Select the last item of the suggestions list popup.
+         *
+         * @since 7.2.6
+         */
+        public void selectLastItem() {
+            debug("VComboBox.SP: selectLastItem()");
+            selectItem(menu.getLastItem());
+        }
+
+        /*
+         * Sets the selected item in the popup menu.
+         */
+        private void selectItem(final MenuItem newSelectedItem) {
+            menu.selectItem(newSelectedItem);
+
+            // Set the icon.
+            ComboBoxSuggestion suggestion = (ComboBoxSuggestion) newSelectedItem
+                    .getCommand();
+            setSelectedItemIcon(suggestion.getIconUri());
+
+            // Set the text.
+            setText(suggestion.getReplacementString());
+
+        }
+
+        /*
+         * Using a timer to scroll up or down the pages so when we receive lots
+         * of consecutive mouse wheel events the pages does not flicker.
+         */
+        private LazyPageScroller lazyPageScroller = new LazyPageScroller();
+
+        private class LazyPageScroller extends Timer {
+            private int pagesToScroll = 0;
+
+            @Override
+            public void run() {
+                debug("VComboBox.SP.LPS: run()");
+                if (pagesToScroll != 0) {
+                    if (!dataReceivedHandler.isWaitingForFilteringResponse()) {
+                        /*
+                         * Avoid scrolling while we are waiting for a response
+                         * because otherwise the waiting flag will be reset in
+                         * the first response and the second response will be
+                         * ignored, causing an empty popup...
+                         *
+                         * As long as the scrolling delay is suitable
+                         * double/triple clicks will work by scrolling two or
+                         * three pages at a time and this should not be a
+                         * problem.
+                         */
+                        // this makes sure that we don't close the popup
+                        dataReceivedHandler.setNavigationCallback(() -> {
+                        });
+                        filterOptions(currentPage + pagesToScroll, lastFilter);
+                    }
+                    pagesToScroll = 0;
+                }
+            }
+
+            public void scrollUp() {
+                debug("VComboBox.SP.LPS: scrollUp()");
+                if (pageLength > 0 && currentPage + pagesToScroll > 0) {
+                    pagesToScroll--;
+                    cancel();
+                    schedule(200);
+                }
+            }
+
+            public void scrollDown() {
+                debug("VComboBox.SP.LPS: scrollDown()");
+                if (pageLength > 0
+                        && totalMatches > (currentPage + pagesToScroll + 1)
+                                * pageLength) {
+                    pagesToScroll++;
+                    cancel();
+                    schedule(200);
+                }
+            }
+        }
+
+        private void scroll(double deltaY) {
+            boolean scrollActive = menu.isScrollActive();
+
+            debug("VComboBox.SP: scroll() scrollActive: " + scrollActive);
+
+            if (!scrollActive) {
+                if (deltaY > 0d) {
+                    lazyPageScroller.scrollDown();
+                } else {
+                    lazyPageScroller.scrollUp();
+                }
+            }
+        }
+
+        @Override
+        public void onBrowserEvent(Event event) {
+            debug("VComboBox.SP: onBrowserEvent()");
+
+            if (event.getTypeInt() == Event.ONCLICK) {
+                final Element target = DOM.eventGetTarget(event);
+                if (target == up || target == DOM.getChild(up, 0)) {
+                    lazyPageScroller.scrollUp();
+                } else if (target == down || target == DOM.getChild(down, 0)) {
+                    lazyPageScroller.scrollDown();
+                }
+
+            }
+
+            /*
+             * Prevent the keyboard focus from leaving the textfield by
+             * preventing the default behaviour of the browser. Fixes #4285.
+             */
+            handleMouseDownEvent(event);
+        }
+
+        /**
+         * Should paging be enabled. If paging is enabled then only a certain
+         * amount of items are visible at a time and a scrollbar or buttons are
+         * visible to change page. If paging is turned of then all options are
+         * rendered into the popup menu.
+         *
+         * @param paging
+         *            Should the paging be turned on?
+         */
+        public void setPagingEnabled(boolean paging) {
+            debug("VComboBox.SP: setPagingEnabled(" + paging + ")");
+            if (isPagingEnabled == paging) {
+                return;
+            }
+            if (paging) {
+                down.getStyle().clearDisplay();
+                up.getStyle().clearDisplay();
+                status.getStyle().clearDisplay();
+            } else {
+                down.getStyle().setDisplay(Display.NONE);
+                up.getStyle().setDisplay(Display.NONE);
+                status.getStyle().setDisplay(Display.NONE);
+            }
+            isPagingEnabled = paging;
+        }
+
+        @Override
+        public void setPosition(int offsetWidth, int offsetHeight) {
+            debug("VComboBox.SP: setPosition(" + offsetWidth + ", "
+                    + offsetHeight + ")");
+
+            int top = topPosition;
+            int left = getPopupLeft();
+
+            // reset menu size and retrieve its "natural" size
+            menu.setHeight("");
+            if (currentPage > 0 && !hasNextPage()) {
+                // fix height to avoid height change when getting to last page
+                menu.fixHeightTo(pageLength);
+            }
+
+            // ignoring the parameter as in V7
+            offsetHeight = getOffsetHeight();
+            final int desiredHeight = offsetHeight;
+            final int desiredWidth = getMainWidth();
+
+            debug("VComboBox.SP:     desired[" + desiredWidth + ", "
+                    + desiredHeight + "]");
+
+            Element menuFirstChild = menu.getElement().getFirstChildElement();
+            int naturalMenuWidth;
+            if (BrowserInfo.get().isIE()
+                    && BrowserInfo.get().getBrowserMajorVersion() < 10) {
+                // On IE 8 & 9 visibility is set to hidden and measuring
+                // elements while they are hidden yields incorrect results
+                String before = menu.getElement().getParentElement().getStyle()
+                        .getVisibility();
+                menu.getElement().getParentElement().getStyle()
+                        .setVisibility(Visibility.VISIBLE);
+                naturalMenuWidth = WidgetUtil.getRequiredWidth(menuFirstChild);
+                menu.getElement().getParentElement().getStyle()
+                        .setProperty("visibility", before);
+            } else {
+                naturalMenuWidth = WidgetUtil.getRequiredWidth(menuFirstChild);
+            }
+
+            if (popupOuterPadding == -1) {
+                popupOuterPadding = WidgetUtil
+                        .measureHorizontalPaddingAndBorder(menu.getElement(), 2)
+                        + WidgetUtil.measureHorizontalPaddingAndBorder(
+                                suggestionPopup.getElement(), 0);
+            }
+
+            updateMenuWidth(desiredWidth, naturalMenuWidth);
+
+            if (BrowserInfo.get().isIE()
+                    && BrowserInfo.get().getBrowserMajorVersion() < 11) {
+                // Must take margin,border,padding manually into account for
+                // menu element as we measure the element child and set width to
+                // the element parent
+
+                double naturalMenuOuterWidth;
+                if (BrowserInfo.get().getBrowserMajorVersion() < 10) {
+                    // On IE 8 & 9 visibility is set to hidden and measuring
+                    // elements while they are hidden yields incorrect results
+                    String before = menu.getElement().getParentElement()
+                            .getStyle().getVisibility();
+                    menu.getElement().getParentElement().getStyle()
+                            .setVisibility(Visibility.VISIBLE);
+                    naturalMenuOuterWidth = WidgetUtil
+                            .getRequiredWidthDouble(menuFirstChild)
+                            + getMarginBorderPaddingWidth(menu.getElement());
+                    menu.getElement().getParentElement().getStyle()
+                            .setProperty("visibility", before);
+                } else {
+                    naturalMenuOuterWidth = WidgetUtil
+                            .getRequiredWidthDouble(menuFirstChild)
+                            + getMarginBorderPaddingWidth(menu.getElement());
+                }
+
+                /*
+                 * IE requires us to specify the width for the container
+                 * element. Otherwise it will be 100% wide
+                 */
+                double rootWidth = Math.max(desiredWidth - popupOuterPadding,
+                        naturalMenuOuterWidth);
+                getContainerElement().getStyle().setWidth(rootWidth, Unit.PX);
+            }
+
+            final int textInputHeight = VComboBox.this.getOffsetHeight();
+            final int textInputTopOnPage = tb.getAbsoluteTop();
+            final int viewportOffset = Document.get().getScrollTop();
+            final int textInputTopInViewport = textInputTopOnPage
+                    - viewportOffset;
+            final int textInputBottomInViewport = textInputTopInViewport
+                    + textInputHeight;
+
+            final int spaceAboveInViewport = textInputTopInViewport;
+            final int spaceBelowInViewport = Window.getClientHeight()
+                    - textInputBottomInViewport;
+
+            if (spaceBelowInViewport < offsetHeight
+                    && spaceBelowInViewport < spaceAboveInViewport) {
+                // popup on top of input instead
+                if (offsetHeight > spaceAboveInViewport) {
+                    // Shrink popup height to fit above
+                    offsetHeight = spaceAboveInViewport;
+                }
+                top = textInputTopOnPage - offsetHeight;
+            } else {
+                // Show below, position calculated in showSuggestions for some
+                // strange reason
+                top = topPosition;
+                offsetHeight = Math.min(offsetHeight, spaceBelowInViewport);
+            }
+
+            // fetch real width (mac FF bugs here due GWT popups overflow:auto )
+            offsetWidth = menuFirstChild.getOffsetWidth();
+
+            if (offsetHeight < desiredHeight) {
+                int menuHeight = offsetHeight;
+                if (isPagingEnabled) {
+                    menuHeight -= up.getOffsetHeight() + down.getOffsetHeight()
+                            + status.getOffsetHeight();
+                } else {
+                    final ComputedStyle s = new ComputedStyle(
+                            menu.getElement());
+                    menuHeight -= s.getIntProperty("marginBottom")
+                            + s.getIntProperty("marginTop");
+                }
+
+                // If the available page height is really tiny then this will be
+                // negative and an exception will be thrown on setHeight.
+                int menuElementHeight = menu.getItemOffsetHeight();
+                if (menuHeight < menuElementHeight) {
+                    menuHeight = menuElementHeight;
+                }
+
+                menu.setHeight(menuHeight + "px");
+
+                if (suggestionPopupWidth == null) {
+                    final int naturalMenuWidthPlusScrollBar = naturalMenuWidth
+                            + WidgetUtil.getNativeScrollbarSize();
+                    if (offsetWidth < naturalMenuWidthPlusScrollBar) {
+                        menu.setWidth(naturalMenuWidthPlusScrollBar + "px");
+                    }
+                }
+            }
+
+            if (offsetWidth + left > Window.getClientWidth()) {
+                left = VComboBox.this.getAbsoluteLeft()
+                        + VComboBox.this.getOffsetWidth() - offsetWidth;
+                if (left < 0) {
+                    left = 0;
+                    menu.setWidth(Window.getClientWidth() + "px");
+
+                }
+            }
+
+            setPopupPosition(left, top);
+            menu.scrollSelectionIntoView();
+        }
+
+        /**
+         * Adds in-line CSS rules to the DOM according to the
+         * suggestionPopupWidth field
+         *
+         * @param desiredWidth
+         * @param naturalMenuWidth
+         */
+        private void updateMenuWidth(final int desiredWidth,
+                int naturalMenuWidth) {
+            /**
+             * Three different width modes for the suggestion pop-up:
+             *
+             * 1. Legacy "null"-mode: width is determined by the longest item
+             * caption for each page while still maintaining minimum width of
+             * (desiredWidth - popupOuterPadding)
+             *
+             * 2. relative to the component itself
+             *
+             * 3. fixed width
+             */
+            String width = "auto";
+            if (suggestionPopupWidth == null) {
+                if (naturalMenuWidth < desiredWidth) {
+                    naturalMenuWidth = desiredWidth - popupOuterPadding;
+                    width = (desiredWidth - popupOuterPadding) + "px";
+                }
+            } else if (isrelativeUnits(suggestionPopupWidth)) {
+                float mainComponentWidth = desiredWidth - popupOuterPadding;
+                // convert percentage value to fraction
+                int widthInPx = Math.round(
+                        mainComponentWidth * asFraction(suggestionPopupWidth));
+                width = widthInPx + "px";
+            } else {
+                // use as fixed width CSS definition
+                width = WidgetUtil.escapeAttribute(suggestionPopupWidth);
+            }
+            menu.setWidth(width);
+        }
+
+        /**
+         * Returns the percentage value as a fraction, e.g. 42% -> 0.42
+         *
+         * @param percentage
+         */
+        private float asFraction(String percentage) {
+            String trimmed = percentage.trim();
+            String withoutPercentSign = trimmed.substring(0,
+                    trimmed.length() - 1);
+            float asFraction = Float.parseFloat(withoutPercentSign) / 100;
+            return asFraction;
+        }
+
+        /**
+         * @since 7.7
+         * @param suggestionPopupWidth
+         * @return
+         */
+        private boolean isrelativeUnits(String suggestionPopupWidth) {
+            return suggestionPopupWidth.trim().endsWith("%");
+        }
+
+        /**
+         * Was the popup just closed?
+         *
+         * @return true if popup was just closed
+         */
+        public boolean isJustClosed() {
+            debug("VComboBox.SP: justClosed()");
+            final long now = (new Date()).getTime();
+            return (lastAutoClosed > 0 && (now - lastAutoClosed) < 200);
+        }
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see
+         * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google
+         * .gwt.event.logical.shared.CloseEvent)
+         */
+
+        @Override
+        public void onClose(CloseEvent<PopupPanel> event) {
+            if (enableDebug) {
+                debug("VComboBox.SP: onClose(" + event.isAutoClosed() + ")");
+            }
+            if (event.isAutoClosed()) {
+                lastAutoClosed = (new Date()).getTime();
+            }
+        }
+
+        /**
+         * Updates style names in suggestion popup to help theme building.
+         *
+         * @param componentState
+         *            shared state of the combo box
+         */
+        public void updateStyleNames(AbstractComponentState componentState) {
+            debug("VComboBox.SP: updateStyleNames()");
+            setStyleName(
+                    VComboBox.this.getStylePrimaryName() + "-suggestpopup");
+            menu.setStyleName(
+                    VComboBox.this.getStylePrimaryName() + "-suggestmenu");
+            status.setClassName(
+                    VComboBox.this.getStylePrimaryName() + "-status");
+            if (ComponentStateUtil.hasStyles(componentState)) {
+                for (String style : componentState.styles) {
+                    if (!"".equals(style)) {
+                        addStyleDependentName(style);
+                    }
+                }
+            }
+        }
+
+    }
+
+    /**
+     * The menu where the suggestions are rendered
+     */
+    public class SuggestionMenu extends MenuBar
+            implements SubPartAware, LoadHandler {
+
+        private VLazyExecutor delayedImageLoadExecutioner = new VLazyExecutor(
+                100, new ScheduledCommand() {
+
+                    @Override
+                    public void execute() {
+                        debug("VComboBox.SM: delayedImageLoadExecutioner()");
+                        if (suggestionPopup.isVisible()
+                                && suggestionPopup.isAttached()) {
+                            setWidth("");
+                            getElement().getFirstChildElement().getStyle()
+                                    .clearWidth();
+                            suggestionPopup
+                                    .setPopupPositionAndShow(suggestionPopup);
+                        }
+
+                    }
+                });
+
+        /**
+         * Default constructor
+         */
+        SuggestionMenu() {
+            super(true);
+            debug("VComboBox.SM: constructor()");
+            addDomHandler(this, LoadEvent.getType());
+
+            setScrollEnabled(true);
+        }
+
+        /**
+         * Fixes menus height to use same space as full page would use. Needed
+         * to avoid height changes when quickly "scrolling" to last page.
+         */
+        public void fixHeightTo(int pageItemsCount) {
+            setHeight(getPreferredHeight(pageItemsCount));
+        }
+
+        /*
+         * Gets the preferred height of the menu including pageItemsCount items.
+         */
+        String getPreferredHeight(int pageItemsCount) {
+            if (currentSuggestions.size() > 0) {
+                final int pixels = (getPreferredHeight()
+                        / currentSuggestions.size()) * pageItemsCount;
+                return pixels + "px";
+            } else {
+                return "";
+            }
+        }
+
+        /**
+         * Sets the suggestions rendered in the menu.
+         *
+         * @param suggestions
+         *            The suggestions to be rendered in the menu
+         */
+        public void setSuggestions(Collection<ComboBoxSuggestion> suggestions) {
+            if (enableDebug) {
+                debug("VComboBox.SM: setSuggestions(" + suggestions + ")");
+            }
+
+            clearItems();
+            final Iterator<ComboBoxSuggestion> it = suggestions.iterator();
+            boolean isFirstIteration = true;
+            while (it.hasNext()) {
+                final ComboBoxSuggestion s = it.next();
+                final MenuItem mi = new MenuItem(s.getDisplayString(), true, s);
+                String style = s.getStyle();
+                if (style != null) {
+                    mi.addStyleName("v-filterselect-item-" + style);
+                }
+                Roles.getListitemRole().set(mi.getElement());
+
+                WidgetUtil.sinkOnloadForImages(mi.getElement());
+
+                this.addItem(mi);
+
+                // By default, first item on the list is always highlighted,
+                // unless adding new items is allowed.
+                if (isFirstIteration && !allowNewItems) {
+                    selectItem(mi);
+                }
+
+                if (currentSuggestion != null && s.getOptionKey()
+                        .equals(currentSuggestion.getOptionKey())) {
+                    // refresh also selected caption and icon in case they have
+                    // been updated on the server
+                    if (currentSuggestion.getReplacementString()
+                            .equals(tb.getText())) {
+                        currentSuggestion = s;
+                        selectItem(mi);
+                        setSelectedCaption(
+                                currentSuggestion.getReplacementString());
+                        setSelectedItemIcon(currentSuggestion.getIconUri());
+                    }
+                }
+
+                isFirstIteration = false;
+            }
+        }
+
+        /**
+         * Create/select a suggestion based on the used entered string. This
+         * method is called after filtering has completed with the given string.
+         *
+         * @param enteredItemValue
+         *            user entered string
+         */
+        public void actOnEnteredValueAfterFiltering(String enteredItemValue) {
+            debug("VComboBox.SM: doPostFilterSelectedItemAction()");
+            final MenuItem item = getSelectedItem();
+
+            // check for exact match in menu
+            int p = getItems().size();
+            if (p > 0) {
+                for (int i = 0; i < p; i++) {
+                    final MenuItem potentialExactMatch = getItems().get(i);
+                    if (potentialExactMatch.getText()
+                            .equals(enteredItemValue)) {
+                        selectItem(potentialExactMatch);
+                        // do not send a value change event if null was and
+                        // stays selected
+                        if (!"".equals(enteredItemValue)
+                                || (selectedOptionKey != null
+                                        && !"".equals(selectedOptionKey))) {
+                            doItemAction(potentialExactMatch, true);
+                        }
+                        suggestionPopup.hide();
+                        return;
+                    }
+                }
+            }
+            if ("".equals(enteredItemValue) && nullSelectionAllowed) {
+                onNullSelected();
+            } else if (allowNewItems) {
+                if (!enteredItemValue.equals(lastNewItemString)) {
+                    // Store last sent new item string to avoid double sends
+                    lastNewItemString = enteredItemValue;
+                    connector.sendNewItem(enteredItemValue);
+                    // TODO try to select the new value if it matches what was
+                    // sent for V7 compatibility
+                }
+            } else if (item != null && !"".equals(lastFilter) && (item.getText()
+                    .toLowerCase().contains(lastFilter.toLowerCase()))) {
+                doItemAction(item, true);
+            } else {
+                // currentSuggestion has key="" for nullselection
+                if (currentSuggestion != null
+                        && !currentSuggestion.key.equals("")) {
+                    // An item (not null) selected
+                    String text = currentSuggestion.getReplacementString();
+                    setText(text);
+                    selectedOptionKey = currentSuggestion.key;
+                } else {
+                    onNullSelected();
+                }
+            }
+            suggestionPopup.hide();
+        }
+
+        private static final String SUBPART_PREFIX = "item";
+
+        @Override
+        public com.google.gwt.user.client.Element getSubPartElement(
+                String subPart) {
+            int index = Integer
+                    .parseInt(subPart.substring(SUBPART_PREFIX.length()));
+
+            MenuItem item = getItems().get(index);
+
+            return item.getElement();
+        }
+
+        @Override
+        public String getSubPartName(
+                com.google.gwt.user.client.Element subElement) {
+            if (!getElement().isOrHasChild(subElement)) {
+                return null;
+            }
+
+            Element menuItemRoot = subElement;
+            while (menuItemRoot != null
+                    && !menuItemRoot.getTagName().equalsIgnoreCase("td")) {
+                menuItemRoot = menuItemRoot.getParentElement().cast();
+            }
+            // "menuItemRoot" is now the root of the menu item
+
+            final int itemCount = getItems().size();
+            for (int i = 0; i < itemCount; i++) {
+                if (getItems().get(i).getElement() == menuItemRoot) {
+                    String name = SUBPART_PREFIX + i;
+                    return name;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public void onLoad(LoadEvent event) {
+            debug("VComboBox.SM: onLoad()");
+            // Handle icon onload events to ensure shadow is resized
+            // correctly
+            delayedImageLoadExecutioner.trigger();
+
+        }
+
+        /**
+         * @deprecated use {@link SuggestionPopup#selectFirstItem()} instead.
+         */
+        @Deprecated
+        public void selectFirstItem() {
+            debug("VComboBox.SM: selectFirstItem()");
+            MenuItem firstItem = getItems().get(0);
+            selectItem(firstItem);
+        }
+
+        /**
+         * @deprecated use {@link SuggestionPopup#selectLastItem()} instead.
+         */
+        @Deprecated
+        public void selectLastItem() {
+            debug("VComboBox.SM: selectLastItem()");
+            List<MenuItem> items = getItems();
+            MenuItem lastItem = items.get(items.size() - 1);
+            selectItem(lastItem);
+        }
+
+        /*
+         * Gets the height of one menu item.
+         */
+        int getItemOffsetHeight() {
+            List<MenuItem> items = getItems();
+            return items != null && items.size() > 0
+                    ? items.get(0).getOffsetHeight() : 0;
+        }
+
+        /*
+         * Gets the width of one menu item.
+         */
+        int getItemOffsetWidth() {
+            List<MenuItem> items = getItems();
+            return items != null && items.size() > 0
+                    ? items.get(0).getOffsetWidth() : 0;
+        }
+
+        /**
+         * Returns true if the scroll is active on the menu element or if the
+         * menu currently displays the last page with less items then the
+         * maximum visibility (in which case the scroll is not active, but the
+         * scroll is active for any other page in general).
+         *
+         * @since 7.2.6
+         */
+        @Override
+        public boolean isScrollActive() {
+            String height = getElement().getStyle().getHeight();
+            String preferredHeight = getPreferredHeight(pageLength);
+
+            return !(height == null || height.length() == 0
+                    || height.equals(preferredHeight));
+        }
+
+        /**
+         * Highlight (select) an item matching the current text box content
+         * without triggering its action.
+         */
+        public void highlightSelectedItem() {
+            int p = getItems().size();
+            // first check if there is a key match to handle items with
+            // identical captions
+            String currentKey = currentSuggestion != null
+                    ? currentSuggestion.getOptionKey() : "";
+            for (int i = 0; i < p; i++) {
+                final MenuItem potentialExactMatch = getItems().get(i);
+                if (currentKey.equals(getSuggestionKey(potentialExactMatch))
+                        && tb.getText().equals(potentialExactMatch.getText())) {
+                    selectItem(potentialExactMatch);
+                    tb.setSelectionRange(tb.getText().length(), 0);
+                    return;
+                }
+            }
+            // then check for exact string match in menu
+            String text = tb.getText();
+            for (int i = 0; i < p; i++) {
+                final MenuItem potentialExactMatch = getItems().get(i);
+                if (potentialExactMatch.getText().equals(text)) {
+                    selectItem(potentialExactMatch);
+                    tb.setSelectionRange(tb.getText().length(), 0);
+                    return;
+                }
+            }
+        }
+    }
+
+    private String getSuggestionKey(MenuItem item) {
+        if (item != null && item.getCommand() != null) {
+            return ((ComboBoxSuggestion) item.getCommand()).getOptionKey();
+        }
+        return "";
+    }
+
+    /**
+     * TextBox variant used as input element for filter selects, which prevents
+     * selecting text when disabled.
+     *
+     * @since 7.1.5
+     */
+    public class FilterSelectTextBox extends TextBox {
+
+        /**
+         * Creates a new filter select text box.
+         *
+         * @since 7.6.4
+         */
+        public FilterSelectTextBox() {
+            /*-
+             * Stop the browser from showing its own suggestion popup.
+             *
+             * Using an invalid value instead of "off" as suggested by
+             * https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
+             *
+             * Leaving the non-standard Safari options autocapitalize and
+             * autocorrect untouched since those do not interfere in the same
+             * way, and they might be useful in a combo box where new items are
+             * allowed.
+             */
+            getElement().setAttribute("autocomplete", "nope");
+        }
+
+        /**
+         * Overridden to avoid selecting text when text input is disabled
+         */
+        @Override
+        public void setSelectionRange(int pos, int length) {
+            if (textInputEnabled) {
+                /*
+                 * set selection range with a backwards direction: anchor at the
+                 * back, focus at the front. This means that items that are too
+                 * long to display will display from the start and not the end
+                 * even on Firefox.
+                 *
+                 * We need the JSNI function to set selection range so that we
+                 * can use the optional direction attribute to set the anchor to
+                 * the end and the focus to the start. This makes Firefox work
+                 * the same way as other browsers (#13477)
+                 */
+                WidgetUtil.setSelectionRange(getElement(), pos, length,
+                        "backward");
+
+            } else {
+                /*
+                 * Setting the selectionrange for an uneditable textbox leads to
+                 * unwanted behaviour when the width of the textbox is narrower
+                 * than the width of the entry: the end of the entry is shown
+                 * instead of the beginning. (see #13477)
+                 *
+                 * To avoid this, we set the caret to the beginning of the line.
+                 */
+
+                super.setSelectionRange(0, 0);
+            }
+        }
+
+    }
+
+    /**
+     * Handler receiving notifications from the connector and updating the
+     * widget state accordingly.
+     *
+     * This class is still subject to change and should not be considered as
+     * public stable API.
+     *
+     * @since
+     */
+    public class DataReceivedHandler {
+
+        private Runnable navigationCallback = null;
+        /**
+         * Set true when popupopened has been clicked. Cleared on each
+         * UIDL-update. This handles the special case where are not filtering
+         * yet and the selected value has changed on the server-side. See #2119
+         * <p>
+         * For internal use only. May be removed or replaced in the future.
+         */
+        private boolean popupOpenerClicked = false;
+        /** For internal use only. May be removed or replaced in the future. */
+        private boolean waitingForFilteringResponse = false;
+        private boolean initialData = true;
+        private String pendingUserInput = null;
+        private boolean showPopup = false;
+
+        /**
+         * Called by the connector when new data for the last requested filter
+         * is received from the server.
+         */
+        public void dataReceived() {
+            if (initialData) {
+                suggestionPopup.menu.setSuggestions(currentSuggestions);
+                performSelection(serverSelectedKey, true, true);
+                updateSuggestionPopupMinWidth();
+                updateRootWidth();
+                initialData = false;
+                return;
+            }
+
+            suggestionPopup.menu.setSuggestions(currentSuggestions);
+            if (!waitingForFilteringResponse && suggestionPopup.isAttached()) {
+                showPopup = true;
+            }
+            if (showPopup) {
+                suggestionPopup.showSuggestions(currentPage, totalMatches);
+            }
+
+            waitingForFilteringResponse = false;
+
+            if (pendingUserInput != null) {
+                suggestionPopup.menu
+                        .actOnEnteredValueAfterFiltering(pendingUserInput);
+                pendingUserInput = null;
+            } else if (popupOpenerClicked) {
+                // make sure the current item is selected in the popup
+                suggestionPopup.menu.highlightSelectedItem();
+            } else {
+                navigateItemAfterPageChange();
+            }
+
+            if (!showPopup) {
+                suggestionPopup.hide();
+            }
+
+            popupOpenerClicked = false;
+            showPopup = false;
+        }
+
+        /**
+         * Perform filtering with the user entered string and when the results
+         * are received, perform any action appropriate for the user input
+         * (select an item or create a new one).
+         *
+         * @param value
+         *            user input
+         */
+        public void reactOnInputWhenReady(String value) {
+            pendingUserInput = value;
+            showPopup = false;
+            filterOptions(0, value);
+        }
+
+        /*
+         * This method navigates to the proper item in the combobox page. This
+         * should be executed after setSuggestions() method which is called from
+         * VComboBox.showSuggestions(). ShowSuggestions() method builds the page
+         * content. As far as setSuggestions() method is called as deferred,
+         * navigateItemAfterPageChange method should be also be called as
+         * deferred. #11333
+         */
+        private void navigateItemAfterPageChange() {
+            if (navigationCallback != null) {
+                // navigationCallback is not reset here but after any server
+                // request in case you are in between two requests both changing
+                // the page back and forth
+
+                // we're paging w/ arrows
+                navigationCallback.run();
+                navigationCallback = null;
+            }
+        }
+
+        /**
+         * Called by the connector any pending navigation operations should be
+         * cleared.
+         */
+        public void clearPendingNavigation() {
+            navigationCallback = null;
+        }
+
+        /**
+         * Set a callback that is invoked when a page change occurs if there
+         * have not been intervening requests to the server. The callback is
+         * reset when any additional request is made to the server.
+         *
+         * @param callback
+         *            method to call after filtering has completed
+         */
+        public void setNavigationCallback(Runnable callback) {
+            showPopup = true;
+            navigationCallback = callback;
+        }
+
+        /**
+         * Record that the popup opener has been clicked and the popup should be
+         * opened on the next request.
+         *
+         * This handles the special case where are not filtering yet and the
+         * selected value has changed on the server-side. See #2119. The flag is
+         * cleared on each server reply.
+         */
+        public void popupOpenerClicked() {
+            popupOpenerClicked = true;
+            showPopup = true;
+        }
+
+        /**
+         * Cancel a pending request to perform post-filtering actions.
+         */
+        private void cancelPendingPostFiltering() {
+            pendingUserInput = null;
+        }
+
+        /**
+         * Called by the connector when it has finished handling any reply from
+         * the server, regardless of what was updated.
+         */
+        public void serverReplyHandled() {
+            popupOpenerClicked = false;
+            lastNewItemString = null;
+
+            // if (!initDone) {
+            // debug("VComboBox: init done, updating widths");
+            // // Calculate minimum textarea width
+            // updateSuggestionPopupMinWidth();
+            // updateRootWidth();
+            // initDone = true;
+            // }
+        }
+
+        /**
+         * For internal use only - this method will be removed in the future.
+         *
+         * @return true if the combo box is waiting for a reply from the server
+         *         with a new page of data, false otherwise
+         */
+        public boolean isWaitingForFilteringResponse() {
+            return waitingForFilteringResponse;
+        }
+
+        /**
+         * For internal use only - this method will be removed in the future.
+         *
+         * @return true if the combo box is waiting for initial data from the
+         *         server, false otherwise
+         */
+        public boolean isWaitingForInitialData() {
+            return initialData;
+        }
+
+        /**
+         * Set a flag that filtering of options is pending a response from the
+         * server.
+         */
+        private void startWaitingForFilteringResponse() {
+            waitingForFilteringResponse = true;
+        }
+
+        /**
+         * Perform selection (if appropriate) based on a reply from the server.
+         * When this method is called, the suggestions have been reset if new
+         * ones (different from the previous list) were received from the
+         * server.
+         *
+         * @param selectedKey
+         *            new selected key or null if none given by the server
+         * @param selectedCaption
+         *            new selected item caption if sent by the server or null -
+         *            this is used when the selected item is not on the current
+         *            page
+         */
+        public void updateSelectionFromServer(String selectedKey,
+                String selectedCaption) {
+            boolean oldSuggestionTextMatchTheOldSelection = currentSuggestion != null
+                    && currentSuggestion.getReplacementString()
+                            .equals(tb.getText());
+
+            serverSelectedKey = selectedKey;
+
+            performSelection(selectedKey, oldSuggestionTextMatchTheOldSelection,
+                    !isWaitingForFilteringResponse() || popupOpenerClicked);
+
+            cancelPendingPostFiltering();
+
+            setSelectedCaption(selectedCaption);
+            if (currentSuggestion != null && serverSelectedKey
+                    .equals(currentSuggestion.getOptionKey())) {
+                setSelectedItemIcon(currentSuggestion.getIconUri());
+            }
+        }
+
+    }
+
+    // TODO decide whether this should change - affects themes and v7
+    public static final String CLASSNAME = "v-filterselect";
+    private static final String STYLE_NO_INPUT = "no-input";
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public int pageLength = 10;
+
+    private boolean enableDebug = false;
+
+    private final FlowPanel panel = new FlowPanel();
+
+    /**
+     * The text box where the filter is written
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     */
+    public final TextBox tb;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public final SuggestionPopup suggestionPopup;
+
+    /**
+     * Used when measuring the width of the popup
+     */
+    private final HTML popupOpener = new HTML("");
+
+    private class IconWidget extends Widget {
+        IconWidget(Icon icon) {
+            setElement(icon.getElement());
+        }
+    }
+
+    private IconWidget selectedItemIcon;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public ComboBoxConnector connector;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public int currentPage;
+
+    /**
+     * A collection of available suggestions (options) as received from the
+     * server.
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     */
+    public final List<ComboBoxSuggestion> currentSuggestions = new ArrayList<ComboBoxSuggestion>();
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public String serverSelectedKey;
+    /** For internal use only. May be removed or replaced in the future. */
+    public String selectedOptionKey;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean initDone = false;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public String lastFilter = "";
+
+    /**
+     * The current suggestion selected from the dropdown. This is one of the
+     * values in currentSuggestions except when filtering, in this case
+     * currentSuggestion might not be in currentSuggestions.
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     */
+    public ComboBoxSuggestion currentSuggestion;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean allowNewItems;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public int totalMatches;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean nullSelectionAllowed;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean nullSelectItem;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean enabled;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean readonly;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public String inputPrompt = "";
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public int suggestionPopupMinWidth = 0;
+
+    public String suggestionPopupWidth = null;
+
+    private int popupWidth = -1;
+    /**
+     * Stores the last new item string to avoid double submissions. Cleared on
+     * uidl updates.
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     */
+    public String lastNewItemString;
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public boolean focused = false;
+
+    /**
+     * If set to false, the component should not allow entering text to the
+     * field even for filtering.
+     */
+    private boolean textInputEnabled = true;
+
+    private final DataReceivedHandler dataReceivedHandler = new DataReceivedHandler();
+
+    /**
+     * Default constructor.
+     */
+    public VComboBox() {
+        tb = createTextBox();
+        suggestionPopup = createSuggestionPopup();
+
+        popupOpener.addMouseDownHandler(VComboBox.this);
+        Roles.getButtonRole().setAriaHiddenState(popupOpener.getElement(),
+                true);
+        Roles.getButtonRole().set(popupOpener.getElement());
+
+        panel.add(tb);
+        panel.add(popupOpener);
+        initWidget(panel);
+        Roles.getComboboxRole().set(panel.getElement());
+
+        tb.addKeyDownHandler(this);
+        tb.addKeyUpHandler(this);
+
+        tb.addFocusHandler(this);
+        tb.addBlurHandler(this);
+
+        panel.addDomHandler(this, ClickEvent.getType());
+
+        setStyleName(CLASSNAME);
+
+        sinkEvents(Event.ONPASTE);
+    }
+
+    private static double getMarginBorderPaddingWidth(Element element) {
+        final ComputedStyle s = new ComputedStyle(element);
+        return s.getMarginWidth() + s.getBorderWidth() + s.getPaddingWidth();
+
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * com.google.gwt.user.client.ui.Composite#onBrowserEvent(com.google.gwt
+     * .user.client.Event)
+     */
+    @Override
+    public void onBrowserEvent(Event event) {
+        super.onBrowserEvent(event);
+
+        if (event.getTypeInt() == Event.ONPASTE) {
+            if (textInputEnabled) {
+                filterOptions(currentPage);
+            }
+        }
+    }
+
+    /**
+     * This method will create the TextBox used by the VComboBox instance. It is
+     * invoked during the Constructor and should only be overridden if a custom
+     * TextBox shall be used. The overriding method cannot use any instance
+     * variables.
+     *
+     * @since 7.1.5
+     * @return TextBox instance used by this VComboBox
+     */
+    protected TextBox createTextBox() {
+        return new FilterSelectTextBox();
+    }
+
+    /**
+     * This method will create the SuggestionPopup used by the VComboBox
+     * instance. It is invoked during the Constructor and should only be
+     * overridden if a custom SuggestionPopup shall be used. The overriding
+     * method cannot use any instance variables.
+     *
+     * @since 7.1.5
+     * @return SuggestionPopup instance used by this VComboBox
+     */
+    protected SuggestionPopup createSuggestionPopup() {
+        return new SuggestionPopup();
+    }
+
+    @Override
+    public void setStyleName(String style) {
+        super.setStyleName(style);
+        updateStyleNames();
+    }
+
+    @Override
+    public void setStylePrimaryName(String style) {
+        super.setStylePrimaryName(style);
+        updateStyleNames();
+    }
+
+    protected void updateStyleNames() {
+        tb.setStyleName(getStylePrimaryName() + "-input");
+        popupOpener.setStyleName(getStylePrimaryName() + "-button");
+        suggestionPopup.setStyleName(getStylePrimaryName() + "-suggestpopup");
+    }
+
+    /**
+     * Does the Select have more pages?
+     *
+     * @return true if a next page exists, else false if the current page is the
+     *         last page
+     */
+    public boolean hasNextPage() {
+        return (pageLength > 0
+                && totalMatches > (currentPage + 1) * pageLength);
+    }
+
+    /**
+     * Filters the options at a certain page. Uses the text box input as a
+     * filter and ensures the popup is opened when filtering results are
+     * available.
+     *
+     * @param page
+     *            The page which items are to be filtered
+     */
+    public void filterOptions(int page) {
+        dataReceivedHandler.popupOpenerClicked();
+        filterOptions(page, tb.getText());
+    }
+
+    /**
+     * Filters the options at certain page using the given filter.
+     *
+     * @param page
+     *            The page to filter
+     * @param filter
+     *            The filter to apply to the components
+     */
+    public void filterOptions(int page, String filter) {
+        debug("VComboBox: filterOptions(" + page + ", " + filter + ")");
+
+        if (filter.equals(lastFilter) && currentPage == page) {
+            if (!suggestionPopup.isAttached()) {
+                dataReceivedHandler.startWaitingForFilteringResponse();
+                connector.requestPage(currentPage);
+            } else {
+                // already have the page
+                dataReceivedHandler.dataReceived();
+            }
+            return;
+        }
+        if (!filter.equals(lastFilter)) {
+            // when filtering, let the server decide the page unless we've
+            // set the filter to empty and explicitly said that we want to see
+            // the results starting from page 0.
+            if ("".equals(filter) && page != 0) {
+                // let server decide
+                page = -1;
+            } else {
+                page = 0;
+            }
+        }
+
+        dataReceivedHandler.startWaitingForFilteringResponse();
+        connector.setFilter(filter);
+        connector.requestPage(currentPage);
+
+        lastFilter = filter;
+        currentPage = page;
+    }
+
+    /** For internal use only. May be removed or replaced in the future. */
+    public void updateReadOnly() {
+        debug("VComboBox: updateReadOnly()");
+        tb.setReadOnly(readonly || !textInputEnabled);
+    }
+
+    public void setTextInputAllowed(boolean textInputAllowed) {
+        debug("VComboBox: setTextInputAllowed()");
+        // Always update styles as they might have been overwritten
+        if (textInputAllowed) {
+            removeStyleDependentName(STYLE_NO_INPUT);
+            Roles.getTextboxRole().removeAriaReadonlyProperty(tb.getElement());
+        } else {
+            addStyleDependentName(STYLE_NO_INPUT);
+            Roles.getTextboxRole().setAriaReadonlyProperty(tb.getElement(),
+                    true);
+        }
+
+        if (textInputEnabled == textInputAllowed) {
+            return;
+        }
+
+        textInputEnabled = textInputAllowed;
+        updateReadOnly();
+    }
+
+    /**
+     * Sets the text in the text box.
+     *
+     * @param text
+     *            the text to set in the text box
+     */
+    public void setText(final String text) {
+        /**
+         * To leave caret in the beginning of the line. SetSelectionRange
+         * wouldn't work on IE (see #13477)
+         */
+        Direction previousDirection = tb.getDirection();
+        tb.setDirection(Direction.RTL);
+        tb.setText(text);
+        tb.setDirection(previousDirection);
+    }
+
+    /**
+     * Set or reset the placeholder attribute for the text field.
+     *
+     * @param placeholder
+     *            new placeholder string or null for none
+     */
+    public void setPlaceholder(String placeholder) {
+        inputPrompt = placeholder;
+        updatePlaceholder();
+    }
+
+    /**
+     * Update placeholder visibility (hidden when read-only or disabled).
+     */
+    public void updatePlaceholder() {
+        if (inputPrompt != null && enabled && !readonly) {
+            tb.getElement().setAttribute("placeholder", inputPrompt);
+        } else {
+            tb.getElement().removeAttribute("placeholder");
+        }
+    }
+
+    /**
+     * Triggered when a suggestion is selected.
+     *
+     * @param suggestion
+     *            The suggestion that just got selected.
+     */
+    public void onSuggestionSelected(ComboBoxSuggestion suggestion) {
+        if (enableDebug) {
+            debug("VComboBox: onSuggestionSelected(" + suggestion.caption + ": "
+                    + suggestion.key + ")");
+        }
+        // special handling of null selection
+        if (suggestion.key.equals("")) {
+            onNullSelected();
+            return;
+        }
+
+        dataReceivedHandler.cancelPendingPostFiltering();
+
+        currentSuggestion = suggestion;
+        String newKey = suggestion.getOptionKey();
+
+        String text = suggestion.getReplacementString();
+        setText(text);
+        setSelectedItemIcon(suggestion.getIconUri());
+
+        if (!(newKey.equals(selectedOptionKey))) {
+            selectedOptionKey = newKey;
+            connector.sendSelection(selectedOptionKey);
+            setSelectedCaption(text);
+
+            // currentPage = -1; // forget the page
+        }
+
+        suggestionPopup.hide();
+    }
+
+    /**
+     * Triggered when an empty value is selected and null selection is allowed.
+     */
+    public void onNullSelected() {
+        if (enableDebug) {
+            debug("VComboBox: onNullSelected()");
+        }
+        // TODO do we need this feature?
+        if (nullSelectItem) {
+            reset();
+            return;
+        }
+        dataReceivedHandler.cancelPendingPostFiltering();
+
+        currentSuggestion = null;
+        setText("");
+        setSelectedItemIcon(null);
+
+        if (!"".equals(selectedOptionKey) || (selectedOptionKey != null)) {
+            selectedOptionKey = "";
+            setSelectedCaption("");
+            connector.sendSelection(null);
+            // currentPage = 0;
+        }
+
+        suggestionPopup.hide();
+    }
+
+    /**
+     * Sets the icon URI of the selected item. The icon is shown on the left
+     * side of the item caption text. Set the URI to null to remove the icon.
+     *
+     * @param iconUri
+     *            The URI of the icon
+     */
+    public void setSelectedItemIcon(String iconUri) {
+
+        if (selectedItemIcon != null) {
+            panel.remove(selectedItemIcon);
+        }
+        if (iconUri == null || iconUri.length() == 0) {
+            if (selectedItemIcon != null) {
+                selectedItemIcon = null;
+                afterSelectedItemIconChange();
+            }
+        } else {
+            selectedItemIcon = new IconWidget(
+                    connector.getConnection().getIcon(iconUri));
+            selectedItemIcon.addDomHandler(VComboBox.this,
+                    ClickEvent.getType());
+            selectedItemIcon.addDomHandler(VComboBox.this,
+                    MouseDownEvent.getType());
+            iconUpdating = true;
+            selectedItemIcon.addDomHandler(new LoadHandler() {
+                @Override
+                public void onLoad(LoadEvent event) {
+                    afterSelectedItemIconChange();
+                    iconUpdating = false;
+                }
+            }, LoadEvent.getType());
+            panel.insert(selectedItemIcon, 0);
+            afterSelectedItemIconChange();
+        }
+    }
+
+    private void afterSelectedItemIconChange() {
+        if (BrowserInfo.get().isWebkit()) {
+            // Some browsers need a nudge to reposition the text field
+            forceReflow();
+        }
+        updateRootWidth();
+        if (selectedItemIcon != null) {
+            updateSelectedIconPosition();
+        }
+    }
+
+    /**
+     * Perform selection based on a message from the server.
+     *
+     * The special case where the selected item is not on the current page is
+     * handled separately by the caller.
+     *
+     * @param selectedKey
+     *            non-empty selected item key
+     * @param forceUpdateText
+     *            true to force the text box value to match the suggestion text
+     * @param updatePromptAndSelectionIfMatchFound
+     */
+    private void performSelection(String selectedKey, boolean forceUpdateText,
+            boolean updatePromptAndSelectionIfMatchFound) {
+        if (selectedKey == null || "".equals(selectedKey)) {
+            currentSuggestion = null; // #13217
+            setSelectedItemIcon(null);
+            selectedOptionKey = null;
+            setText("");
+        }
+        // some item selected
+        for (ComboBoxSuggestion suggestion : currentSuggestions) {
+            String suggestionKey = suggestion.getOptionKey();
+            if (!suggestionKey.equals(selectedKey)) {
+                continue;
+            }
+            // at this point, suggestion key matches the new selection key
+            if (updatePromptAndSelectionIfMatchFound) {
+                if (!suggestionKey.equals(selectedOptionKey) || suggestion
+                        .getReplacementString().equals(tb.getText())
+                        || forceUpdateText) {
+                    // Update text field if we've got a new
+                    // selection
+                    // Also update if we've got the same text to
+                    // retain old text selection behavior
+                    // OR if selected item caption is changed.
+                    setText(suggestion.getReplacementString());
+                    selectedOptionKey = suggestionKey;
+                }
+            }
+            currentSuggestion = suggestion;
+            setSelectedItemIcon(suggestion.getIconUri());
+            // only a single item can be selected
+            break;
+        }
+    }
+
+    private void forceReflow() {
+        WidgetUtil.setStyleTemporarily(tb.getElement(), "zoom", "1");
+    }
+
+    /**
+     * Positions the icon vertically in the middle. Should be called after the
+     * icon has loaded
+     */
+    private void updateSelectedIconPosition() {
+        // Position icon vertically to middle
+        int availableHeight = 0;
+        availableHeight = getOffsetHeight();
+
+        int iconHeight = WidgetUtil.getRequiredHeight(selectedItemIcon);
+        int marginTop = (availableHeight - iconHeight) / 2;
+        selectedItemIcon.getElement().getStyle().setMarginTop(marginTop,
+                Unit.PX);
+    }
+
+    private static Set<Integer> navigationKeyCodes = new HashSet<Integer>();
+    static {
+        navigationKeyCodes.add(KeyCodes.KEY_DOWN);
+        navigationKeyCodes.add(KeyCodes.KEY_UP);
+        navigationKeyCodes.add(KeyCodes.KEY_PAGEDOWN);
+        navigationKeyCodes.add(KeyCodes.KEY_PAGEUP);
+        navigationKeyCodes.add(KeyCodes.KEY_ENTER);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
+     * .event.dom.client.KeyDownEvent)
+     */
+
+    @Override
+    public void onKeyDown(KeyDownEvent event) {
+        if (enabled && !readonly) {
+            int keyCode = event.getNativeKeyCode();
+
+            if (enableDebug) {
+                debug("VComboBox: key down: " + keyCode);
+            }
+            if (dataReceivedHandler.isWaitingForFilteringResponse()
+                    && navigationKeyCodes.contains(keyCode)
+                    && (!allowNewItems || keyCode != KeyCodes.KEY_ENTER)) {
+                /*
+                 * Keyboard navigation events should not be handled while we are
+                 * waiting for a response. This avoids flickering, disappearing
+                 * items, wrongly interpreted responses and more.
+                 */
+                if (enableDebug) {
+                    debug("Ignoring " + keyCode
+                            + " because we are waiting for a filtering response");
+                }
+                DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
+                event.stopPropagation();
+                return;
+            }
+
+            if (suggestionPopup.isAttached()) {
+                if (enableDebug) {
+                    debug("Keycode " + keyCode + " target is popup");
+                }
+                popupKeyDown(event);
+            } else {
+                if (enableDebug) {
+                    debug("Keycode " + keyCode + " target is text field");
+                }
+                inputFieldKeyDown(event);
+            }
+        }
+    }
+
+    private void debug(String string) {
+        if (enableDebug) {
+            VConsole.error(string);
+        }
+    }
+
+    /**
+     * Triggered when a key is pressed in the text box
+     *
+     * @param event
+     *            The KeyDownEvent
+     */
+    private void inputFieldKeyDown(KeyDownEvent event) {
+        if (enableDebug) {
+            debug("VComboBox: inputFieldKeyDown(" + event.getNativeKeyCode()
+                    + ")");
+        }
+        switch (event.getNativeKeyCode()) {
+        case KeyCodes.KEY_DOWN:
+        case KeyCodes.KEY_UP:
+        case KeyCodes.KEY_PAGEDOWN:
+        case KeyCodes.KEY_PAGEUP:
+            // open popup as from gadget
+            filterOptions(-1, "");
+            tb.selectAll();
+            dataReceivedHandler.popupOpenerClicked();
+            break;
+        case KeyCodes.KEY_ENTER:
+            /*
+             * This only handles the case when new items is allowed, a text is
+             * entered, the popup opener button is clicked to close the popup
+             * and enter is then pressed (see #7560).
+             */
+            if (!allowNewItems) {
+                return;
+            }
+
+            if (currentSuggestion != null && tb.getText()
+                    .equals(currentSuggestion.getReplacementString())) {
+                // Retain behavior from #6686 by returning without stopping
+                // propagation if there's nothing to do
+                return;
+            }
+            dataReceivedHandler.reactOnInputWhenReady(tb.getText());
+            suggestionPopup.hide();
+
+            event.stopPropagation();
+            break;
+        }
+
+    }
+
+    /**
+     * Triggered when a key was pressed in the suggestion popup.
+     *
+     * @param event
+     *            The KeyDownEvent of the key
+     */
+    private void popupKeyDown(KeyDownEvent event) {
+        if (enableDebug) {
+            debug("VComboBox: popupKeyDown(" + event.getNativeKeyCode() + ")");
+        }
+        // Propagation of handled events is stopped so other handlers such as
+        // shortcut key handlers do not also handle the same events.
+        switch (event.getNativeKeyCode()) {
+        case KeyCodes.KEY_DOWN:
+            suggestionPopup.selectNextItem();
+
+            DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
+            event.stopPropagation();
+            break;
+        case KeyCodes.KEY_UP:
+            suggestionPopup.selectPrevItem();
+
+            DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
+            event.stopPropagation();
+            break;
+        case KeyCodes.KEY_PAGEDOWN:
+            selectNextPage();
+            event.stopPropagation();
+            break;
+        case KeyCodes.KEY_PAGEUP:
+            selectPrevPage();
+            event.stopPropagation();
+            break;
+        case KeyCodes.KEY_ESCAPE:
+            reset();
+            DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
+            event.stopPropagation();
+            break;
+        case KeyCodes.KEY_TAB:
+        case KeyCodes.KEY_ENTER:
+
+            // queue this, may be cancelled by selection
+            int selectedIndex = suggestionPopup.menu.getSelectedIndex();
+            if (!allowNewItems && selectedIndex != -1) {
+                onSuggestionSelected(currentSuggestions.get(selectedIndex));
+            } else {
+                dataReceivedHandler.reactOnInputWhenReady(tb.getText());
+            }
+            suggestionPopup.hide();
+
+            event.stopPropagation();
+            break;
+        }
+
+    }
+
+    /*
+     * Show the prev page.
+     */
+    private void selectPrevPage() {
+        if (currentPage > 0) {
+            dataReceivedHandler.setNavigationCallback(
+                    () -> suggestionPopup.selectLastItem());
+            filterOptions(currentPage - 1, lastFilter);
+        }
+    }
+
+    /*
+     * Show the next page.
+     */
+    private void selectNextPage() {
+        if (hasNextPage()) {
+            dataReceivedHandler.setNavigationCallback(
+                    () -> suggestionPopup.selectFirstItem());
+            filterOptions(currentPage + 1, lastFilter);
+        }
+    }
+
+    /**
+     * Triggered when a key was depressed.
+     *
+     * @param event
+     *            The KeyUpEvent of the key depressed
+     */
+    @Override
+    public void onKeyUp(KeyUpEvent event) {
+        if (enableDebug) {
+            debug("VComboBox: onKeyUp(" + event.getNativeKeyCode() + ")");
+        }
+        if (enabled && !readonly) {
+            switch (event.getNativeKeyCode()) {
+            case KeyCodes.KEY_ENTER:
+            case KeyCodes.KEY_TAB:
+            case KeyCodes.KEY_SHIFT:
+            case KeyCodes.KEY_CTRL:
+            case KeyCodes.KEY_ALT:
+            case KeyCodes.KEY_DOWN:
+            case KeyCodes.KEY_UP:
+            case KeyCodes.KEY_PAGEDOWN:
+            case KeyCodes.KEY_PAGEUP:
+            case KeyCodes.KEY_ESCAPE:
+                // NOP
+                break;
+            default:
+                if (textInputEnabled) {
+                    // when filtering, we always want to see the results on the
+                    // first page first.
+                    filterOptions(0);
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * Resets the ComboBox to its initial state.
+     */
+    private void reset() {
+        debug("VComboBox: reset()");
+        if (currentSuggestion != null) {
+            String text = currentSuggestion.getReplacementString();
+            setText(text);
+            setSelectedItemIcon(currentSuggestion.getIconUri());
+
+            selectedOptionKey = currentSuggestion.key;
+
+        } else {
+            setText("");
+            setSelectedItemIcon(null);
+            updatePlaceholder();
+
+            selectedOptionKey = null;
+        }
+
+        lastFilter = "";
+        suggestionPopup.hide();
+    }
+
+    /**
+     * Listener for popupopener.
+     */
+    @Override
+    public void onClick(ClickEvent event) {
+        debug("VComboBox: onClick()");
+        if (textInputEnabled && event.getNativeEvent().getEventTarget()
+                .cast() == tb.getElement()) {
+            // Don't process clicks on the text field if text input is enabled
+            return;
+        }
+        if (enabled && !readonly) {
+            // ask suggestionPopup if it was just closed, we are using GWT
+            // Popup's auto close feature
+            if (!suggestionPopup.isJustClosed()) {
+                filterOptions(-1, "");
+                dataReceivedHandler.popupOpenerClicked();
+            }
+            DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
+            focus();
+            tb.selectAll();
+        }
+    }
+
+    /**
+     * Update minimum width for combo box textarea based on input prompt and
+     * suggestions.
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     */
+    public void updateSuggestionPopupMinWidth() {
+        debug("VComboBox: updateSuggestionPopupMinWidth()");
+
+        // used only to calculate minimum width
+        String captions = WidgetUtil.escapeHTML(inputPrompt);
+
+        for (ComboBoxSuggestion suggestion : currentSuggestions) {
+            // Collect captions so we can calculate minimum width for
+            // textarea
+            if (captions.length() > 0) {
+                captions += "|";
+            }
+            captions += WidgetUtil
+                    .escapeHTML(suggestion.getReplacementString());
+        }
+
+        // Calculate minimum textarea width
+        suggestionPopupMinWidth = minWidth(captions);
+    }
+
+    /**
+     * Calculate minimum width for FilterSelect textarea.
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     *
+     * @param captions
+     *            pipe separated string listing all the captions to measure
+     * @return minimum width in pixels
+     */
+    public native int minWidth(String captions)
+    /*-{
+        if(!captions || captions.length <= 0)
+                return 0;
+        captions = captions.split("|");
+        var d = $wnd.document.createElement("div");
+        var html = "";
+        for(var i=0; i < captions.length; i++) {
+                html += "<div>" + captions[i] + "</div>";
+                // TODO apply same CSS classname as in suggestionmenu
+        }
+        d.style.position = "absolute";
+        d.style.top = "0";
+        d.style.left = "0";
+        d.style.visibility = "hidden";
+        d.innerHTML = html;
+        $wnd.document.body.appendChild(d);
+        var w = d.offsetWidth;
+        $wnd.document.body.removeChild(d);
+        return w;
+    }-*/;
+
+    /**
+     * A flag which prevents a focus event from taking place.
+     */
+    boolean iePreventNextFocus = false;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event
+     * .dom.client.FocusEvent)
+     */
+
+    @Override
+    public void onFocus(FocusEvent event) {
+        debug("VComboBox: onFocus()");
+
+        /*
+         * When we disable a blur event in ie we need to refocus the textfield.
+         * This will cause a focus event we do not want to process, so in that
+         * case we just ignore it.
+         */
+        if (BrowserInfo.get().isIE() && iePreventNextFocus) {
+            iePreventNextFocus = false;
+            return;
+        }
+
+        focused = true;
+        updatePlaceholder();
+        addStyleDependentName("focus");
+
+        connector.sendFocusEvent();
+
+        connector.getConnection().getVTooltip()
+                .showAssistive(connector.getTooltipInfo(getElement()));
+    }
+
+    /**
+     * A flag which cancels the blur event and sets the focus back to the
+     * textfield if the Browser is IE.
+     */
+    boolean preventNextBlurEventInIE = false;
+
+    private String explicitSelectedCaption;
+    private boolean iconUpdating = false;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event
+     * .dom.client.BlurEvent)
+     */
+
+    @Override
+    public void onBlur(BlurEvent event) {
+        debug("VComboBox: onBlur()");
+
+        if (BrowserInfo.get().isIE() && preventNextBlurEventInIE) {
+            /*
+             * Clicking in the suggestion popup or on the popup button in IE
+             * causes a blur event to be sent for the field. In other browsers
+             * this is prevented by canceling/preventing default behavior for
+             * the focus event, in IE we handle it here by refocusing the text
+             * field and ignoring the resulting focus event for the textfield
+             * (in onFocus).
+             */
+            preventNextBlurEventInIE = false;
+
+            Element focusedElement = WidgetUtil.getFocusedElement();
+            if (getElement().isOrHasChild(focusedElement) || suggestionPopup
+                    .getElement().isOrHasChild(focusedElement)) {
+
+                // IF the suggestion popup or another part of the VComboBox
+                // was focused, move the focus back to the textfield and prevent
+                // the triggered focus event (in onFocus).
+                iePreventNextFocus = true;
+                tb.setFocus(true);
+                return;
+            }
+        }
+
+        focused = false;
+        updatePlaceholder();
+        if (!readonly) {
+            reset();
+            suggestionPopup.hide();
+        }
+        removeStyleDependentName("focus");
+
+        connector.sendBlurEvent();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see com.vaadin.client.Focusable#focus()
+     */
+
+    @Override
+    public void focus() {
+        debug("VComboBox: focus()");
+        focused = true;
+        updatePlaceholder();
+        tb.setFocus(true);
+    }
+
+    /**
+     * Calculates the width of the select if the select has undefined width.
+     * Should be called when the width changes or when the icon changes.
+     * <p>
+     * For internal use only. May be removed or replaced in the future.
+     */
+    public void updateRootWidth() {
+        debug("VComboBox: updateRootWidth()");
+
+        if (connector.isUndefinedWidth()) {
+
+            /*
+             * When the select has a undefined with we need to check that we are
+             * only setting the text box width relative to the first page width
+             * of the items. If this is not done the text box width will change
+             * when the popup is used to view longer items than the text box is
+             * wide.
+             */
+            int w = WidgetUtil.getRequiredWidth(this);
+
+            if (dataReceivedHandler.isWaitingForInitialData()
+                    && suggestionPopupMinWidth > w) {
+                /*
+                 * We want to compensate for the paddings just to preserve the
+                 * exact size as in Vaadin 6.x, but we get here before
+                 * MeasuredSize has been initialized.
+                 * Util.measureHorizontalPaddingAndBorder does not work with
+                 * border-box, so we must do this the hard way.
+                 */
+                Style style = getElement().getStyle();
+                String originalPadding = style.getPadding();
+                String originalBorder = style.getBorderWidth();
+                style.setPaddingLeft(0, Unit.PX);
+                style.setBorderWidth(0, Unit.PX);
+                style.setProperty("padding", originalPadding);
+                style.setProperty("borderWidth", originalBorder);
+
+                // Use util.getRequiredWidth instead of getOffsetWidth here
+
+                int iconWidth = selectedItemIcon == null ? 0
+                        : WidgetUtil.getRequiredWidth(selectedItemIcon);
+                int buttonWidth = popupOpener == null ? 0
+                        : WidgetUtil.getRequiredWidth(popupOpener);
+
+                /*
+                 * Instead of setting the width of the wrapper, set the width of
+                 * the combobox. Subtract the width of the icon and the
+                 * popupopener
+                 */
+
+                tb.setWidth((suggestionPopupMinWidth - iconWidth - buttonWidth)
+                        + "px");
+            }
+
+            /*
+             * Lock the textbox width to its current value if it's not already
+             * locked. This can happen after setWidth("") which resets the
+             * textbox width to "100%".
+             */
+            if (!tb.getElement().getStyle().getWidth().endsWith("px")) {
+                int iconWidth = selectedItemIcon == null ? 0
+                        : selectedItemIcon.getOffsetWidth();
+                tb.setWidth((tb.getOffsetWidth() - iconWidth) + "px");
+            }
+        }
+    }
+
+    /**
+     * Get the width of the select in pixels where the text area and icon has
+     * been included.
+     *
+     * @return The width in pixels
+     */
+    private int getMainWidth() {
+        return getOffsetWidth();
+    }
+
+    @Override
+    public void setWidth(String width) {
+        super.setWidth(width);
+        if (width.length() != 0) {
+            tb.setWidth("100%");
+        }
+    }
+
+    /**
+     * Handles special behavior of the mouse down event.
+     *
+     * @param event
+     */
+    private void handleMouseDownEvent(Event event) {
+        /*
+         * Prevent the keyboard focus from leaving the textfield by preventing
+         * the default behaviour of the browser. Fixes #4285.
+         */
+        if (event.getTypeInt() == Event.ONMOUSEDOWN) {
+            debug("VComboBox: blocking mouseDown event to avoid blur");
+
+            event.preventDefault();
+            event.stopPropagation();
+
+            /*
+             * In IE the above wont work, the blur event will still trigger. So,
+             * we set a flag here to prevent the next blur event from happening.
+             * This is not needed if do not already have focus, in that case
+             * there will not be any blur event and we should not cancel the
+             * next blur.
+             */
+            if (BrowserInfo.get().isIE() && focused) {
+                preventNextBlurEventInIE = true;
+                debug("VComboBox: Going to prevent next blur event on IE");
+            }
+        }
+    }
+
+    @Override
+    public void onMouseDown(MouseDownEvent event) {
+        debug("VComboBox.onMouseDown(): blocking mouseDown event to avoid blur");
+
+        event.preventDefault();
+        event.stopPropagation();
+
+        /*
+         * In IE the above wont work, the blur event will still trigger. So, we
+         * set a flag here to prevent the next blur event from happening. This
+         * is not needed if do not already have focus, in that case there will
+         * not be any blur event and we should not cancel the next blur.
+         */
+        if (BrowserInfo.get().isIE() && focused) {
+            preventNextBlurEventInIE = true;
+            debug("VComboBox: Going to prevent next blur event on IE");
+        }
+    }
+
+    @Override
+    protected void onDetach() {
+        super.onDetach();
+        suggestionPopup.hide();
+    }
+
+    @Override
+    public com.google.gwt.user.client.Element getSubPartElement(
+            String subPart) {
+        String[] parts = subPart.split("/");
+        if ("textbox".equals(parts[0])) {
+            return tb.getElement();
+        } else if ("button".equals(parts[0])) {
+            return popupOpener.getElement();
+        } else if ("popup".equals(parts[0]) && suggestionPopup.isAttached()) {
+            if (parts.length == 2) {
+                return suggestionPopup.menu.getSubPartElement(parts[1]);
+            }
+            return suggestionPopup.getElement();
+        }
+        return null;
+    }
+
+    @Override
+    public String getSubPartName(
+            com.google.gwt.user.client.Element subElement) {
+        if (tb.getElement().isOrHasChild(subElement)) {
+            return "textbox";
+        } else if (popupOpener.getElement().isOrHasChild(subElement)) {
+            return "button";
+        } else if (suggestionPopup.getElement().isOrHasChild(subElement)) {
+            return "popup";
+        }
+        return null;
+    }
+
+    @Override
+    public void setAriaRequired(boolean required) {
+        AriaHelper.handleInputRequired(tb, required);
+    }
+
+    @Override
+    public void setAriaInvalid(boolean invalid) {
+        AriaHelper.handleInputInvalid(tb, invalid);
+    }
+
+    @Override
+    public void bindAriaCaption(
+            com.google.gwt.user.client.Element captionElement) {
+        AriaHelper.bindCaption(tb, captionElement);
+    }
+
+    @Override
+    public boolean isWorkPending() {
+        return dataReceivedHandler.isWaitingForFilteringResponse()
+                || suggestionPopup.lazyPageScroller.isRunning() || iconUpdating;
+    }
+
+    /**
+     * Sets the caption of selected item, if "scroll to page" is disabled. This
+     * method is meant for internal use and may change in future versions.
+     *
+     * @since 7.7
+     * @param selectedCaption
+     *            the caption of selected item
+     */
+    public void setSelectedCaption(String selectedCaption) {
+        explicitSelectedCaption = selectedCaption;
+        if (selectedCaption != null) {
+            setText(selectedCaption);
+        }
+    }
+
+    /**
+     * This method is meant for internal use and may change in future versions.
+     *
+     * @since 7.7
+     * @return the caption of selected item, if "scroll to page" is disabled
+     */
+    public String getSelectedCaption() {
+        return explicitSelectedCaption;
+    }
+
+    /**
+     * Returns a handler receiving notifications from the connector about
+     * communications.
+     *
+     * @return the dataReceivedHandler
+     */
+    public DataReceivedHandler getDataReceivedHandler() {
+        return dataReceivedHandler;
+    }
+
+    /**
+     * Sets the number of items to show per page, or 0 for showing all items.
+     *
+     * @param pageLength
+     *            new page length or 0 for all items
+     */
+    public void setPageLength(int pageLength) {
+        this.pageLength = pageLength;
+    }
+
+    /**
+     * Sets the suggestion pop-up's width as a CSS string. By using relative
+     * units (e.g. "50%") it's possible to set the popup's width relative to the
+     * ComboBox itself.
+     *
+     * @param suggestionPopupWidth
+     *            new popup width as CSS string, null for old default width
+     *            calculation based on items
+     */
+    public void setSuggestionPopupWidth(String suggestionPopupWidth) {
+        this.suggestionPopupWidth = suggestionPopupWidth;
+    }
+
+    /**
+     * Sets whether creation of new items when there is no match is allowed or
+     * not.
+     *
+     * @param allowNewItems
+     *            true to allow creation of new items, false to only allow
+     *            selection of existing items
+     */
+    public void setAllowNewItems(boolean allowNewItems) {
+        this.allowNewItems = allowNewItems;
+    }
+
+}
diff --git a/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/main/java/com/vaadin/client/ui/combobox/ComboBoxConnector.java
new file mode 100644 (file)
index 0000000..d0758b7
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * 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.ui.combobox;
+
+import com.vaadin.client.Profiler;
+import com.vaadin.client.communication.RpcProxy;
+import com.vaadin.client.communication.StateChangeEvent;
+import com.vaadin.client.connectors.data.HasDataSource;
+import com.vaadin.client.data.DataSource;
+import com.vaadin.client.ui.AbstractFieldConnector;
+import com.vaadin.client.ui.SimpleManagedLayout;
+import com.vaadin.client.ui.VComboBox;
+import com.vaadin.client.ui.VComboBox.DataReceivedHandler;
+import com.vaadin.shared.EventId;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc;
+import com.vaadin.shared.data.DataCommunicatorConstants;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.combobox.ComboBoxClientRpc;
+import com.vaadin.shared.ui.combobox.ComboBoxConstants;
+import com.vaadin.shared.ui.combobox.ComboBoxServerRpc;
+import com.vaadin.shared.ui.combobox.ComboBoxState;
+import com.vaadin.ui.ComboBox;
+
+import elemental.json.JsonObject;
+
+@Connect(ComboBox.class)
+public class ComboBoxConnector extends AbstractFieldConnector
+        implements HasDataSource, SimpleManagedLayout {
+
+    protected ComboBoxServerRpc rpc = RpcProxy.create(ComboBoxServerRpc.class,
+            this);
+
+    protected FocusAndBlurServerRpc focusAndBlurRpc = RpcProxy
+            .create(FocusAndBlurServerRpc.class, this);
+
+    private DataSource<JsonObject> dataSource;
+
+    private Registration dataChangeHandlerRegistration;
+
+    @Override
+    protected void init() {
+        super.init();
+        getWidget().connector = this;
+        registerRpc(ComboBoxClientRpc.class, new ComboBoxClientRpc() {
+            @Override
+            public void setSelectedItem(String selectedKey,
+                    String selectedCaption) {
+                getDataReceivedHandler().updateSelectionFromServer(selectedKey,
+                        selectedCaption);
+            }
+        });
+    }
+
+    @Override
+    public void onStateChanged(StateChangeEvent stateChangeEvent) {
+        super.onStateChanged(stateChangeEvent);
+
+        Profiler.enter("ComboBoxConnector.onStateChanged update content");
+
+        getWidget().readonly = isReadOnly();
+        getWidget().updateReadOnly();
+
+        // not a FocusWidget -> needs own tabindex handling
+        getWidget().tb.setTabIndex(getState().tabIndex);
+
+        getWidget().suggestionPopup.updateStyleNames(getState());
+
+        getWidget().nullSelectionAllowed = getState().emptySelectionAllowed;
+        // TODO having this true would mean that the empty selection item comes
+        // from the data source so none needs to be added - currently
+        // unsupported
+        getWidget().nullSelectItem = false;
+
+        // make sure the input prompt is updated
+        getWidget().updatePlaceholder();
+
+        getDataReceivedHandler().serverReplyHandled();
+
+        Profiler.leave("ComboBoxConnector.onStateChanged update content");
+    }
+
+    @Override
+    public VComboBox getWidget() {
+        return (VComboBox) super.getWidget();
+    }
+
+    private DataReceivedHandler getDataReceivedHandler() {
+        return getWidget().getDataReceivedHandler();
+    }
+
+    @Override
+    public ComboBoxState getState() {
+        return (ComboBoxState) super.getState();
+    }
+
+    @Override
+    public void layout() {
+        VComboBox widget = getWidget();
+        if (widget.initDone) {
+            widget.updateRootWidth();
+        }
+    }
+
+    @Override
+    public void setWidgetEnabled(boolean widgetEnabled) {
+        super.setWidgetEnabled(widgetEnabled);
+        getWidget().enabled = widgetEnabled;
+        getWidget().tb.setEnabled(widgetEnabled);
+    }
+
+    /*
+     * These methods exist to move communications out of VComboBox, and may be
+     * refactored/removed in the future
+     */
+
+    /**
+     * Send a message about a newly created item to the server.
+     *
+     * This method is for internal use only and may be removed in future
+     * versions.
+     *
+     * @since
+     * @param itemValue
+     *            user entered string value for the new item
+     */
+    public void sendNewItem(String itemValue) {
+        rpc.createNewItem(itemValue);
+        getDataReceivedHandler().clearPendingNavigation();
+    }
+
+    /**
+     * Send a message to the server set the current filter.
+     *
+     * This method is for internal use only and may be removed in future
+     * versions.
+     *
+     * @since
+     * @param filter
+     *            the current filter string
+     */
+    public void setFilter(String filter) {
+        if (filter != getWidget().lastFilter) {
+            getDataReceivedHandler().clearPendingNavigation();
+        }
+        rpc.setFilter(filter);
+    }
+
+    /**
+     * Send a message to the server to request a page of items with the current
+     * filter.
+     *
+     * This method is for internal use only and may be removed in future
+     * versions.
+     *
+     * @since
+     * @param page
+     *            the page number to get or -1 to let the server/connector
+     *            decide based on current selection (possibly loading more data
+     *            from the server)
+     */
+    public void requestPage(int page) {
+        if (page < 0) {
+            if (getState().scrollToSelectedItem) {
+                getDataSource().ensureAvailability(0, 10000);
+                return;
+            } else {
+                page = 0;
+            }
+        }
+        int adjustment = (getWidget().nullSelectionAllowed
+                && "".equals(getWidget().lastFilter)) ? 1 : 0;
+        int startIndex = Math.max(0,
+                page * getWidget().pageLength - adjustment);
+        int pageLength = getWidget().pageLength > 0 ? getWidget().pageLength
+                : 10000;
+        getDataSource().ensureAvailability(startIndex, pageLength);
+    }
+
+    /**
+     * Send a message to the server updating the current selection.
+     *
+     * This method is for internal use only and may be removed in future
+     * versions.
+     *
+     * @since
+     * @param selectionKey
+     *            the current selected item key
+     */
+    public void sendSelection(String selectionKey) {
+        rpc.setSelectedItem(selectionKey);
+        getDataReceivedHandler().clearPendingNavigation();
+    }
+
+    /**
+     * Notify the server that the combo box received focus.
+     *
+     * For timing reasons, ConnectorFocusAndBlurHandler is not used at the
+     * moment.
+     *
+     * This method is for internal use only and may be removed in future
+     * versions.
+     *
+     * @since
+     */
+    public void sendFocusEvent() {
+        boolean registeredListeners = hasEventListener(EventId.FOCUS);
+        if (registeredListeners) {
+            focusAndBlurRpc.focus();
+            getDataReceivedHandler().clearPendingNavigation();
+        }
+    }
+
+    /**
+     * Notify the server that the combo box lost focus.
+     *
+     * For timing reasons, ConnectorFocusAndBlurHandler is not used at the
+     * moment.
+     *
+     * This method is for internal use only and may be removed in future
+     * versions.
+     *
+     * @since
+     */
+    public void sendBlurEvent() {
+        boolean registeredListeners = hasEventListener(EventId.BLUR);
+        if (registeredListeners) {
+            focusAndBlurRpc.blur();
+            getDataReceivedHandler().clearPendingNavigation();
+        }
+    }
+
+    @Override
+    public void setDataSource(DataSource<JsonObject> dataSource) {
+        this.dataSource = dataSource;
+        dataChangeHandlerRegistration = dataSource
+                .addDataChangeHandler(range -> {
+                    // try to find selected item if requested
+                    if (getState().scrollToSelectedItem
+                            && getState().pageLength > 0
+                            && getWidget().currentPage < 0
+                            && getWidget().selectedOptionKey != null) {
+                        // search for the item with the selected key
+                        getWidget().currentPage = 0;
+                        for (int i = 0; i < getDataSource().size(); ++i) {
+                            JsonObject row = getDataSource().getRow(i);
+                            if (row != null) {
+                                String key = row.getString(
+                                        DataCommunicatorConstants.KEY);
+                                if (getWidget().selectedOptionKey.equals(key)) {
+                                    if (getWidget().nullSelectionAllowed) {
+                                        getWidget().currentPage = (i + 1)
+                                                / getState().pageLength;
+                                    } else {
+                                        getWidget().currentPage = i
+                                                / getState().pageLength;
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    } else if (getWidget().currentPage < 0) {
+                        getWidget().currentPage = 0;
+                    }
+
+                    getWidget().currentSuggestions.clear();
+
+                    int start = getWidget().currentPage
+                            * getWidget().pageLength;
+                    int end = getWidget().pageLength > 0
+                            ? start + getWidget().pageLength
+                            : getDataSource().size();
+
+                    if (getWidget().nullSelectionAllowed
+                            && "".equals(getWidget().lastFilter)) {
+                        // add special null selection item...
+                        if (getWidget().currentPage == 0) {
+                            getWidget().currentSuggestions
+                                    .add(getWidget().new ComboBoxSuggestion("",
+                                            "", null, null));
+                        } else {
+                            // ...or leave space for it
+                            start = start - 1;
+                        }
+                        // in either case, the last item to show is
+                        // shifted by one
+                        end = end - 1;
+                    }
+
+                    for (int i = start; i < end; ++i) {
+                        JsonObject row = getDataSource().getRow(i);
+
+                        if (row != null) {
+                            String key = row
+                                    .getString(DataCommunicatorConstants.KEY);
+                            String caption = row
+                                    .getString(DataCommunicatorConstants.NAME);
+                            String style = row
+                                    .getString(ComboBoxConstants.STYLE);
+                            String untranslatedIconUri = row
+                                    .getString(ComboBoxConstants.ICON);
+                            getWidget().currentSuggestions
+                                    .add(getWidget().new ComboBoxSuggestion(key,
+                                            caption, style,
+                                            untranslatedIconUri));
+                        }
+                    }
+                    getWidget().totalMatches = getDataSource().size()
+                            + (getState().emptySelectionAllowed ? 1 : 0);
+
+                    getDataReceivedHandler().dataReceived();
+                });
+    }
+
+    @Override
+    public void onUnregister() {
+        super.onUnregister();
+        dataChangeHandlerRegistration.remove();
+    }
+
+    @Override
+    public DataSource<JsonObject> getDataSource() {
+        return dataSource;
+    }
+
+}
diff --git a/server/src/main/java/com/vaadin/ui/ComboBox.java b/server/src/main/java/com/vaadin/ui/ComboBox.java
new file mode 100644 (file)
index 0000000..c76ae4a
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import com.vaadin.data.HasValue;
+import com.vaadin.event.FieldEvents;
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.event.selection.SingleSelectionChange;
+import com.vaadin.event.selection.SingleSelectionListener;
+import com.vaadin.server.KeyMapper;
+import com.vaadin.server.Resource;
+import com.vaadin.server.ResourceReference;
+import com.vaadin.server.data.DataCommunicator;
+import com.vaadin.server.data.DataKeyMapper;
+import com.vaadin.server.data.DataSource;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.data.DataCommunicatorConstants;
+import com.vaadin.shared.data.selection.SelectionModel;
+import com.vaadin.shared.ui.combobox.ComboBoxClientRpc;
+import com.vaadin.shared.ui.combobox.ComboBoxConstants;
+import com.vaadin.shared.ui.combobox.ComboBoxServerRpc;
+import com.vaadin.shared.ui.combobox.ComboBoxState;
+
+import elemental.json.JsonObject;
+
+/**
+ * A filtering dropdown single-select. Items are filtered based on user input.
+ * Supports the creation of new items when a handler is set by the user.
+ *
+ * @param <T>
+ *            item (bean) type in ComboBox
+ * @author Vaadin Ltd
+ */
+@SuppressWarnings("serial")
+public class ComboBox<T> extends
+        AbstractListing<T, ComboBox<T>.ComboBoxSelectionModel> implements
+        HasValue<T>, FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {
+
+    /**
+     * Custom single selection model for ComboBox.
+     */
+    protected class ComboBoxSelectionModel implements SelectionModel.Single<T> {
+        private Optional<T> selectedItem = Optional.empty();
+        private List<SingleSelectionListener<T>> listeners = new ArrayList<>(2);
+
+        @Override
+        public void deselect(T item) {
+            selectedItem.ifPresent(selected -> {
+                if (selected.equals(item)) {
+                    setValue(Optional.empty(), false);
+                }
+            });
+        }
+
+        /**
+         * Sets the selection. This method is primarily for internal use.
+         *
+         * @param value
+         *            optional new value
+         * @param userOriginated
+         *            true if the value comes from user input, false otherwise
+         */
+        protected void setValue(Optional<T> value, boolean userOriginated) {
+            if (selectedItem.equals(value)) {
+                return;
+            }
+            selectedItem = value;
+            String key = value
+                    .map(v -> getDataCommunicator().getKeyMapper().key(v))
+                    .orElse(null);
+            String selectedCaption = value
+                    .map(v -> getItemCaptionProvider().apply(v)).orElse(null);
+            getRpcProxy(ComboBoxClientRpc.class).setSelectedItem(key,
+                    selectedCaption);
+
+            fireEvent(userOriginated);
+        }
+
+        /**
+         * Adds a selection 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 addSelectionListener(
+                SingleSelectionListener<T> listener) {
+            Objects.requireNonNull(listener, "listener cannot be null");
+            listeners.add(listener);
+            return () -> listeners.remove(listener);
+        }
+
+        @Override
+        public void select(T item) {
+            Objects.requireNonNull(item);
+            setValue(Optional.of(item), false);
+        }
+
+        @Override
+        public Optional<T> getSelectedItem() {
+            return selectedItem;
+        }
+
+        /**
+         * Fires a selection change event to all listeners.
+         *
+         * @param userOriginated
+         *            true to indicate that the change was caused directly by a
+         *            user action, false for programmatically set values
+         */
+        protected void fireEvent(boolean userOriginated) {
+            for (SingleSelectionListener<T> listener : listeners) {
+                listener.accept(new SingleSelectionChange<T>(ComboBox.this,
+                        getSelectedItem().orElse(null), userOriginated));
+            }
+        }
+    }
+
+    /**
+     * Handler that adds a new item based on user input when the new items
+     * allowed mode is active.
+     */
+    @FunctionalInterface
+    public interface NewItemHandler extends Consumer<String>, Serializable {
+    }
+
+    /**
+     * ItemCaptionProvider can be used to customize the string shown to the user
+     * for an item.
+     *
+     * @see ComboBox#setItemCaptionProvider(ItemCaptionProvider)
+     * @param <T>
+     *            item type in the combo box
+     */
+    @FunctionalInterface
+    public interface ItemCaptionProvider<T>
+            extends Function<T, String>, Serializable {
+    }
+
+    /**
+     * ItemStyleProvider can be used to add custom styles to combo box items
+     * shown in the popup. The CSS class name that will be added to the item
+     * style names is <tt>v-filterselect-item-[style name]</tt>.
+     *
+     * @see ComboBox#setItemStyleProvider(ItemStyleProvider)
+     * @param <T>
+     *            item type in the combo box
+     */
+    @FunctionalInterface
+    public interface ItemStyleProvider<T>
+            extends Function<T, String>, Serializable {
+    }
+
+    /**
+     * ItemIconProvider can be used to add custom icons to combo box items shown
+     * in the popup.
+     *
+     * @see ComboBox#setItemIconProvider(ItemIconProvider)
+     * @param <T>
+     *            item type in the combo box
+     */
+    @FunctionalInterface
+    public interface ItemIconProvider<T>
+            extends Function<T, Resource>, Serializable {
+    }
+
+    /**
+     * Filter can be used to customize the filtering of items based on user
+     * input.
+     *
+     * @see ComboBox#setFilter(ItemFilter)
+     * @param <T>
+     *            item type in the combo box
+     */
+    @FunctionalInterface
+    public interface ItemFilter<T>
+            extends BiFunction<String, T, Boolean>, Serializable {
+    }
+
+    private ComboBoxServerRpc rpc = new ComboBoxServerRpc() {
+        @Override
+        public void createNewItem(String itemValue) {
+            // New option entered
+            if (getNewItemHandler() != null && itemValue != null
+                    && itemValue.length() > 0) {
+                getNewItemHandler().accept(itemValue);
+                // rebuild list
+                filterstring = null;
+            }
+        }
+
+        @Override
+        public void setSelectedItem(String key) {
+            // it seems both of these happen, and mean empty selection...
+            if (key == null || "".equals(key)) {
+                getSelectionModel().setValue(Optional.empty(), true);
+            } else {
+                T item = getDataCommunicator().getKeyMapper().get(key);
+                getSelectionModel().setValue(Optional.ofNullable(item), true);
+            }
+        }
+
+        @Override
+        public void setFilter(String filterText) {
+            filterstring = filterText;
+            if (filterText != null) {
+                getDataCommunicator().setInMemoryFilter(
+                        item -> filter.apply(filterstring, item));
+            } else {
+                getDataCommunicator().setInMemoryFilter(null);
+            }
+        }
+    };
+
+    private FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl(
+            this) {
+        @Override
+        protected void fireEvent(Component.Event event) {
+            ComboBox.this.fireEvent(event);
+        }
+    };
+
+    private String filterstring;
+
+    /**
+     * Handler for new items entered by the user.
+     */
+    private NewItemHandler newItemHandler;
+
+    private ItemCaptionProvider<T> itemCaptionProvider = String::valueOf;
+
+    private ItemStyleProvider<T> itemStyleProvider = item -> null;
+    private ItemIconProvider<T> itemIconProvider = item -> null;
+
+    private ItemFilter<T> filter = (filterText, item) -> {
+        if (filterText == null) {
+            return true;
+        } else {
+            return getItemCaptionProvider().apply(item).toLowerCase(getLocale())
+                    .contains(filterText.toLowerCase(getLocale()));
+        }
+    };
+
+    /**
+     * Constructs an empty combo box without a caption. The content of the combo
+     * box can be set with {@link #setDataSource(DataSource)} or
+     * {@link #setItems(Collection)}
+     */
+    public ComboBox() {
+        super(new DataCommunicator<T>() {
+            @Override
+            protected DataKeyMapper<T> createKeyMapper() {
+                return new KeyMapper<T>() {
+                    @Override
+                    public void remove(T removeobj) {
+                        // never remove keys from ComboBox to support selection
+                        // of items that are not currently visible
+                    }
+                };
+            }
+        });
+        setSelectionModel(new ComboBoxSelectionModel());
+
+        init();
+    }
+
+    /**
+     * Constructs an empty combo box, whose content can be set with
+     * {@link #setDataSource(DataSource)} or {@link #setItems(Collection)}.
+     *
+     * @param caption
+     *            the caption to show in the containing layout, null for no
+     *            caption
+     */
+    public ComboBox(String caption) {
+        this();
+        setCaption(caption);
+    }
+
+    /**
+     * Constructs a combo box with a static in-memory data source with the given
+     * options.
+     *
+     * @param caption
+     *            the caption to show in the containing layout, null for no
+     *            caption
+     * @param options
+     *            collection of options, not null
+     */
+    public ComboBox(String caption, Collection<T> options) {
+        this(caption, DataSource.create(options));
+    }
+
+    /**
+     * Constructs a combo box with the given data source.
+     *
+     * @param caption
+     *            the caption to show in the containing layout, null for no
+     *            caption
+     * @param dataSource
+     *            the data source to use, not null
+     */
+    public ComboBox(String caption, DataSource<T> dataSource) {
+        this(caption);
+        setDataSource(dataSource);
+    }
+
+    /**
+     * Initialize the ComboBox with default settings and register client to
+     * server RPC implementation.
+     */
+    private void init() {
+        registerRpc(rpc);
+        registerRpc(focusBlurRpc);
+
+        addDataGenerator((T data, JsonObject jsonObject) -> {
+            jsonObject.put(DataCommunicatorConstants.NAME,
+                    getItemCaptionProvider().apply(data));
+            String style = itemStyleProvider.apply(data);
+            if (style != null) {
+                jsonObject.put(ComboBoxConstants.STYLE, style);
+            }
+            Resource icon = itemIconProvider.apply(data);
+            if (icon != null) {
+                String iconUrl = ResourceReference
+                        .create(icon, ComboBox.this, null).getURL();
+                jsonObject.put(ComboBoxConstants.ICON, iconUrl);
+            }
+        });
+    }
+
+    /**
+     * Gets the current placeholder text shown when the combo box would be
+     * empty.
+     *
+     * @see #setPlaceholder(String)
+     * @return the current placeholder string, or null if not enabled
+     */
+    public String getPlaceholder() {
+        return getState(false).placeholder;
+    }
+
+    /**
+     * Sets the placeholder string - a textual prompt that is displayed when the
+     * select would otherwise be empty, to prompt the user for input.
+     *
+     * @param placeholder
+     *            the desired placeholder, or null to disable
+     */
+    public void setPlaceholder(String placeholder) {
+        getState().placeholder = placeholder;
+    }
+
+    /**
+     * Sets whether it is possible to input text into the field or whether the
+     * field area of the component is just used to show what is selected. By
+     * disabling text input, the comboBox will work in the same way as a
+     * {@link NativeSelect}
+     *
+     * @see #isTextInputAllowed()
+     *
+     * @param textInputAllowed
+     *            true to allow entering text, false to just show the current
+     *            selection
+     */
+    public void setTextInputAllowed(boolean textInputAllowed) {
+        getState().textInputAllowed = textInputAllowed;
+    }
+
+    /**
+     * Returns true if the user can enter text into the field to either filter
+     * the selections or enter a new value if {@link #isNewItemsAllowed()}
+     * returns true. If text input is disabled, the comboBox will work in the
+     * same way as a {@link NativeSelect}
+     *
+     * @return true if text input is allowed
+     */
+    public boolean isTextInputAllowed() {
+        return getState(false).textInputAllowed;
+    }
+
+    @Override
+    public void addBlurListener(BlurListener listener) {
+        addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
+                BlurListener.blurMethod);
+    }
+
+    @Override
+    public void removeBlurListener(BlurListener listener) {
+        removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
+    }
+
+    @Override
+    public void addFocusListener(FocusListener listener) {
+        addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
+                FocusListener.focusMethod);
+    }
+
+    @Override
+    public void removeFocusListener(FocusListener listener) {
+        removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
+    }
+
+    /**
+     * Returns the page length of the suggestion popup.
+     *
+     * @return the pageLength
+     */
+    public int getPageLength() {
+        return getState(false).pageLength;
+    }
+
+    /**
+     * Returns the suggestion pop-up's width as a CSS string.
+     *
+     * @see #setPopupWidth
+     * @since 7.7
+     * @return explicitly set popup width as CSS size string or null if not set
+     */
+    public String getPopupWidth() {
+        return getState(false).suggestionPopupWidth;
+    }
+
+    /**
+     * Sets the page length for the suggestion popup. Setting the page length to
+     * 0 will disable suggestion popup paging (all items visible).
+     *
+     * @param pageLength
+     *            the pageLength to set
+     */
+    public void setPageLength(int pageLength) {
+        getState().pageLength = pageLength;
+    }
+
+    /**
+     * Returns whether the user is allowed to select nothing in the combo box.
+     *
+     * @return true if empty selection is allowed, false otherwise
+     */
+    public boolean isEmptySelectionAllowed() {
+        return getState(false).emptySelectionAllowed;
+    }
+
+    /**
+     * Sets whether the user is allowed to select nothing in the combo box. When
+     * true, a special empty item is shown to the user.
+     *
+     * @param emptySelectionAllowed
+     *            true to allow not selecting anything, false to require
+     *            selection
+     */
+    public void setEmptySelectionAllowed(boolean emptySelectionAllowed) {
+        getState().emptySelectionAllowed = emptySelectionAllowed;
+    }
+
+    /**
+     * Sets the suggestion pop-up's width as a CSS string. By using relative
+     * units (e.g. "50%") it's possible to set the popup's width relative to the
+     * ComboBox itself.
+     *
+     * @see #getPopupWidth()
+     * @since 7.7
+     * @param width
+     *            the width
+     */
+    public void setPopupWidth(String width) {
+        getState().suggestionPopupWidth = width;
+    }
+
+    /**
+     * Sets whether to scroll the selected item visible (directly open the page
+     * on which it is) when opening the combo box popup or not.
+     *
+     * This requires finding the index of the item, which can be expensive in
+     * many large lazy loading containers.
+     *
+     * @param scrollToSelectedItem
+     *            true to find the page with the selected item when opening the
+     *            selection popup
+     */
+    public void setScrollToSelectedItem(boolean scrollToSelectedItem) {
+        getState().scrollToSelectedItem = scrollToSelectedItem;
+    }
+
+    /**
+     * Returns true if the select should find the page with the selected item
+     * when opening the popup.
+     *
+     * @see #setScrollToSelectedItem(boolean)
+     *
+     * @return true if the page with the selected item will be shown when
+     *         opening the popup
+     */
+    public boolean isScrollToSelectedItem() {
+        return getState(false).scrollToSelectedItem;
+    }
+
+    /**
+     * Gets the item caption provider that is used to produce the strings shown
+     * in the combo box for each item.
+     *
+     * @return the item caption provider used, not null
+     */
+    public ItemCaptionProvider<T> getItemCaptionProvider() {
+        return itemCaptionProvider;
+    }
+
+    /**
+     * Sets the item caption provider that is used to produce the strings shown
+     * in the combo box for each item. By default,
+     * {@link String#valueOf(Object)} is used.
+     *
+     * @param itemCaptionProvider
+     *            the item caption provider to use, not null
+     */
+    public void setItemCaptionProvider(
+            ItemCaptionProvider<T> itemCaptionProvider) {
+        Objects.requireNonNull(itemCaptionProvider,
+                "Item caption providers must not be null");
+        this.itemCaptionProvider = itemCaptionProvider;
+        getDataCommunicator().reset();
+    }
+
+    /**
+     * Sets the item style provider that is used to produce custom styles for
+     * showing items in the popup. The CSS class name that will be added to the
+     * item style names is <tt>v-filterselect-item-[style name]</tt>. Returning
+     * null from the provider results in no custom style name being set.
+     *
+     * @param itemStyleProvider
+     *            the item style provider to set, not null
+     */
+    public void setItemStyleProvider(ItemStyleProvider<T> itemStyleProvider) {
+        Objects.requireNonNull(itemStyleProvider,
+                "Item style providers must not be null");
+        this.itemStyleProvider = itemStyleProvider;
+        getDataCommunicator().reset();
+    }
+
+    /**
+     * Gets the currently used item style provider that is used to generate CSS
+     * class names for items. The default item style provider returns null for
+     * all items, resulting in no custom item class names being set.
+     *
+     * @see #setItemStyleProvider(ItemStyleProvider)
+     *
+     * @return the currently used item style provider, not null
+     */
+    public ItemStyleProvider<T> getItemStyleProvider() {
+        return itemStyleProvider;
+    }
+
+    /**
+     * Sets the item icon provider that is used to produce custom icons for
+     * showing items in the popup. The provider can return null for items with
+     * no icon.
+     *
+     * @param itemIconProvider
+     *            the item icon provider to set, not null
+     */
+    public void setItemIconProvider(ItemIconProvider<T> itemIconProvider) {
+        Objects.requireNonNull(itemIconProvider,
+                "Item icon providers must not be null");
+        this.itemIconProvider = itemIconProvider;
+        getDataCommunicator().reset();
+    }
+
+    /**
+     * Gets the currently used item icon provider. The default item icon
+     * provider returns null for all items, resulting in no icons being used.
+     *
+     * @see #setItemIconProvider(ItemIconProvider)
+     *
+     * @return the currently used item icon provider, not null
+     */
+    public ItemIconProvider<T> getItemIconProvider() {
+        return itemIconProvider;
+    }
+
+    /**
+     * Sets the handler that is called when user types a new item. The creation
+     * of new items is allowed when a new item handler has been set.
+     *
+     * @param newItemHandler
+     *            handler called for new items, null to only permit the
+     *            selection of existing items
+     */
+    public void setNewItemHandler(NewItemHandler newItemHandler) {
+        this.newItemHandler = newItemHandler;
+        getState().allowNewItems = (newItemHandler != null);
+        markAsDirty();
+    }
+
+    /**
+     * Returns the handler called when the user enters a new item (not present
+     * in the data source).
+     *
+     * @return new item handler or null if none specified
+     */
+    public NewItemHandler getNewItemHandler() {
+        return newItemHandler;
+    }
+
+    // HasValue methods delegated to the selection model
+
+    /**
+     * Returns the filter used to customize the list based on user input.
+     *
+     * @return the current filter, not null
+     */
+    public ItemFilter<T> getFilter() {
+        return filter;
+    }
+
+    /**
+     * Sets the filter used to customize the list based on user input. The
+     * default filter checks case-insensitively that the input string is
+     * contained in the item caption.
+     *
+     * @param filter
+     *            the filter function to use, not null
+     */
+    public void setFilter(ItemFilter<T> filter) {
+        Objects.requireNonNull(filter, "Item filter must not be null");
+        this.filter = filter;
+    }
+
+    @Override
+    public void setValue(T value) {
+        getSelectionModel().setValue(Optional.ofNullable(value), false);
+
+    }
+
+    @Override
+    public T getValue() {
+        return getSelectionModel().getSelectedItem().orElse(null);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Registration addValueChangeListener(
+            HasValue.ValueChangeListener<? super T> listener) {
+        return getSelectionModel().addSelectionListener(event -> {
+            ((ValueChangeListener<T>) listener)
+                    .accept(new ValueChange<T>(event.getConnector(),
+                            event.getValue(), event.isUserOriginated()));
+        });
+    }
+
+    @Override
+    protected ComboBoxState getState() {
+        return (ComboBoxState) super.getState();
+    }
+
+    @Override
+    protected ComboBoxState getState(boolean markAsDirty) {
+        return (ComboBoxState) super.getState(markAsDirty);
+    }
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxClientRpc.java b/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxClientRpc.java
new file mode 100644 (file)
index 0000000..1e8273c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.shared.ui.combobox;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+/**
+ * Server to client RPC interface for ComboBox.
+ *
+ * @since
+ */
+public interface ComboBoxClientRpc extends ClientRpc {
+    /**
+     * Set the current selection.
+     *
+     * @param selectedKey
+     *            the id of a single item or null to deselect the current value
+     * @param selectedCaption
+     *            the caption of the selected item (used in case selection is
+     *            outside the lazy loaded range)
+     */
+    public void setSelectedItem(String selectedKey, String selectedCaption);
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxConstants.java b/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxConstants.java
new file mode 100644 (file)
index 0000000..1944c3a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.shared.ui.combobox;
+
+import java.io.Serializable;
+
+/**
+ * Constants related to the combo box component and its client-server
+ * communication.
+ *
+ * @since 8.0
+ * @author Vaadin Ltd
+ */
+public class ComboBoxConstants implements Serializable {
+    public static final String STYLE = "style";
+    public static final String ICON = "icon";
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxServerRpc.java b/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxServerRpc.java
new file mode 100644 (file)
index 0000000..9d6ba6d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.shared.ui.combobox;
+
+import com.vaadin.shared.communication.ServerRpc;
+
+/**
+ * Client to server RPC interface for ComboBox.
+ *
+ * @since
+ */
+public interface ComboBoxServerRpc extends ServerRpc {
+    /**
+     * Create a new item in the combo box. This method can only be used when the
+     * ComboBox is configured to allow the creation of new items by the user.
+     *
+     * @param itemValue
+     *            user entered string value for the new item
+     */
+    public void createNewItem(String itemValue);
+
+    /**
+     * Set the current selection.
+     *
+     * @param item
+     *            the id of a single item or null to deselect the current value
+     */
+    public void setSelectedItem(String item);
+
+    /**
+     * Sets the filter to use.
+     *
+     * @param filter
+     *            filter string interpreted according to the current filtering
+     *            mode
+     */
+    public void setFilter(String filter);
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxState.java b/shared/src/main/java/com/vaadin/shared/ui/combobox/ComboBoxState.java
new file mode 100644 (file)
index 0000000..72d10b8
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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.shared.ui.combobox;
+
+import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.annotations.DelegateToWidget;
+import com.vaadin.shared.annotations.NoLayout;
+
+/**
+ * Shared state for the ComboBox component.
+ *
+ * @since 7.0
+ */
+public class ComboBoxState extends AbstractFieldState {
+    {
+        // TODO ideally this would be v-combobox, but that would affect a lot of
+        // themes
+        primaryStyleName = "v-filterselect";
+    }
+
+    /**
+     * If text input is not allowed, the ComboBox behaves like a pretty
+     * NativeSelect - the user can not enter any text and clicking the text
+     * field opens the drop down with options.
+     *
+     * @since
+     */
+    @DelegateToWidget
+    public boolean textInputAllowed = true;
+
+    /**
+     * The prompt to display in an empty field. Null when disabled.
+     */
+    @DelegateToWidget
+    @NoLayout
+    public String placeholder = null;
+
+    /**
+     * Number of items to show per page or 0 to disable paging.
+     */
+    @DelegateToWidget
+    public int pageLength = 10;
+
+    /**
+     * Suggestion pop-up's width as a CSS string. By using relative units (e.g.
+     * "50%") it's possible to set the popup's width relative to the ComboBox
+     * itself.
+     */
+    @DelegateToWidget
+    public String suggestionPopupWidth = null;
+
+    /**
+     * True to allow the user to send new items to the server, false to only
+     * select among existing items.
+     */
+    @DelegateToWidget
+    public boolean allowNewItems = false;
+
+    /**
+     * True to allow selecting nothing (a special empty selection item is shown
+     * at the beginning of the list), false not to allow empty selection by the
+     * user.
+     */
+    public boolean emptySelectionAllowed = true;
+
+    /**
+     * True to automatically scroll the ComboBox to show the selected item,
+     * false not to search for it in the results.
+     */
+    public boolean scrollToSelectedItem = false;
+
+}
diff --git a/uitest-common/src/main/java/com/vaadin/testbench/customelements/ComboBoxElement.java b/uitest-common/src/main/java/com/vaadin/testbench/customelements/ComboBoxElement.java
new file mode 100644 (file)
index 0000000..0f3b7b9
--- /dev/null
@@ -0,0 +1,61 @@
+package com.vaadin.testbench.customelements;
+
+import org.junit.Assert;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ComboBox")
+public class ComboBoxElement
+        extends com.vaadin.testbench.elements.ComboBoxElement {
+
+    private static org.openqa.selenium.By bySuggestionPopup = By
+            .vaadin("#popup");
+
+    public WebElement getInputField() {
+        return findElement(By.vaadin("#textbox"));
+    }
+
+    @Override
+    public String getText() {
+        return getInputField().getAttribute("value");
+    }
+
+    @Override
+    public void clear() {
+        getInputField().clear();
+    }
+
+    public WebElement getSuggestionPopup() {
+        return findElement(bySuggestionPopup);
+    }
+
+    @Override
+    public void sendKeys(CharSequence... keysToSend) {
+        sendKeys(50, keysToSend);
+    }
+
+    /**
+     * Use this method to simulate typing into an element, which may set its
+     * value.
+     *
+     * @param delay
+     *            delay after sending each individual key (mainly needed for
+     *            PhantomJS)
+     * @param keysToSend
+     *            keys to type into the element
+     */
+    public void sendKeys(int delay, CharSequence... keysToSend) {
+        WebElement input = getInputField();
+
+        for (CharSequence key : keysToSend) {
+            input.sendKeys(key);
+            try {
+                Thread.sleep(delay);
+            } catch (InterruptedException e) {
+                Assert.fail(e.getMessage());
+            }
+        }
+    }
+}
index 898c1014fca323ae6919c6436c9fef0401fedc6e..7c616521fcab5d701d7b2c00c10a678b1a6b0c7f 100644 (file)
@@ -6,8 +6,8 @@ import java.util.List;
 import com.vaadin.server.CompositeErrorMessage;
 import com.vaadin.server.UserError;
 import com.vaadin.ui.Button;
-import com.vaadin.v7.ui.ComboBox;
-import com.vaadin.v7.ui.TextField;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.TextField;
 
 public class ErrorMessages extends TestBase {
 
@@ -24,7 +24,8 @@ public class ErrorMessages extends TestBase {
         tf.setComponentError(new UserError("This is a failure"));
         addComponent(tf);
 
-        ComboBox cb = new ComboBox("ComboBox with description and UserError");
+        ComboBox<String> cb = new ComboBox<>(
+                "ComboBox with description and UserError");
         cb.setDescription("This is a combobox");
         cb.setComponentError(new UserError("This is a failure"));
         addComponent(cb);
index 807af1efd8baea9526b69dbb69ffad10cc63dd50..c16b811038f9f7a16718f147f633c7d1110a2b8b 100644 (file)
@@ -10,12 +10,12 @@ import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.Button.ClickListener;
 import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.DateField;
 import com.vaadin.ui.Label;
 import com.vaadin.ui.Layout;
 import com.vaadin.ui.NativeButton;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.OptionGroup;
 import com.vaadin.v7.ui.TextField;
 
index f4cc2e5560ce5662a6309b1812a0b85fedd479ef..12a48b1a9698b067a05118c0e2f53b83949fdc64 100644 (file)
@@ -5,13 +5,11 @@ import com.vaadin.shared.ui.label.ContentMode;
 import com.vaadin.tests.VaadinClasses;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.tests.util.Log;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.ComponentContainer;
 import com.vaadin.ui.Embedded;
 import com.vaadin.ui.Label;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
 
 public class IconsInCaption extends TestBase {
 
@@ -35,38 +33,20 @@ public class IconsInCaption extends TestBase {
 
     private Log log = new Log(5);
 
-    private ComboBox containerSelect;
+    private ComboBox<Class<? extends ComponentContainer>> containerSelect;
 
-    private ComboBox iconTypeSelect;
+    private ComboBox<String> iconTypeSelect;
 
     @Override
     protected void setup() {
-        iconTypeSelect = new ComboBox("Icon container");
-        iconTypeSelect.addItem(TYPE_EMBEDDED);
-        iconTypeSelect.addItem(TYPE_CAPTION);
-        iconTypeSelect.setImmediate(true);
-        iconTypeSelect.setNullSelectionAllowed(false);
-        iconTypeSelect.addListener(new ValueChangeListener() {
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                updateContainer();
-            }
-        });
-
-        containerSelect = new ComboBox("Container");
-        for (Class<? extends ComponentContainer> cc : VaadinClasses
-                .getComponentContainersSupportingUnlimitedNumberOfComponents()) {
-            containerSelect.addItem(cc);
-        }
-        containerSelect.setImmediate(true);
-        containerSelect.addListener(new ValueChangeListener() {
+        iconTypeSelect = new ComboBox<>("Icon container");
+        iconTypeSelect.setItems(TYPE_EMBEDDED, TYPE_CAPTION);
+        iconTypeSelect.setEmptySelectionAllowed(false);
+        iconTypeSelect.addValueChangeListener(event -> updateContainer());
 
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                updateContainer();
-
-            }
-        });
+        containerSelect = new ComboBox<>("Container", VaadinClasses
+                .getComponentContainersSupportingUnlimitedNumberOfComponents());
+        containerSelect.addValueChangeListener(event -> updateContainer());
 
         addComponent(log);
         addComponent(iconTypeSelect);
@@ -78,7 +58,7 @@ public class IconsInCaption extends TestBase {
     }
 
     protected void updateContainer() {
-        Class<? extends ComponentContainer> containerClass = (Class<? extends ComponentContainer>) containerSelect
+        Class<? extends ComponentContainer> containerClass = containerSelect
                 .getValue();
         if (containerClass == null) {
             return;
index a2f54de1f85b13d6a70116d790fed0d84eef7180..4d30db6e5432159a81c57f007a34a0e61aec0774 100644 (file)
@@ -4,9 +4,7 @@ import java.util.Arrays;
 
 import com.vaadin.server.UserError;
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxBorder extends TestBase {
 
@@ -14,17 +12,13 @@ public class ComboBoxBorder extends TestBase {
     protected void setup() {
         setTheme("tests-tickets");
 
-        final ComboBox cb = new ComboBox("All errors",
+        final ComboBox<String> cb = new ComboBox<>("All errors",
                 Arrays.asList("Error", "Error 2"));
         cb.setStyleName("ComboBoxBorder");
-        cb.setImmediate(true);
         cb.setWidth("200px"); // must have with to reproduce
 
-        cb.addListener(new ValueChangeListener() {
-            public void valueChange(ValueChangeEvent event) {
-                cb.setComponentError(new UserError("Error"));
-            }
-        });
+        cb.addValueChangeListener(
+                event -> cb.setComponentError(new UserError("Error")));
 
         addComponent(cb);
 
index 8cb6ab3ba8ec4f49d30ecaf353efea8a9923ae10..886dfc7ae243caceef89ca01189a1e26320d9da6 100644 (file)
  */
 package com.vaadin.tests.components.combobox;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import com.vaadin.server.FontAwesome;
 import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 /**
  * Test UI to check click on icon in the combobox.
@@ -32,16 +30,9 @@ public class ComboBoxClickIcon extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        final List<String> items = new ArrayList<>();
-        items.add("A");
-        items.add("B");
-        items.add("C");
-        final ComboBox combo = new ComboBox();
-        combo.setImmediate(true);
-        combo.setItemIcon(items.get(0), FontAwesome.ALIGN_CENTER);
-        combo.setItemIcon(items.get(1), FontAwesome.ALIGN_CENTER);
-        combo.setItemIcon(items.get(2), FontAwesome.ALIGN_CENTER);
-        combo.addItems(items);
+        final ComboBox<String> combo = new ComboBox<>(null,
+                DataSource.create("A", "B", "C"));
+        combo.setItemIconProvider(item -> FontAwesome.ALIGN_CENTER);
         combo.setTextInputAllowed(false);
         addComponent(combo);
     }
index 7baee460c9d70cc29417bada0e1a8d8e254f1813..b3f5a6835321e6eb83f66dc873ee0e7e52aa921e 100644 (file)
@@ -17,9 +17,9 @@ package com.vaadin.tests.components.combobox;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxCursorPositionReset extends AbstractTestUI {
 
@@ -29,11 +29,10 @@ public class ComboBoxCursorPositionReset extends AbstractTestUI {
         root.setSizeFull();
         setContent(root);
 
-        ComboBox combo = new ComboBox();
+        ComboBox<String> combo = new ComboBox<>();
         combo.setImmediate(true);
         root.addComponent(combo);
-        combo.addItem("Hello World");
-        combo.addItem("Please click on the text");
+        combo.setItems("Hello World", "Please click on the text");
 
         combo.setValue("Please click on the text");
         Label gap = new Label();
index 2a4d57c97fb614a30bf98b9f3d2027fec7f40d22..df093a297605ccd848ac929662af87ed6476d0c6 100644 (file)
@@ -7,10 +7,7 @@ import com.vaadin.tests.components.TestBase;
 import com.vaadin.tests.util.Log;
 import com.vaadin.tests.util.Person;
 import com.vaadin.ui.Button;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.data.util.BeanItemContainer;
-import com.vaadin.v7.ui.AbstractSelect.ItemCaptionMode;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxDuplicateCaption extends TestBase {
 
@@ -29,25 +26,14 @@ public class ComboBoxDuplicateCaption extends TestBase {
         p2.setLastName("Doe");
         list.add(p2);
 
-        BeanItemContainer<Person> container = new BeanItemContainer<>(
-                Person.class);
-        container.addAll(list);
-
-        ComboBox box = new ComboBox("Duplicate captions test Box");
+        ComboBox<Person> box = new ComboBox<>("Duplicate captions test Box");
         box.setId("ComboBox");
-        box.setImmediate(true);
-        box.addValueChangeListener(new ValueChangeListener() {
-
-            @Override
-            public void valueChange(
-                    com.vaadin.v7.data.Property.ValueChangeEvent event) {
-                Person p = (Person) event.getProperty().getValue();
-                log.log("Person = " + p.getFirstName() + " " + p.getLastName());
-            }
+        box.addValueChangeListener(event -> {
+            Person p = event.getValue();
+            log.log("Person = " + p.getFirstName() + " " + p.getLastName());
         });
-        box.setContainerDataSource(container);
-        box.setItemCaptionMode(ItemCaptionMode.PROPERTY);
-        box.setItemCaptionPropertyId("lastName");
+        box.setItems(list);
+        box.setItemCaptionProvider(Person::getLastName);
 
         addComponent(log);
 
@@ -57,7 +43,7 @@ public class ComboBoxDuplicateCaption extends TestBase {
 
     @Override
     protected String getDescription() {
-        return "VFilterSelects with duplicate item captions should not try to do a select (exact match search) for onBlur if not waitingForFilteringResponse";
+        return "ComboBoxes with duplicate item captions should not try to do a select (exact match search) for onBlur if not waitingForFilteringResponse";
     }
 
     @Override
index 4d5c25597ea8d0d9f131d23f53dd1d6cb228b9b4..3fe049f65bd891621b59bd9ec3421fee49fbae67 100644 (file)
@@ -1,14 +1,15 @@
 package com.vaadin.tests.components.combobox;
 
 import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxEmptyItemsKeyboardNavigation extends AbstractTestUI {
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox comboBox = new ComboBox();
-        comboBox.addItems("foo", "bar");
+        ComboBox<String> comboBox = new ComboBox<>(null,
+                DataSource.create("foo", "bar"));
 
         addComponent(comboBox);
     }
index 16b3c5df5c4515353620e41c5694b8502def497b..28b791626b5ced8eda066fbc6b93a936ea6dec12 100644 (file)
@@ -1,9 +1,10 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxEnablesComboBox extends TestBase {
 
@@ -11,19 +12,10 @@ public class ComboBoxEnablesComboBox extends TestBase {
 
     @Override
     protected void setup() {
-        ComboBox cb = new ComboBox("Always enabled");
-        cb.setImmediate(true);
+        ComboBox<String> cb = new ComboBox<>("Always enabled");
         populate(cb);
-        cb.addListener(new ValueChangeListener() {
-
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                cb2.setEnabled(true);
-            }
-
-        });
-        cb2 = new ComboBox("Initially disabled");
-        cb2.setImmediate(true);
+        cb.addValueChangeListener(event -> cb2.setEnabled(true));
+        cb2 = new ComboBox<String>("Initially disabled");
         cb2.setEnabled(false);
         populate(cb2);
 
@@ -31,10 +23,12 @@ public class ComboBoxEnablesComboBox extends TestBase {
         addComponent(cb2);
     }
 
-    private void populate(ComboBox cb) {
+    private void populate(ComboBox<String> cb) {
+        List<String> items = new ArrayList<>();
         for (int i = 1; i < 10; i++) {
-            cb.addItem("Item " + i);
+            items.add("Item " + i);
         }
+        cb.setItems(items);
     }
 
     @Override
index ed915f1a51448aaa38c00574d937cde9fa395c50..3de97dc46cfcedc7fdec9815bfbcc5f91621cba4 100644 (file)
@@ -3,36 +3,21 @@ package com.vaadin.tests.components.combobox;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.tests.util.Log;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.data.Property;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxIdenticalItems extends AbstractTestUI {
 
     private Log log = new Log(5);
 
-    @SuppressWarnings("unchecked")
     @Override
     protected void setup(VaadinRequest request) {
-        final ComboBox select = new ComboBox("ComboBox");
-        select.addContainerProperty("caption", String.class, null);
-        Item item = select.addItem("one-1");
-        item.getItemProperty("caption").setValue("One");
-        item = select.addItem("one-2");
-        item.getItemProperty("caption").setValue("One");
-        item = select.addItem("two");
-        item.getItemProperty("caption").setValue("Two");
-        select.setItemCaptionPropertyId("caption");
-        select.setNullSelectionAllowed(false);
-        select.setImmediate(true);
-        select.addValueChangeListener(new Property.ValueChangeListener() {
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                log.log("Item " + select.getValue() + " selected");
-
-            }
-        });
+        final ComboBox<String> select = new ComboBox<>("ComboBox");
+        select.setItemCaptionProvider(
+                item -> item.startsWith("one") ? "One" : "Two");
+        select.setItems("one-1", "one-2", "two");
+        select.setEmptySelectionAllowed(false);
+        select.addValueChangeListener(
+                event -> log.log("Item " + select.getValue() + " selected"));
 
         addComponent(log);
         addComponent(select);
@@ -41,10 +26,10 @@ public class ComboBoxIdenticalItems extends AbstractTestUI {
     @Override
     protected String getTestDescription() {
         return "Keyboard selecting of a value is broken in combobox if two "
-                + "items have the same caption. The first item's id is \"One-1\" "
-                + "while the second one is \"One-2\". Selecting with mouse works "
+                + "items have the same caption. The first item's id is \"one-1\" "
+                + "while the second one is \"one-2\". Selecting with mouse works "
                 + "as expected but selecting with keyboard always returns the "
-                + "object \"One-1\".";
+                + "object \"one-1\".";
     }
 
     @Override
index d09ca0c99dec81416133c283d9bc5cedd8141864..f34259e750478602a26fd2656fd0ca1eb10668c1 100644 (file)
@@ -1,13 +1,14 @@
 package com.vaadin.tests.components.combobox;
 
 import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxInPopup extends TestBase {
 
@@ -34,12 +35,8 @@ public class ComboBoxInPopup extends TestBase {
     }
 
     private Component createComboBox() {
-        ComboBox cb = new ComboBox("A combo box");
-
-        cb.addItem("Yes");
-        cb.addItem("No");
-        cb.addItem("Maybe");
-        return cb;
+        return new ComboBox<String>("A combo box",
+                DataSource.create("Yes", "No", "Maybe"));
     }
 
     @Override
index 5137d8f7511143a82bc663d45f00d3b331adcd44..4e17ab6072fa145ba5941c3cf41ccc16faa21988 100644 (file)
@@ -18,33 +18,27 @@ package com.vaadin.tests.components.combobox;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxInputPrompt extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        final ComboBox cb1 = new ComboBox("Normal");
-        cb1.setInputPrompt("Normal input prompt");
+        final ComboBox<String> cb1 = new ComboBox<String>("Normal");
+        cb1.setPlaceholder("Normal input prompt");
 
-        final ComboBox cb2 = new ComboBox("Disabled");
+        final ComboBox<String> cb2 = new ComboBox<String>("Disabled");
         cb2.setEnabled(false);
-        cb2.setInputPrompt("Disabled input prompt");
+        cb2.setPlaceholder("Disabled input prompt");
 
-        final ComboBox cb3 = new ComboBox("Read-only");
+        final ComboBox<String> cb3 = new ComboBox<String>("Read-only");
         cb3.setReadOnly(true);
-        cb3.setInputPrompt("Read-only input prompt");
+        cb3.setPlaceholder("Read-only input prompt");
 
-        Button enableButton = new Button("Toggle enabled",
-                new Button.ClickListener() {
-
-                    @Override
-                    public void buttonClick(ClickEvent event) {
-                        cb2.setEnabled(!cb2.isEnabled());
-                        cb3.setReadOnly(!cb3.isReadOnly());
-                    }
-                });
+        Button enableButton = new Button("Toggle enabled", event -> {
+            cb2.setEnabled(!cb2.isEnabled());
+            cb3.setReadOnly(!cb3.isReadOnly());
+        });
 
         addComponents(cb1, cb2, cb3, enableButton);
     }
index b83f295682d8cb8198ef9640e8ac77d9526a0f04..a569801cbee3b804cbe871e8532343b6fd0bd0c0 100644 (file)
@@ -1,20 +1,17 @@
 package com.vaadin.tests.components.combobox;
 
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.tests.util.Log;
 import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.data.util.IndexedContainer;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxInvalidNullSelection extends TestBase {
 
     private static final Object CAPTION = "C";
-    private IndexedContainer ds1;
-    private IndexedContainer ds2;
-    private ComboBox combo;
+    private DataSource<String> ds1;
+    private DataSource<String> ds2;
+    private ComboBox<String> combo;
     private Log log = new Log(5);
 
     @Override
@@ -23,28 +20,19 @@ public class ComboBoxInvalidNullSelection extends TestBase {
         createDataSources();
 
         Button b = new Button("Swap data source");
-        b.addListener(new Button.ClickListener() {
-            @Override
-            public void buttonClick(ClickEvent event) {
-                if (combo.getContainerDataSource() == ds1) {
-                    combo.setContainerDataSource(ds2);
-                } else {
-                    combo.setContainerDataSource(ds1);
-                }
-                combo.setValue("Item 3");
+        b.addClickListener(event -> {
+            if (combo.getDataSource() == ds1) {
+                combo.setDataSource(ds2);
+            } else {
+                combo.setDataSource(ds1);
             }
+            combo.setValue("Item 3");
         });
 
-        combo = new ComboBox();
-        combo.setImmediate(true);
-        combo.setContainerDataSource(ds1);
-        combo.addListener(new ValueChangeListener() {
-
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                log.log("Value is now: " + combo.getValue());
-            }
-        });
+        combo = new ComboBox<>();
+        combo.setDataSource(ds1);
+        combo.addValueChangeListener(
+                event -> log.log("Value is now: " + combo.getValue()));
         addComponent(log);
         addComponent(b);
         addComponent(combo);
@@ -52,16 +40,9 @@ public class ComboBoxInvalidNullSelection extends TestBase {
     }
 
     private void createDataSources() {
-        ds1 = new IndexedContainer();
-        ds1.addContainerProperty(CAPTION, String.class, "");
-        ds1.addItem("Item 1");
-        ds1.addItem("Item 2");
-        ds1.addItem("Item 3");
-        ds1.addItem("Item 4");
+        ds1 = DataSource.create("Item 1", "Item 2", "Item 3", "Item 4");
 
-        ds2 = new IndexedContainer();
-        ds2.addContainerProperty(CAPTION, String.class, "");
-        ds2.addItem("Item 3");
+        ds2 = DataSource.create("Item 3");
 
     }
 
index f6fd24f2a492f05420306c4944e7c91d7b5f93da..0a29669e1b8060415aab55c6902ddfab5e67eb68 100644 (file)
@@ -1,10 +1,8 @@
 package com.vaadin.tests.components.combobox;
 
-import com.vaadin.server.Resource;
 import com.vaadin.server.ThemeResource;
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxItemIcon extends TestBase {
 
@@ -21,33 +19,19 @@ public class ComboBoxItemIcon extends TestBase {
     @Override
     protected void setup() {
         {
-            ComboBox cb = new ComboBox();
-            cb.addContainerProperty("icon", Resource.class, null);
-            cb.setItemIconPropertyId("icon");
-
-            Item item = cb.addItem("FI");
-            item.getItemProperty("icon").setValue(
-                    new ThemeResource("../tests-tickets/icons/fi.gif"));
-            item = cb.addItem("SE");
-            item.getItemProperty("icon").setValue(
-                    new ThemeResource("../tests-tickets/icons/se.gif"));
+            ComboBox<String> cb = new ComboBox<>();
+            cb.setItems("FI", "SE");
+            cb.setItemIconProvider(item -> new ThemeResource(
+                    "../tests-tickets/icons/" + item.toLowerCase() + ".gif"));
 
             addComponent(cb);
         }
         {
-            ComboBox cb = new ComboBox();
-            cb.addContainerProperty("icon", Resource.class, null);
-            cb.setItemIconPropertyId("icon");
-
-            Item item = cb.addItem("Finland");
-            item.getItemProperty("icon").setValue(
-                    new ThemeResource("../tests-tickets/icons/fi.gif"));
-            item = cb.addItem("Australia");
-            item.getItemProperty("icon").setValue(
-                    new ThemeResource("../tests-tickets/icons/au.gif"));
-            item = cb.addItem("Hungary");
-            item.getItemProperty("icon").setValue(
-                    new ThemeResource("../tests-tickets/icons/hu.gif"));
+            ComboBox<String> cb = new ComboBox<>();
+            cb.setItems("Finland", "Australia", "Hungary");
+            cb.setItemIconProvider(
+                    item -> new ThemeResource("../tests-tickets/icons/"
+                            + item.substring(0, 2).toLowerCase() + ".gif"));
 
             cb.setValue("Hungary");
             addComponent(cb);
index 97d03e3a6fd8731debcea60a99318f6ceeca252d..a2fb93def961af0aaf528fab972a33bb04ff80dc 100644 (file)
@@ -2,11 +2,10 @@ package com.vaadin.tests.components.combobox;
 
 import java.util.Date;
 
-import com.vaadin.server.Resource;
 import com.vaadin.server.ThemeResource;
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxLargeIcons extends TestBase {
 
@@ -22,22 +21,15 @@ public class ComboBoxLargeIcons extends TestBase {
 
     @Override
     protected void setup() {
-        ComboBox cb = new ComboBox();
-        cb.addContainerProperty("icon", Resource.class, null);
-        cb.setItemIconPropertyId("icon");
+        ComboBox<String> cb = new ComboBox<String>(null,
+                DataSource.create("folder-add", "folder-delete", "arrow-down",
+                        "arrow-left", "arrow-right", "arrow-up", "document-add",
+                        "document-delete", "document-doc", "document-edit",
+                        "document-image", "document-pdf", "document-ppt",
+                        "document-txt", "document-web", "document"));
         getLayout().addComponent(cb);
-        cb.setNullSelectionAllowed(false);
-        String[] icons = new String[] { "folder-add", "folder-delete",
-                "arrow-down", "arrow-left", "arrow-right", "arrow-up",
-                "document-add", "document-delete", "document-doc",
-                "document-edit", "document-image", "document-pdf",
-                "document-ppt", "document-txt", "document-web", "document" };
-        for (String icon : icons) {
-            Item item = cb.addItem(icon);
-            item.getItemProperty("icon")
-                    .setValue(new ThemeResource("../runo/icons/32/" + icon
-                            + ".png?" + new Date().getTime()));
-        }
-
+        // FIXME cb.setNullSelectionAllowed(false);
+        cb.setItemIconProvider(icon -> new ThemeResource(
+                "../runo/icons/32/" + icon + ".png?" + new Date().getTime()));
     }
 }
index 812513bcaabd2c846d33fb466554be5fc743d82b..d5602be096cc698d19b750e7cf0c6602b3866d74 100644 (file)
  */
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.data.Property;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxMouseSelectEnter extends AbstractTestUI {
-    protected ComboBox comboBox;
+    protected ComboBox<String> comboBox;
 
     @Override
     protected void setup(VaadinRequest request) {
-        comboBox = new ComboBox();
+        List<String> items = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            items.add("a" + i);
+        }
+        comboBox = new ComboBox<>(null, items);
         final Label label = new Label();
         label.setId("value");
 
         comboBox.setTextInputAllowed(true);
-        comboBox.setNullSelectionAllowed(true);
-        comboBox.setNullSelectionItemId(null);
-
-        for (int i = 0; i < 10; i++) {
-            comboBox.addItem("a" + i);
-        }
+        comboBox.setEmptySelectionAllowed(true);
 
-        comboBox.addValueChangeListener(new Property.ValueChangeListener() {
-            @Override
-            public void valueChange(Property.ValueChangeEvent event) {
-                Object value = event.getProperty().getValue();
-                if (value != null) {
-                    label.setValue(value.toString());
-                } else {
-                    label.setValue("null");
-                }
-            }
-        });
+        comboBox.addValueChangeListener(
+                event -> label.setValue(String.valueOf(event.getValue())));
 
         addComponents(comboBox);
         addComponent(label);
index d872365c58374e87ca6e0d798c071850ef79d004..d99e1ef68170e812fb54adf8ffae59b9348b7b1e 100644 (file)
  */
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 /**
  * Tests mousewheel handling in ComboBox.
@@ -36,12 +39,12 @@ public class ComboBoxMousewheel extends AbstractTestUI {
     }
 
     private ComboBox createComboBox(String caption) {
-        ComboBox cb = new ComboBox(caption);
-        cb.setId(caption);
-        cb.setImmediate(true);
+        List<String> data = new ArrayList<>();
         for (int i = 1; i < 100; i++) {
-            cb.addItem("Item " + i);
+            data.add("Item " + i);
         }
+        ComboBox<String> cb = new ComboBox<>(caption, data);
+        cb.setId(caption);
         return cb;
     }
 
index 2a1889e7d970404ddebd5f7a2f1e976e79af6a69..e823c32e1d2bb5dbdec8f5fcc585001bf8656e4a 100644 (file)
@@ -1,8 +1,10 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.shared.ui.combobox.FilteringMode;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxNavigation extends TestBase {
 
@@ -18,12 +20,12 @@ public class ComboBoxNavigation extends TestBase {
 
     @Override
     protected void setup() {
-        ComboBox cb = new ComboBox();
+        List<String> items = new ArrayList<>();
         for (int i = 1; i < 100; i++) {
-            cb.addItem("Item " + i);
+            items.add("Item " + i);
         }
+        ComboBox cb = new ComboBox(null, items);
 
-        cb.setFilteringMode(FilteringMode.CONTAINS);
         addComponent(cb);
 
     }
index 9910c764eadc41a5af95a3e006742b7f23ac2cfd..adfb1204090fe6330d2c11b58af62bcc61160fff 100644 (file)
@@ -3,11 +3,9 @@ package com.vaadin.tests.components.combobox;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
 import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.FormLayout;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.data.Property;
-import com.vaadin.v7.ui.ComboBox;
 
 /**
  * The Application's "main" class
@@ -23,21 +21,14 @@ public class ComboBoxParentDisable extends AbstractTestUIWithLog {
 
         final FormLayout formLayout = new FormLayout();
 
-        final ComboBox combo = new ComboBox("Item:");
-        combo.addItem("Item 1");
-        combo.addItem("Item 2");
-        combo.addItem("Item 3");
-        combo.addItem("Item 4");
-        combo.addValueChangeListener(new MyValueChangeListener());
+        final ComboBox<String> combo = new ComboBox<>("Item:");
+        combo.setItems("Item 1", "Item 2", "Item 3", "Item 4");
+        combo.addValueChangeListener(
+                event -> log.log("you made a selection change"));
         combo.setImmediate(true);
 
         Button btn1 = new Button("Click me");
-        btn1.addClickListener(new Button.ClickListener() {
-            @Override
-            public void buttonClick(ClickEvent event) {
-                log.log("you clicked me");
-            }
-        });
+        btn1.addClickListener(event -> log.log("you clicked me"));
 
         formLayout.addComponent(combo);
         formLayout.addComponent(btn1);
@@ -45,31 +36,14 @@ public class ComboBoxParentDisable extends AbstractTestUIWithLog {
         layout.addComponent(formLayout);
 
         Button btn = new Button("Enable/Disable combobox",
-                new Button.ClickListener() {
-                    @Override
-                    public void buttonClick(ClickEvent event) {
-                        combo.setEnabled(!combo.isEnabled());
-                    }
-                });
+                event -> combo.setEnabled(!combo.isEnabled()));
         layout.addComponent(btn);
-        btn = new Button("Enable/Disable parent", new Button.ClickListener() {
-            @Override
-            public void buttonClick(ClickEvent event) {
-                formLayout.setEnabled(!formLayout.isEnabled());
-            }
-        });
+        btn = new Button("Enable/Disable parent",
+                event -> formLayout.setEnabled(!formLayout.isEnabled()));
         layout.addComponent(btn);
 
     }
 
-    private class MyValueChangeListener
-            implements Property.ValueChangeListener {
-        @Override
-        public void valueChange(Property.ValueChangeEvent event) {
-            log.log("you made a selection change");
-        }
-    }
-
     @Override
     protected String getTestDescription() {
         return "Test for ensuring that disabling a parent properly disables the combobox";
index 1c9f00fe3993c0569c61503eb2017e46c862f2eb..98b4c8025f7a699b99cf8e7ff27aeed1572d34fd 100644 (file)
  */
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxPopupWhenBodyScrolls extends AbstractTestUI {
 
@@ -28,10 +31,11 @@ public class ComboBoxPopupWhenBodyScrolls extends AbstractTestUI {
                 .add("body.v-generated-body { overflow: auto;height:auto;}");
         getPage().getStyles().add(
                 "body.v-generated-body .v-ui.v-scrollable{ overflow: visible;height:auto !important;}");
-        ComboBox cb = new ComboBox();
+        List<String> data = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
-            cb.addItem("Item " + i);
+            data.add("Item " + i);
         }
+        ComboBox<String> cb = new ComboBox<>(null, data);
 
         Label spacer = new Label("foo");
         spacer.setHeight("2000px");
index 3bf724bad4e22e04fdcddc4ca803e37d22994fbb..4a5eec6e391a6ed7f04bd864540866c63e76421b 100644 (file)
@@ -1,12 +1,11 @@
 package com.vaadin.tests.components.combobox;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import com.vaadin.tests.components.ComponentTestCase;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Notification;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxScrollingToPageDisabled
         extends ComponentTestCase<ComboBox> {
@@ -20,42 +19,26 @@ public class ComboBoxScrollingToPageDisabled
 
     @Override
     protected void initializeComponents() {
-        ComboBox s = createSelect(null);
+        ComboBox<String> s = createSelect(null);
         s.setScrollToSelectedItem(false);
         populate(s, 100);
-        Object selection = new ArrayList<Object>(s.getItemIds()).get(50);
-        s.setValue(selection);
+        s.setValue("Item 50");
         addTestComponent(s);
     }
 
     private void populate(ComboBox s, int nr) {
+        List<String> items = new ArrayList<>();
         for (int i = 0; i < nr; i++) {
-            addItem(s, "Item " + i);
+            items.add("Item " + i);
         }
+        s.setItems(items);
     }
 
-    @SuppressWarnings("unchecked")
-    private void addItem(ComboBox s, String string) {
-        Object id = s.addItem();
-        s.getItem(id).getItemProperty(CAPTION).setValue(string);
-
-    }
-
-    private ComboBox createSelect(String caption) {
-        final ComboBox cb = new ComboBox();
-        cb.setImmediate(true);
-        cb.addContainerProperty(CAPTION, String.class, "");
-        cb.setItemCaptionPropertyId(CAPTION);
+    private ComboBox<String> createSelect(String caption) {
+        final ComboBox<String> cb = new ComboBox<>();
         cb.setCaption(caption);
-        cb.addValueChangeListener(new ValueChangeListener() {
-
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                Notification.show("Value now:" + cb.getValue() + " "
-                        + cb.getItemCaption(cb.getValue()));
-
-            }
-        });
+        cb.addValueChangeListener(event -> Notification
+                .show("Value now:" + cb.getValue() + " " + cb.getValue()));
         return cb;
     }
 
index 58c0a3efc808069b763bcd399297c3cb301ceef2..823c7c5abd0bac3ea6efda353f873034be1653f5 100644 (file)
  */
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.AbstractLayout;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.ui.ComboBox;
 
 /**
  * Test UI verifying navigating in combobox via arrow keys.
@@ -61,12 +64,14 @@ public class ComboBoxScrollingWithArrows extends AbstractTestUI {
     }
 
     private void addComboBox(AbstractLayout layout) {
-        ComboBox box = new ComboBox();
+        ComboBox<String> box = new ComboBox<>();
+        List<String> items = new ArrayList<>();
         for (int i = 0; i < 100; i++) {
-            box.addItem("item " + i);
+            items.add("item " + i);
         }
+        box.setItems(items);
         box.setPageLength(10);
-        box.setNullSelectionAllowed(false);
+        box.setEmptySelectionAllowed(false);
         layout.addComponent(box);
     }
 }
index e9a46cd29785cddb807fe1fbfeb4c0a8231f5d7b..f5c2e62940769c568857366c990c08d877a360da 100644 (file)
@@ -1,41 +1,38 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.data.Property;
-import com.vaadin.v7.ui.ComboBox;
-import com.vaadin.v7.ui.TextField;
+import com.vaadin.ui.TextField;
 
 public class ComboBoxSelecting extends AbstractTestUI {
-    protected ComboBox comboBox;
+    protected ComboBox<String> comboBox;
+    protected List<String> items = new ArrayList<>();
 
     @Override
     protected void setup(VaadinRequest request) {
-        comboBox = new ComboBox();
-        final Label label = new Label();
-        label.setId("value");
-
-        comboBox.setTextInputAllowed(true);
-        comboBox.setNullSelectionAllowed(true);
-        comboBox.setNullSelectionItemId(null);
-
         for (char c = 'a'; c <= 'z'; c++) {
             for (int i = 0; i < 100; i++) {
-                comboBox.addItem("" + c + i);
+                items.add("" + c + i);
             }
         }
+        comboBox = new ComboBox<>(null, items);
+        final Label label = new Label();
+        label.setId("value");
 
-        comboBox.addValueChangeListener(new Property.ValueChangeListener() {
-            @Override
-            public void valueChange(Property.ValueChangeEvent event) {
-                Object value = event.getProperty().getValue();
-                if (value != null) {
-                    label.setValue(value.toString());
-                } else {
-                    label.setValue("null");
-                }
-
+        comboBox.setTextInputAllowed(true);
+        comboBox.setEmptySelectionAllowed(true);
+
+        comboBox.addValueChangeListener(event -> {
+            String value = event.getValue();
+            if (value != null) {
+                label.setValue(value);
+            } else {
+                label.setValue("null");
             }
         });
 
index ef07726d1787f6cde3e5240bd094d090e47aaca4..cbd3c4ebcf1d42e12fb75e9774e8b6e2bcfa760a 100644 (file)
 package com.vaadin.tests.components.combobox;
 
 import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.data.Query;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.data.Property;
 
 public class ComboBoxSelectingWithNewItemsAllowed extends ComboBoxSelecting {
 
     @Override
     protected void setup(VaadinRequest request) {
         super.setup(request);
-        comboBox.setNewItemsAllowed(true);
-
-        final Label label = new Label(
-                String.valueOf(comboBox.getItemIds().size()));
+        final Label label = new Label(String.valueOf(items.size()));
         label.setCaption("Item count:");
         label.setId("count");
-        comboBox.addValueChangeListener(new Property.ValueChangeListener() {
 
-            @Override
-            public void valueChange(Property.ValueChangeEvent event) {
-                label.setValue(String.valueOf(comboBox.getItemIds().size()));
-            }
+        comboBox.setNewItemHandler(text -> {
+            items.add(text);
+            comboBox.setItems(items);
+            comboBox.select(text);
+            label.setValue(String.valueOf(items.size()));
         });
+
+        comboBox.addValueChangeListener(event -> label.setValue(
+                String.valueOf(comboBox.getDataSource().size(new Query()))));
         addComponent(label);
     }
 
index 9a87dcda01412227f98d4b305d69dd5a789273bd..20cfea22ae3cc0167093b3fc817356eed61083ab 100644 (file)
@@ -5,9 +5,9 @@ import java.util.Arrays;
 import com.vaadin.event.FieldEvents;
 import com.vaadin.event.FieldEvents.FocusEvent;
 import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxSuggestionOnDetach extends TestBase {
 
@@ -20,7 +20,7 @@ public class ComboBoxSuggestionOnDetach extends TestBase {
         layout.setSizeUndefined();
         popup.setContent(layout);
 
-        ComboBox comboBox = new ComboBox("Combo box",
+        ComboBox<String> comboBox = new ComboBox<>("Combo box",
                 Arrays.asList("Option 1", "Option 2", "Option 3"));
         comboBox.addFocusListener(new FieldEvents.FocusListener() {
             @Override
index c25d2b43fac9b3cf97981ff157b9d752d899f958..8e6d4ec83a42a5680ee2fea937330f1174bdcfe3 100644 (file)
@@ -20,8 +20,7 @@ import java.util.List;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.shared.ui.combobox.FilteringMode;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxSuggestionPageLength extends AbstractTestUI {
 
@@ -30,14 +29,12 @@ public class ComboBoxSuggestionPageLength extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox cb = new ComboBox("Page length 0", items);
+        ComboBox<String> cb = new ComboBox<>("Page length 0", items);
         cb.setPageLength(0);
-        cb.setFilteringMode(FilteringMode.CONTAINS);
         addComponent(cb);
 
-        cb = new ComboBox("Page length 2", items);
+        cb = new ComboBox<>("Page length 2", items);
         cb.setPageLength(2);
-        cb.setFilteringMode(FilteringMode.CONTAINS);
         addComponent(cb);
     }
 
index 088cf5597e627546eb4723666d7ccd0089cbca33..19c264717a2dcbe0fc6570c4d2206f5e95fa0ea0 100644 (file)
@@ -2,16 +2,14 @@ package com.vaadin.tests.components.combobox;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxSuggestionPopupClose extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        final ComboBox select = new ComboBox("ComboBox");
-        select.addItem("one");
-        select.addItem("two");
-        select.addItem("three");
+        final ComboBox<String> select = new ComboBox<>("ComboBox");
+        select.setItems("one", "two", "three");
         addComponent(select);
     }
 
index ccc589ef31dd718da96338fc9160f13dacc71ea4..4a5fef4a22af11b6525b0873b26b8da36800d774 100644 (file)
@@ -5,7 +5,7 @@ import java.util.List;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxSuggestionPopupWidth extends AbstractTestUI {
 
@@ -16,7 +16,7 @@ public class ComboBoxSuggestionPopupWidth extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox cb = new ComboBox(
+        ComboBox<String> cb = new ComboBox<>(
                 "200px wide ComboBox with 100% wide suggestion popup", items);
         cb.setPopupWidth("100%");
         cb.setWidth("200px");
index 29326bce82cac21ae38766126938afd2dd164212..d1a619d9f331e9fd0e6e89338387ba1bb9f75f7e 100644 (file)
@@ -5,7 +5,7 @@ import java.util.List;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxSuggestionPopupWidthLegacy extends AbstractTestUI {
 
@@ -16,7 +16,7 @@ public class ComboBoxSuggestionPopupWidthLegacy extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox legacy = new ComboBox(
+        ComboBox<String> legacy = new ComboBox<>(
                 "200px wide ComboBox with legacy mode suggestion popup setPopupWidth(null)",
                 items);
         legacy.addStyleName("legacy");
index 8b1d89d3392452d4d331c6360cb0d9d0f1a7c6c2..c860018f0a46a29166d2e423593843aef4c4334d 100644 (file)
@@ -5,7 +5,7 @@ import java.util.List;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxSuggestionPopupWidthPercentage extends AbstractTestUI {
 
@@ -16,7 +16,7 @@ public class ComboBoxSuggestionPopupWidthPercentage extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox percentage = new ComboBox(
+        ComboBox<String> percentage = new ComboBox<>(
                 "200px wide ComboBox with 200% wide suggestion popup", items);
         percentage.addStyleName("percentage");
         percentage.setWidth("200px");
index fa8fd118aee14bd64fbd4a32d6d88f1b0ec44fbe..2f749e10511db2161b14fda9ed961ef3e55f3635 100644 (file)
@@ -5,7 +5,7 @@ import java.util.List;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxSuggestionPopupWidthPixels extends AbstractTestUI {
 
@@ -16,7 +16,7 @@ public class ComboBoxSuggestionPopupWidthPixels extends AbstractTestUI {
 
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox pixels = new ComboBox(
+        ComboBox<String> pixels = new ComboBox<>(
                 "200px wide ComboBox with 300px wide suggestion popup", items);
         pixels.addStyleName("pixels");
         pixels.setWidth("200px");
index f4805789e2cf2fb3d96cebae900012d5f4df60be..c5d72528afa85a2bcc70fe1218f10ef51f2dd317 100644 (file)
@@ -1,25 +1,22 @@
 package com.vaadin.tests.components.combobox;
 
-import com.vaadin.server.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.ThemeResource;
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboBoxUndefinedWidthAndIcon extends TestBase {
     @Override
     protected void setup() {
-        ComboBox cb = new ComboBox();
-        cb.addContainerProperty("caption", String.class, null);
-        cb.addContainerProperty("icon", Resource.class, null);
+        List<String> data = new ArrayList<>();
         for (int i = 1; i < 200 + 1; i++) {
-            Item item = cb.addItem(i);
-            item.getItemProperty("caption").setValue("Item " + i);
-            item.getItemProperty("icon")
-                    .setValue(new ThemeResource("../runo/icons/16/users.png"));
+            data.add("Item " + i);
         }
-        cb.setItemIconPropertyId("icon");
-        cb.setItemCaptionPropertyId("caption");
+        ComboBox<String> cb = new ComboBox<>(null, data);
+        cb.setItemIconProvider(
+                item -> new ThemeResource("../runo/icons/16/users.png"));
 
         addComponent(cb);
     }
index 7b32b5e570405002e51c0cc6a97a1a5f863e949f..06bbe7a2624a688f9d718447f6245320164f82c5 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
  */
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.annotations.Theme;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 @Theme("valo")
 public class ComboBoxValoDoubleClick extends AbstractTestUI {
@@ -28,10 +31,12 @@ public class ComboBoxValoDoubleClick extends AbstractTestUI {
     // bug. Manually a double click is just about the right timing.
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox cb = new ComboBox("Double-click Me");
+        ComboBox<String> cb = new ComboBox<>("Double-click Me");
+        List<String> items = new ArrayList<String>();
         for (int i = 0; i < 100; i++) {
-            cb.addItem("Item-" + i);
+            items.add("Item-" + i);
         }
+        cb.setItems(items);
         addComponent(cb);
     }
 
index a416c2e9c3ed4f81935f739f4739e1e35dc581ca..cf5833015c99fedaaf143eae1d153d9afb03a3e2 100644 (file)
@@ -1,9 +1,11 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboBoxValueUpdate extends TestBase {
 
@@ -19,23 +21,17 @@ public class ComboBoxValueUpdate extends TestBase {
 
     @Override
     protected void setup() {
-        ComboBox select = new ComboBox("");
-        select.setImmediate(true);
+        List<String> items = new ArrayList<>();
         for (int i = 0; i < 100; i++) {
-            select.addItem("item " + i);
+            items.add("item " + i);
         }
+        ComboBox<String> select = new ComboBox<>("", items);
 
         final Label value = new Label();
 
-        select.addListener(new ComboBox.ValueChangeListener() {
-
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                System.err
-                        .println("Selected " + event.getProperty().getValue());
-                value.setValue("Selected " + event.getProperty().getValue());
-
-            }
+        select.addValueChangeListener(event -> {
+            System.err.println("Selected " + event.getValue());
+            value.setValue("Selected " + event.getValue());
         });
 
         getLayout().addComponent(select);
index 17a0405690c86862e04b4a003ad53a40b4f7564b..88986fb69ad913917b13bf66627140a244350f4f 100644 (file)
@@ -3,15 +3,12 @@ package com.vaadin.tests.components.combobox;
 import java.util.ArrayList;
 import java.util.List;
 
-import com.vaadin.event.FieldEvents;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.FocusEvent;
 import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.TextField;
 import com.vaadin.v7.data.util.ObjectProperty;
 import com.vaadin.v7.shared.ui.label.ContentMode;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.Label;
-import com.vaadin.v7.ui.TextField;
 
 public class ComboFocusBlurEvents extends TestBase {
 
@@ -25,34 +22,26 @@ public class ComboFocusBlurEvents extends TestBase {
             list.add("Item " + i);
         }
 
-        ComboBox cb = new ComboBox("Combobox", list);
-        cb.setImmediate(true);
-        cb.setInputPrompt("Enter text");
+        ComboBox<String> cb = new ComboBox<>("Combobox", list);
+        cb.setPlaceholder("Enter text");
         cb.setDescription("Some Combobox");
         addComponent(cb);
 
         final ObjectProperty<String> log = new ObjectProperty<>("");
 
-        cb.addFocusListener(new FieldEvents.FocusListener() {
-            @Override
-            public void focus(FocusEvent event) {
-                log.setValue(log.getValue().toString() + "<br>" + counter
-                        + ": Focus event!");
-                counter++;
-            }
+        cb.addFocusListener(event -> {
+            log.setValue(log.getValue().toString() + "<br>" + counter
+                    + ": Focus event!");
+            counter++;
         });
 
-        cb.addBlurListener(new FieldEvents.BlurListener() {
-            @Override
-            public void blur(BlurEvent event) {
-                log.setValue(log.getValue().toString() + "<br>" + counter
-                        + ": Blur event!");
-                counter++;
-            }
+        cb.addBlurListener(event -> {
+            log.setValue(log.getValue().toString() + "<br>" + counter
+                    + ": Blur event!");
+            counter++;
         });
 
         TextField field = new TextField("Some textfield");
-        field.setImmediate(true);
         addComponent(field);
 
         Label output = new Label(log);
index c10e1ece643c6707ca357c5b24ef8dfb66530fa0..d591651fcda38c7ff761887cb2bf9d92875d604f 100644 (file)
@@ -1,11 +1,12 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
 
 @SuppressWarnings("serial")
 public class ComboSelectedValueBeyondTheFirstDropdownPage
@@ -17,7 +18,7 @@ public class ComboSelectedValueBeyondTheFirstDropdownPage
     @Override
     protected void setup(VaadinRequest request) {
         Label value = getLabel();
-        ComboBox combobox = getComboBox(value);
+        ComboBox<String> combobox = getComboBox(value);
 
         addComponent(combobox);
         addComponent(value);
@@ -30,23 +31,19 @@ public class ComboSelectedValueBeyondTheFirstDropdownPage
         return value;
     }
 
-    private ComboBox getComboBox(final Label value) {
-        final ComboBox combobox = new ComboBox("MyCaption");
+    private ComboBox<String> getComboBox(final Label value) {
+        final ComboBox<String> combobox = new ComboBox<>("MyCaption");
         combobox.setDescription(
                 "ComboBox with more than 10 elements in it's dropdown list.");
 
-        combobox.setImmediate(true);
-
+        List<String> items = new ArrayList<>();
         for (int i = 1; i <= ITEM_COUNT; i++) {
-            combobox.addItem(String.format(ITEM_NAME_TEMPLATE, i));
+            items.add(String.format(ITEM_NAME_TEMPLATE, i));
         }
+        combobox.setItems(items);
 
-        combobox.addValueChangeListener(new ValueChangeListener() {
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                value.setValue(String.valueOf(event.getProperty().getValue()));
-            }
-        });
+        combobox.addValueChangeListener(
+                event -> value.setValue(String.valueOf(event.getValue())));
 
         return combobox;
     }
index 4c6e4663fcf964706582d4b842dbd6ae159a05f8..40226fcb91f9c6db5c2b1f80b82edf0eccb3f209 100644 (file)
@@ -3,9 +3,9 @@ package com.vaadin.tests.components.combobox;
 import java.util.Arrays;
 
 import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.PopupView;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.TextArea;
 
 public class ComboboxInPopupViewWithItems extends TestBase {
@@ -29,7 +29,7 @@ public class ComboboxInPopupViewWithItems extends TestBase {
 
     class PopupContent implements PopupView.Content {
 
-        private final ComboBox cb = new ComboBox(null,
+        private final ComboBox<String> cb = new ComboBox<>(null,
                 Arrays.asList("Item 1", "Item 2", "Item 3"));
 
         @Override
index 83f94aac8b5714817c7a243be60396e1f24f9a33..b1497576352f2555a8913e5b82fe8fc44514de3f 100644 (file)
  */
 package com.vaadin.tests.components.combobox;
 
-import java.util.ArrayList;
-
 import com.vaadin.server.Page;
 import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.MenuBar;
 import com.vaadin.ui.MenuBar.MenuItem;
 import com.vaadin.ui.Notification;
 import com.vaadin.ui.Notification.Type;
-import com.vaadin.v7.ui.ComboBox;
 
 /**
  * Test UI for combobox popup which should be closed on any click outside it.
@@ -38,11 +37,8 @@ public class ComboboxMenuBarAutoopen extends AbstractTestUI {
     protected void setup(VaadinRequest request) {
         HorizontalLayout layout = new HorizontalLayout();
         layout.setSpacing(true);
-        ArrayList<String> options = new ArrayList<>();
-        options.add("1");
-        options.add("2");
-        options.add("3");
-        ComboBox combo = new ComboBox(null, options);
+        ComboBox<String> combo = new ComboBox<>(null,
+                DataSource.create("1", "2", "3"));
         layout.addComponent(combo);
 
         MenuBar menubar = getMenubar();
index c6753f0b01604ccdbdce0138b0cba997236a882c..24ecc91e01e34f350566e2f27c394efb0d2521c2 100644 (file)
@@ -1,10 +1,13 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.annotations.Theme;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.v7.ui.ComboBox;
 
 @Theme("valo")
 public class ComboboxPopupScrolling extends AbstractTestUIWithLog {
@@ -12,25 +15,24 @@ public class ComboboxPopupScrolling extends AbstractTestUIWithLog {
     protected void setup(VaadinRequest request) {
         ComboBox combobox = new ComboBox("100px wide combobox");
         combobox.setWidth("100px");
-        combobox.addItem("AMERICAN SAMOA");
-        combobox.addItem("ANTIGUA AND BARBUDA");
+        combobox.setItems("AMERICAN SAMOA", "ANTIGUA AND BARBUDA");
 
         ComboBox combobox2 = new ComboBox("250px wide combobox");
         combobox2.setWidth("250px");
-        combobox2.addItem("AMERICAN SAMOA");
-        combobox2.addItem("ANTIGUA AND BARBUDA");
+        combobox2.setItems("AMERICAN SAMOA", "ANTIGUA AND BARBUDA");
 
         ComboBox combobox3 = new ComboBox("Undefined wide combobox");
         combobox3.setWidth(null);
-        combobox3.addItem("AMERICAN SAMOA");
-        combobox3.addItem("ANTIGUA AND BARBUDA");
+        combobox3.setItems("AMERICAN SAMOA", "ANTIGUA AND BARBUDA");
 
         ComboBox combobox4 = new ComboBox("Another 100px wide combobox");
         combobox4.setWidth("100px");
+        List<String> items = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
-            combobox4.addItem("AMERICAN SAMOA " + i);
-            combobox4.addItem("ANTIGUA AND BARBUDA " + i);
+            items.add("AMERICAN SAMOA " + i);
+            items.add("ANTIGUA AND BARBUDA " + i);
         }
+        combobox4.setItems(items);
 
         HorizontalLayout hl = new HorizontalLayout(combobox, combobox2,
                 combobox3, combobox4);
index f5de8d508d0d2c72e1176d19f76c8c6f99512d15..98ddb6be8270a6daf345368daa3e90ea651d32ea 100644 (file)
@@ -1,33 +1,22 @@
 package com.vaadin.tests.components.combobox;
 
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class ComboboxPrimaryStyleNames extends TestBase {
 
     @Override
     protected void setup() {
-        final ComboBox box = new ComboBox();
+        final ComboBox<String> box = new ComboBox(null,
+                DataSource.create("Value 1", "Value 2", "Value 3", "Value 4"));
         box.setImmediate(true);
-        box.addContainerProperty("caption", String.class, "");
-        box.setItemCaptionPropertyId("caption");
         box.setPrimaryStyleName("my-combobox");
 
-        addItem(box, "Value 1");
-        addItem(box, "Value 2");
-        addItem(box, "Value 3");
-        addItem(box, "Value 4");
-
         addComponent(box);
-        addComponent(
-                new Button("Set primary style", new Button.ClickListener() {
-                    @Override
-                    public void buttonClick(ClickEvent event) {
-                        box.setPrimaryStyleName("my-second-combobox");
-                    }
-                }));
+        addComponent(new Button("Set primary style",
+                event -> box.setPrimaryStyleName("my-second-combobox")));
 
     }
 
@@ -41,9 +30,4 @@ public class ComboboxPrimaryStyleNames extends TestBase {
         return 9901;
     }
 
-    private void addItem(ComboBox s, String string) {
-        Object id = s.addItem();
-        s.getItem(id).getItemProperty("caption").setValue(string);
-    }
-
 }
index d223ed7a2888c779183abf8e71bb5d33885eae1b..3faef53ed77fa42945808888ac612186e2f582bc 100644 (file)
 package com.vaadin.tests.components.combobox;
 
 import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.data.DataSource;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
 import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 /**
  * Test UI for adding a stylename to a combobox with an undefined width.
@@ -30,20 +30,12 @@ public class ComboboxStyleChangeWidth extends AbstractTestUIWithLog {
 
     @Override
     protected void setup(VaadinRequest request) {
-        final ComboBox cbFoo = new ComboBox();
-        cbFoo.setImmediate(true);
+        final ComboBox<String> cbFoo = new ComboBox<>(null, DataSource.create(
+                "A really long string that causes an inline width to be set"));
         cbFoo.setSizeUndefined();
-        cbFoo.addItem(
-                "A really long string that causes an inline width to be set");
 
         Button btn = new Button("Click to break CB",
-                new Button.ClickListener() {
-                    @Override
-                    public void buttonClick(ClickEvent event) {
-                        cbFoo.addStyleName("foofoo");
-
-                    }
-                });
+                event -> cbFoo.addStyleName("foofoo"));
 
         addComponent(cbFoo);
         addComponent(btn);
index 9ebc37a4bf8d0a13fd65c9172135f743de3c5980..4cc8ca7919708c9302171e0e5fda05670f8132b3 100644 (file)
@@ -1,17 +1,28 @@
 package com.vaadin.tests.components.combobox;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.LinkedHashMap;
 import java.util.List;
 
 import com.vaadin.server.ThemeResource;
 import com.vaadin.tests.components.ComponentTestCase;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Component;
-import com.vaadin.v7.ui.ComboBox;
 
 public class Comboboxes extends ComponentTestCase<ComboBox> {
 
-    private static final Object CAPTION = "caption";
+    private static class StringBean {
+        private String value;
+
+        public StringBean(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
 
     @Override
     protected Class<ComboBox> getTestClass() {
@@ -20,69 +31,67 @@ public class Comboboxes extends ComponentTestCase<ComboBox> {
 
     @Override
     protected void initializeComponents() {
-        ComboBox s;
-
-        s = createSelect(null);
-        s.setWidth(null);
-        addTestComponent(s);
-
-        s = createSelect("Undefined wide, empty select");
-        s.setWidth(null);
-        addTestComponent(s);
-
-        s = createSelect("Undefined wide select with 5 items");
-        s.setWidth(null);
-        addItem(s, "The first item");
-        addItem(s, "The second item");
-        addItem(s, "The third item");
-        addItem(s, "The fourth item");
-        addItem(s, "The fifth item");
-        addTestComponent(s);
-
-        s = createSelect("Undefined wide select with 50 items");
-        s.setWidth(null);
-        populate(s, 50);
-        addTestComponent(s);
-
-        s = createSelect(null);
-        s.setWidth("100px");
-        addTestComponent(s);
-
-        s = createSelect("100px wide, empty select");
-        s.setWidth("100px");
-        addTestComponent(s);
-
-        s = createSelect("150px wide select with 5 items");
-        s.setWidth("150px");
-        addItem(s, "The first item");
-        addItem(s, "The second item");
-        addItem(s, "The third item");
-        addItem(s, "The fourth item");
-        addItem(s, "The fifth item");
-        addTestComponent(s);
-
-        s = createSelect("200px wide select with 50 items");
-        s.setWidth("200px");
-        populate(s, 50);
-        addTestComponent(s);
-
-        s = new PageLength0ComboBox();
-        s.setImmediate(true);
-        s.addContainerProperty(CAPTION, String.class, "");
-        s.setItemCaptionPropertyId(CAPTION);
-        s.setCaption("Pagelength 0");
-        populate(s, 15);
-        addTestComponent(s);
+        ComboBox<String> s1 = createSelect(null);
+        s1.setWidth(null);
+        addTestComponent(s1);
+
+        ComboBox<String> s2 = createSelect("Undefined wide, empty select");
+        s2.setWidth(null);
+        addTestComponent(s2);
+
+        ComboBox<String> s3 = createSelect(
+                "Undefined wide select with 5 items");
+        s3.setWidth(null);
+        s3.setItems("The first item", "The second item", "The third item",
+                "The fourth item", "The fifth item");
+        addTestComponent(s3);
+
+        ComboBox<StringBean> s4 = new ComboBox<>(
+                "Undefined wide select with 50 items");
+        s4.setWidth(null);
+        populate(s4, 50);
+        s4.setItemCaptionProvider(StringBean::getValue);
+        s4.setScrollToSelectedItem(true);
+        addTestComponent(s4);
+
+        ComboBox<String> s5 = createSelect(null);
+        s5.setWidth("100px");
+        addTestComponent(s5);
+
+        ComboBox<String> s6 = createSelect("100px wide, empty select");
+        s6.setWidth("100px");
+        addTestComponent(s6);
+
+        ComboBox<String> s7 = createSelect("150px wide select with 5 items");
+        s7.setWidth("150px");
+        s7.setItems("The first item", "The second item", "The third item",
+                "The fourth item", "The fifth item");
+        addTestComponent(s7);
+
+        ComboBox<StringBean> s8 = new ComboBox<>(
+                "200px wide select with 50 items");
+        s8.setWidth("200px");
+        populate(s8, 50);
+        s8.setItemCaptionProvider(StringBean::getValue);
+        addTestComponent(s8);
+
+        ComboBox<StringBean> s9 = new PageLength0ComboBox();
+        s9.setImmediate(true);
+        s9.setCaption("Pagelength 0");
+        populate(s9, 15);
+        s9.setItemCaptionProvider(StringBean::getValue);
+        addTestComponent(s9);
     }
 
-    public class PageLength0ComboBox extends ComboBox {
+    public class PageLength0ComboBox extends ComboBox<StringBean> {
         public PageLength0ComboBox() {
             super();
             setPageLength(0);
         }
     }
 
-    private void populate(ComboBox s, int nr) {
+    private void populate(ComboBox<StringBean> s, int nr) {
+        List<StringBean> beans = new ArrayList<>();
         String text = " an item ";
 
         String caption = "";
@@ -93,25 +102,13 @@ public class Comboboxes extends ComponentTestCase<ComboBox> {
                 caption += i;
             }
 
-            addItem(s, caption);
+            beans.add(new StringBean(caption));
         }
-
+        s.setItems(beans);
     }
 
-    private void addItem(ComboBox s, String string) {
-        Object id = s.addItem();
-        s.getItem(id).getItemProperty(CAPTION).setValue(string);
-
-    }
-
-    private ComboBox createSelect(String caption) {
-        ComboBox cb = new ComboBox();
-        cb.setImmediate(true);
-        cb.addContainerProperty(CAPTION, String.class, "");
-        cb.setItemCaptionPropertyId(CAPTION);
-        cb.setCaption(caption);
-
-        return cb;
+    private ComboBox<String> createSelect(String caption) {
+        return new ComboBox<>(caption);
     }
 
     @Override
@@ -124,6 +121,7 @@ public class Comboboxes extends ComponentTestCase<ComboBox> {
         actions.add(createIconSelect());
     }
 
+    @SuppressWarnings("rawtypes")
     private Component createIconSelect() {
 
         LinkedHashMap<String, String> options = new LinkedHashMap<>();
@@ -135,15 +133,14 @@ public class Comboboxes extends ComponentTestCase<ComboBox> {
         return createSelectAction("Icon", options, "<None>",
                 new Command<ComboBox, String>() {
 
+                    @SuppressWarnings("unchecked")
                     @Override
                     public void execute(ComboBox c, String value, Object data) {
-                        for (Object id : c.getItemIds()) {
-                            if (value == null) {
-                                c.setItemIcon(id, null);
-                            } else {
-                                c.setItemIcon(id, new ThemeResource(
-                                        value + "?" + new Date().getTime()));
-                            }
+                        if (value == null) {
+                            c.setItemIconProvider(item -> null);
+                        } else {
+                            c.setItemIconProvider(item -> new ThemeResource(
+                                    value + "?" + new Date().getTime()));
                         }
                     }
                 });
diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/EscapeClosesComboboxNotWindow.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/EscapeClosesComboboxNotWindow.java
deleted file mode 100644 (file)
index 43d042c..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.vaadin.tests.components.combobox;
-
-import com.vaadin.event.ShortcutAction.KeyCode;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.FormLayout;
-import com.vaadin.ui.UI;
-import com.vaadin.ui.VerticalLayout;
-import com.vaadin.ui.Window;
-import com.vaadin.v7.ui.ComboBox;
-
-/**
- * Ticket #12163: when a combo box popup is open in a subwindow, escape should
- * only close it and not the window, also on Safari 6.
- */
-public class EscapeClosesComboboxNotWindow extends UI {
-    final Window window = new Window("Window");
-
-    @Override
-    protected void init(VaadinRequest request) {
-        final VerticalLayout layout = new VerticalLayout();
-        layout.setMargin(true);
-        setContent(layout);
-
-        Button button = new Button("Click Me");
-        button.addClickListener(new Button.ClickListener() {
-            @Override
-            public void buttonClick(ClickEvent event) {
-                final FormLayout content = new FormLayout();
-                ComboBox cb = new ComboBox();
-                cb.addItem("foo");
-                cb.addItem("bar");
-                content.addComponent(cb);
-                window.setContent(content);
-                window.setCloseShortcut(KeyCode.ESCAPE);
-                UI.getCurrent().addWindow(window);
-            }
-        });
-        layout.addComponent(button);
-    }
-
-}
index 4624d213e9a7a88014354ec98bee3f075d5befc0..4844f252cecdc50d6191b1212d25ef7c98999617 100644 (file)
@@ -20,9 +20,7 @@ import java.util.Locale;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.v7.ui.NativeSelect;
 
 public class FilteringTurkishLocale extends AbstractTestUI {
@@ -30,18 +28,14 @@ public class FilteringTurkishLocale extends AbstractTestUI {
     @Override
     protected void setup(VaadinRequest request) {
 
-        final ComboBox comboBox = new ComboBox("Box",
-                Arrays.asList("I without dot", "İ with dot"));
-        comboBox.setNullSelectionAllowed(false);
+        final ComboBox<String> comboBox = new ComboBox<>("Box",
+                Arrays.asList("I dotless", "İ dotted"));
+        comboBox.setEmptySelectionAllowed(false);
 
         NativeSelect localeSelect = new NativeSelect("Locale",
                 Arrays.asList(Locale.ENGLISH, new Locale("tr")));
-        localeSelect.addValueChangeListener(new ValueChangeListener() {
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                comboBox.setLocale((Locale) event.getProperty().getValue());
-            }
-        });
+        localeSelect.addValueChangeListener(event -> comboBox
+                .setLocale((Locale) event.getProperty().getValue()));
         localeSelect.setValue(Locale.ENGLISH);
 
         addComponents(localeSelect, comboBox);
index 513e11b1fed21385cdf8389b7d90ff07f9993605..8432605b09a7b90380efdd18f5cf3f156d0d8e04 100644 (file)
@@ -1,11 +1,11 @@
 package com.vaadin.tests.components.combobox;
 
 import com.vaadin.tests.components.AbstractTestCase;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.GridLayout;
 import com.vaadin.ui.Label;
 import com.vaadin.ui.Layout;
 import com.vaadin.ui.LegacyWindow;
-import com.vaadin.v7.ui.ComboBox;
 
 @SuppressWarnings("serial")
 public class GridLayoutComboBoxZoomOut extends AbstractTestCase {
@@ -24,20 +24,15 @@ public class GridLayoutComboBoxZoomOut extends AbstractTestCase {
         // formLayout.setWidth("100%");
         formLayout.setWidth("1000px");
 
-        ComboBox countryField = new ComboBox();
-        countryField.addItem("Finland");
-        countryField.addItem("Sweden");
-        countryField.addItem("Canada");
-        countryField.addItem("USA");
+        ComboBox<String> countryField = new ComboBox<>();
+        countryField.setItems("Finland", "Sweden", "Canada", "USA");
         countryField.setCaption("Country");
         countryField.setWidth("100%");
         formLayout.addComponent(countryField);
 
-        ComboBox statusField = new ComboBox();
-        statusField.addItem("Available");
-        statusField.addItem("On vacation");
-        statusField.addItem("Busy");
-        statusField.addItem("Left the building");
+        ComboBox<String> statusField = new ComboBox<>();
+        statusField.setItems("Available", "On vacation", "Busy",
+                "Left the building");
         statusField.setCaption("Status");
         statusField.setWidth("100%");
         formLayout.addComponent(statusField);
index 88907504f8ebba5bafd79ba642216b9fd6d0154d..6cbfc42ab86d2ffb095294d27f7742cb00c7851a 100644 (file)
@@ -1,10 +1,11 @@
 package com.vaadin.tests.components.combobox;
 
-import com.vaadin.server.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.ThemeResource;
 import com.vaadin.tests.components.TestBase;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class PopUpWidth extends TestBase {
 
@@ -16,18 +17,16 @@ public class PopUpWidth extends TestBase {
                 "Browse this (check that width does not change)"));
     }
 
-    private ComboBox createComboBox(String caption) {
-        ComboBox cb = new ComboBox(caption);
-        cb.addContainerProperty("caption", String.class, null);
-        cb.addContainerProperty("icon", Resource.class, null);
+    private ComboBox<Integer> createComboBox(String caption) {
+        ComboBox<Integer> cb = new ComboBox<>(caption);
+        List<Integer> items = new ArrayList<>();
         for (int i = 1; i < 200 + 1; i++) {
-            Item item = cb.addItem(i);
-            item.getItemProperty("caption").setValue("Item " + i);
-            item.getItemProperty("icon")
-                    .setValue(new ThemeResource("../runo/icons/16/users.png"));
+            items.add(i);
         }
-        cb.setItemIconPropertyId("icon");
-        cb.setItemCaptionPropertyId("caption");
+        cb.setItems(items);
+        cb.setItemIconProvider(
+                item -> new ThemeResource("../runo/icons/16/users.png"));
+        cb.setItemCaptionProvider(item -> "Item " + item);
         return cb;
     }
 
index 687ef412fc54dc83f25ccdd0a8669e5e88d2f840..8b6ff1487617eb75f5d0e7ba64dc3f2cc0d43700 100644 (file)
@@ -2,7 +2,7 @@ package com.vaadin.tests.components.combobox;
 
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.CheckBox;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
 
 public class WidthToggleReadOnly extends TestBase {
 
@@ -16,9 +16,9 @@ public class WidthToggleReadOnly extends TestBase {
         addComponent(createReadOnlyForComboBox(combo));
     }
 
-    private ComboBox createNewComboBoxA(String caption) {
-        ComboBox combo = new ComboBox(caption);
-        combo.addItem("first");
+    private ComboBox<String> createNewComboBoxA(String caption) {
+        ComboBox<String> combo = new ComboBox<>(caption);
+        combo.setItems("first");
         combo.setValue("first");
 
         addComponent(combo);
@@ -31,7 +31,6 @@ public class WidthToggleReadOnly extends TestBase {
         readonly.setValue(combo.isReadOnly());
         readonly.addValueChangeListener(
                 event -> combo.setReadOnly(event.getValue()));
-        readonly.setImmediate(true);
         addComponent(readonly);
         return readonly;
     }
index cbea45583364e6c6b95bdb6436ac00806d3a6784..c06c17afadd14cbcced3310e7619b86339f923ab 100644 (file)
@@ -4,10 +4,10 @@ import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.FormLayout;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.TextField;
 import com.vaadin.v7.ui.NativeSelect;
-import com.vaadin.v7.ui.TextField;
 
 public class CaptionEnableDisable extends AbstractTestUI {
 
@@ -23,7 +23,7 @@ public class CaptionEnableDisable extends AbstractTestUI {
         textField.setEnabled(false);
         layout.addComponent(textField);
 
-        final ComboBox combobox = new ComboBox("Combobox");
+        final ComboBox<String> combobox = new ComboBox<>("Combobox");
         combobox.setEnabled(false);
         layout.addComponent(combobox);
 
@@ -35,16 +35,12 @@ public class CaptionEnableDisable extends AbstractTestUI {
         checkBox.setEnabled(false);
         layout.addComponent(checkBox);
 
-        layout.addComponent(new Button("Toggle components enabled",
-                new Button.ClickListener() {
-                    @Override
-                    public void buttonClick(Button.ClickEvent event) {
-                        combobox.setEnabled(!combobox.isEnabled());
-                        textField.setEnabled(!textField.isEnabled());
-                        checkBox.setEnabled(!checkBox.isEnabled());
-                        nativeSelect.setEnabled(!nativeSelect.isEnabled());
-                    }
-                }));
+        layout.addComponent(new Button("Toggle components enabled", event -> {
+            combobox.setEnabled(!combobox.isEnabled());
+            textField.setEnabled(!textField.isEnabled());
+            checkBox.setEnabled(!checkBox.isEnabled());
+            nativeSelect.setEnabled(!nativeSelect.isEnabled());
+        }));
         return layout;
     }
 
index 7eefa585b28b7b5ad178e7b00f87bede9eb7974f..c2df9a2cbe295d7d87722dbfdf6f78e10abc6f0e 100644 (file)
@@ -1,5 +1,7 @@
 package com.vaadin.tests.components.notification;
 
+import java.util.LinkedHashMap;
+
 import com.vaadin.server.Page;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.shared.ui.ValueChangeMode;
@@ -8,13 +10,12 @@ import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Notification;
 import com.vaadin.ui.Notification.Type;
 import com.vaadin.ui.NotificationConfiguration;
 import com.vaadin.ui.TextField;
 import com.vaadin.ui.UI;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.NativeSelect;
 import com.vaadin.v7.ui.TextArea;
 
@@ -33,7 +34,7 @@ public class NotificationsWaiAria extends AbstractTestUI {
     private NativeSelect role;
 
     private TextArea tf;
-    private ComboBox type;
+    private ComboBox<Notification.Type> type;
 
     @SuppressWarnings("unchecked")
     @Override
@@ -60,28 +61,18 @@ public class NotificationsWaiAria extends AbstractTestUI {
         tf.setImmediate(false);
         tf.setRows(10);
         addComponent(tf);
-        type = new ComboBox();
-        type.setNullSelectionAllowed(false);
-        type.addContainerProperty(CAPTION, String.class, "");
-
-        type.setItemCaptionPropertyId(CAPTION);
-
-        Item item = type.addItem(Notification.Type.HUMANIZED_MESSAGE);
-        item.getItemProperty(CAPTION).setValue("Humanized");
-
-        item = type.addItem(Notification.Type.ERROR_MESSAGE);
-        item.getItemProperty(CAPTION).setValue("Error");
-
-        item = type.addItem(Notification.Type.WARNING_MESSAGE);
-        item.getItemProperty(CAPTION).setValue("Warning");
-
-        item = type.addItem(Notification.Type.TRAY_NOTIFICATION);
-        item.getItemProperty(CAPTION).setValue("Tray");
-
-        item = type.addItem(Notification.Type.ASSISTIVE_NOTIFICATION);
-        item.getItemProperty(CAPTION).setValue("Assistive");
-
-        type.setValue(type.getItemIds().iterator().next());
+        type = new ComboBox<>();
+        LinkedHashMap<Notification.Type, String> items = new LinkedHashMap<>();
+        items.put(Notification.Type.HUMANIZED_MESSAGE, "Humanized");
+        items.put(Notification.Type.ERROR_MESSAGE, "Error");
+        items.put(Notification.Type.WARNING_MESSAGE, "Warning");
+        items.put(Notification.Type.TRAY_NOTIFICATION, "Tray");
+        items.put(Notification.Type.ASSISTIVE_NOTIFICATION, "Assistive");
+
+        type.setItemCaptionProvider(item -> items.get(item));
+        type.setItems(items.keySet());
+
+        type.setValue(items.keySet().iterator().next());
         addComponent(type);
 
         Button showNotification = new Button("Show notification",
@@ -106,7 +97,7 @@ public class NotificationsWaiAria extends AbstractTestUI {
     private class SettingHandler implements ClickListener {
         @Override
         public void buttonClick(ClickEvent event) {
-            Type typeValue = (Type) type.getValue();
+            Type typeValue = type.getValue();
 
             Notification n = new Notification(tf.getValue(), typeValue);
             n.setDelayMsec(-1);
@@ -125,8 +116,7 @@ public class NotificationsWaiAria extends AbstractTestUI {
     private class DefaultHandler implements ClickListener {
         @Override
         public void buttonClick(ClickEvent event) {
-            Notification n = new Notification(tf.getValue(),
-                    (Type) type.getValue());
+            Notification n = new Notification(tf.getValue(), type.getValue());
             n.setHtmlContentAllowed(true);
             n.show(Page.getCurrent());
         }
index 58dd3b2e411b0f50ea2b4ca5efccfc10a03f974d..5a57bedcc3ac98308e5912cd97bb6c3853d4c9c1 100644 (file)
@@ -20,10 +20,10 @@ import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.ui.ComboBox;
 
 public class InsertComponentInHorizontalLayout extends AbstractTestUI {
     private VerticalLayout layout;
index 1c9047a74b01fba497b233cc8804251b55b875a9..8e002fa52f3ed38cd83216ad5f433e541a8beebd 100644 (file)
@@ -9,6 +9,7 @@ import com.vaadin.shared.ui.slider.SliderOrientation;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Alignment;
 import com.vaadin.ui.Button;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Embedded;
 import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.HorizontalSplitPanel;
@@ -16,7 +17,6 @@ import com.vaadin.ui.Label;
 import com.vaadin.ui.NativeButton;
 import com.vaadin.ui.Slider;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.NativeSelect;
 import com.vaadin.v7.ui.Table;
 
@@ -69,7 +69,7 @@ public class VaadinTunesLayout extends AbstractTestUI {
         HorizontalLayout volume = new HorizontalLayout();
         HorizontalLayout status = new HorizontalLayout();
         HorizontalLayout viewmodes = new HorizontalLayout();
-        ComboBox search = new ComboBox();
+        ComboBox<String> search = new ComboBox<>();
 
         // Add the components and align them properly
         top.addComponent(playback);
index 7754d982c2be29b810e19be02f5a0233318cdfcc..97f5251d5c739d85bcd22f7fcd0b053a2322c913 100644 (file)
@@ -18,10 +18,10 @@ package com.vaadin.tests.components.panel;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.GridLayout;
 import com.vaadin.ui.Panel;
 import com.vaadin.ui.VerticalLayout;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.TextField;
 
 public class UndefinedSizeScrollbars extends AbstractTestUI {
@@ -44,7 +44,7 @@ public class UndefinedSizeScrollbars extends AbstractTestUI {
         text2.setCaption("Text2");
         text2.setRequired(true);
 
-        ComboBox combo = new ComboBox();
+        ComboBox<String> combo = new ComboBox<>();
         combo.setCaption("Combo1");
 
         CheckBox check = new CheckBox();
index bb0d3517ad3f858fb12660acf5da5f9ff2fc7060..ad98a4b38a8665fcfda5b0e297909052d6c66046 100644 (file)
  */
 package com.vaadin.tests.components.select;
 
+import java.util.Arrays;
 import java.util.Locale;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
-import com.vaadin.v7.shared.ui.combobox.FilteringMode;
-import com.vaadin.v7.ui.ComboBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.v7.data.util.converter.StringToEnumConverter;
 import com.vaadin.v7.ui.NativeSelect;
 import com.vaadin.v7.ui.Tree;
 
@@ -34,11 +35,10 @@ public class EnumSelect extends AbstractTestUIWithLog {
     protected void setup(VaadinRequest request) {
 
         setLocale(new Locale("fi", "FI"));
-        ComboBox cb = new ComboBox();
-        cb.setFilteringMode(FilteringMode.CONTAINS);
-        for (Constant c : Constant.values()) {
-            cb.addItem(c);
-        }
+        ComboBox<Constant> cb = new ComboBox<>(null,
+                Arrays.asList(Constant.values()));
+        cb.setItemCaptionProvider(value -> StringToEnumConverter
+                .enumToString(value, getLocale()));
         addComponent(cb);
 
         NativeSelect ns = new NativeSelect();
diff --git a/uitest/src/main/java/com/vaadin/tests/components/select/SelectTest.java b/uitest/src/main/java/com/vaadin/tests/components/select/SelectTest.java
deleted file mode 100644 (file)
index 95c651e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.vaadin.tests.components.select;
-
-import com.vaadin.tests.components.combobox.ComboBoxes2;
-import com.vaadin.v7.ui.Select;
-
-public class SelectTest extends ComboBoxes2<Select> {
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected Class<Select> getTestClass() {
-        return Select.class;
-    }
-
-}
index 9b63326e277b3b51c7e1bf9f8019cd0725d03602..3ebd2178188a6115ed6ad0b702d18b080672ebf9 100644 (file)
@@ -26,7 +26,7 @@ public class StylingPopupOpener extends TestBase {
 
     @Override
     protected String getDescription() {
-        return "VFilterSelect popup opener width is not updated when the style or theme changes";
+        return "ComboBox popup opener width is not updated when the style or theme changes";
     }
 
     @Override
index 923e5e0c43324dd8e76b84fe3bac05ef375bf6e0..6bc84db6e9ab90546e5ad09ac17c14a95ee75e38 100644 (file)
@@ -2,6 +2,7 @@ package com.vaadin.tests.components.table;
 
 import java.math.BigDecimal;
 import java.text.NumberFormat;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Locale;
 
@@ -12,12 +13,12 @@ import com.vaadin.tests.data.bean.Person;
 import com.vaadin.tests.data.bean.Sex;
 import com.vaadin.tests.util.Log;
 import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.v7.data.Property.ValueChangeEvent;
 import com.vaadin.v7.data.Property.ValueChangeListener;
 import com.vaadin.v7.data.util.BeanItemContainer;
 import com.vaadin.v7.data.util.converter.Converter;
 import com.vaadin.v7.data.util.converter.StringToDoubleConverter;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.Table;
 
 public class DoublesInTable extends TestBase {
@@ -56,20 +57,10 @@ public class DoublesInTable extends TestBase {
     }
 
     private ComboBox createLocaleSelect() {
-        ComboBox cb = new ComboBox();
-        cb.setNullSelectionAllowed(false);
-        for (Locale l : Locale.getAvailableLocales()) {
-            cb.addItem(l);
-        }
-        cb.setImmediate(true);
+        ComboBox<Locale> cb = new ComboBox<>(null,
+                Arrays.asList(Locale.getAvailableLocales()));
         cb.setValue(Locale.US);
-        cb.addListener(new ValueChangeListener() {
-
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-                recreateTable();
-            }
-        });
+        cb.addListener(event -> recreateTable());
         return cb;
     }
 
index a5edab0d08e229462c8aed17eef5f1eac6d07e2b..1c065450f6f20c53f0a38cbae00401a9aa83fa52 100644 (file)
@@ -2,8 +2,8 @@ package com.vaadin.tests.components.ui;
 
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Label;
-import com.vaadin.v7.ui.ComboBox;
 
 public class ComboboxSelectedItemText extends AbstractTestUIWithLog {
     @Override
@@ -11,18 +11,16 @@ public class ComboboxSelectedItemText extends AbstractTestUIWithLog {
         getLayout().addComponent(new Label(
                 "Select first ANTIGUA AND BARBUDA from the first combobox. Then select ANTIGUA AND BARBUDA from the second combobox. Finally, click the popup button on the first combobox. Before fix you would see UA AND BAR in the field."));
 
-        ComboBox combobox = new ComboBox("Text input enabled:");
+        ComboBox<String> combobox = new ComboBox<>("Text input enabled:");
         combobox.setWidth("100px");
 
-        combobox.addItem("AMERICAN SAMOA");
-        combobox.addItem("ANTIGUA AND BARBUDA");
+        combobox.setItems("AMERICAN SAMOA", "ANTIGUA AND BARBUDA");
 
-        ComboBox combobox2 = new ComboBox("Text input disabled:");
+        ComboBox<String> combobox2 = new ComboBox<>("Text input disabled:");
         combobox2.setWidth("100px");
         combobox2.setTextInputAllowed(false);
 
-        combobox2.addItem("AMERICAN SAMOA");
-        combobox2.addItem("ANTIGUA AND BARBUDA");
+        combobox2.setItems("AMERICAN SAMOA", "ANTIGUA AND BARBUDA");
 
         getLayout().addComponent(combobox);
         getLayout().addComponent(combobox2);
index 80ddbaa9da82092702a30305d70815ee37833583..683d9b7deb4142b328f65dec12fbd9c16ebee24e 100644 (file)
@@ -1,6 +1,7 @@
 package com.vaadin.tests.components.upload;
 
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
@@ -15,20 +16,22 @@ import com.vaadin.server.StreamVariable;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
 import com.vaadin.ui.Button;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.DragAndDropWrapper;
 import com.vaadin.ui.Html5File;
 import com.vaadin.ui.Panel;
-import com.vaadin.v7.ui.ComboBox;
 
 public class DragAndDropUploadAndInteractions extends AbstractTestUIWithLog {
 
     @Override
     protected void setup(VaadinRequest request) {
-        ComboBox comboBox = new ComboBox();
+        ComboBox<String> comboBox = new ComboBox<>();
+        List<String> items = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
-            comboBox.addItem("Test " + i);
+            items.add("Test " + i);
         }
+        comboBox.setItems(items);
         addComponent(comboBox);
         Button b = new Button("Dummy");
         addComponent(b);
index b98694ce76b9e527abef622f4d196e7f82eee774..6a5a6ff30ce0af7c87aa700fde8a138c253b4c2c 100644 (file)
@@ -18,9 +18,9 @@ package com.vaadin.tests.components.window;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Alignment;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
-import com.vaadin.v7.ui.ComboBox;
 
 /**
  *
@@ -44,7 +44,7 @@ public class ComboboxScrollableWindow extends AbstractTestUI {
         VerticalLayout content = new VerticalLayout();
         w.setContent(content);
         content.setHeight("1000px");
-        ComboBox cb = new ComboBox();
+        ComboBox<String> cb = new ComboBox<>();
         cb.setId(COMBOBOX_ID);
         content.addComponent(cb);
         content.setComponentAlignment(cb, Alignment.BOTTOM_CENTER);
index 5b08d08456d1d3b7c48d16bc3e33e87048c5328f..0288eafad529010470b881ec50bf1c9938984e4c 100644 (file)
@@ -1,53 +1,41 @@
 package com.vaadin.tests.components.window;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.shared.ui.window.WindowMode;
 import com.vaadin.tests.components.AbstractTestUI;
 import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.ComponentContainer;
 import com.vaadin.ui.NativeButton;
 import com.vaadin.ui.UI;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
-import com.vaadin.ui.Window.CloseEvent;
-import com.vaadin.ui.Window.CloseListener;
 import com.vaadin.ui.Window.WindowModeChangeEvent;
 import com.vaadin.ui.Window.WindowModeChangeListener;
-import com.vaadin.v7.data.Item;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
 
 public class WindowMaximizeRestoreTest extends AbstractTestUI {
-    Button.ClickListener addListener = new Button.ClickListener() {
-
-        @Override
-        public void buttonClick(ClickEvent event) {
-            addWindow(createNewWindow());
-        }
-    };
-
     @Override
     protected void setup(VaadinRequest request) {
         Button addButton = new Button("Add new Window");
-        addButton.addListener(addListener);
+        addButton.addClickListener(event -> {
+            addWindow(createNewWindow());
+            addWindowAgain.setValue(null);
+        });
         addComponent(addButton);
 
-        addWindowAgain = new ComboBox("Add Window Again");
-        addWindowAgain.setBuffered(false);
-        addWindowAgain.setImmediate(true);
-        addWindowAgain.addValueChangeListener(new ValueChangeListener() {
-
-            @Override
-            public void valueChange(ValueChangeEvent event) {
-
-                Object value = event.getProperty().getValue();
-                if (value != null && value instanceof Window) {
-                    UI.getCurrent().addWindow((Window) value);
-                    addWindowAgain.removeItem(value);
-                }
+        addWindowAgain = new ComboBox<>("Add Window Again");
+        addWindowAgain
+                .setItemCaptionProvider(window -> window.getData().toString());
+        addWindowAgain.addValueChangeListener(event -> {
+            Object value = event.getValue();
+            if (value != null && value instanceof Window) {
+                UI.getCurrent().addWindow((Window) value);
+                windowList.remove(value);
+                addWindowAgain.setItems(windowList);
             }
         });
         addComponent(addWindowAgain);
@@ -56,7 +44,8 @@ public class WindowMaximizeRestoreTest extends AbstractTestUI {
     }
 
     private int windowCount = 0;
-    private ComboBox addWindowAgain;
+    private ComboBox<Window> addWindowAgain;
+    private List<Window> windowList = new ArrayList<>();
 
     private Window createNewWindow() {
         final Window w = new Window("Window " + (++windowCount));
@@ -68,21 +57,15 @@ public class WindowMaximizeRestoreTest extends AbstractTestUI {
         w.setPositionX(200);
         w.setPositionY(200);
         final NativeButton maximize = new NativeButton("Maximize");
-        Button.ClickListener listener = new Button.ClickListener() {
-
-            @Override
-            public void buttonClick(ClickEvent event) {
-                if (w.getWindowMode() == WindowMode.MAXIMIZED) {
-                    w.setWindowMode(WindowMode.NORMAL);
-                    maximize.setCaption("Maximize");
-                } else {
-                    w.setWindowMode(WindowMode.MAXIMIZED);
-                    maximize.setCaption("Restore");
-                }
+        maximize.addClickListener(event -> {
+            if (w.getWindowMode() == WindowMode.MAXIMIZED) {
+                w.setWindowMode(WindowMode.NORMAL);
+                maximize.setCaption("Maximize");
+            } else {
+                w.setWindowMode(WindowMode.MAXIMIZED);
+                maximize.setCaption("Restore");
             }
-
-        };
-        maximize.addClickListener(listener);
+        });
         ((ComponentContainer) w.getContent()).addComponent(maximize);
 
         w.addWindowModeChangeListener(new WindowModeChangeListener() {
@@ -110,34 +93,17 @@ public class WindowMaximizeRestoreTest extends AbstractTestUI {
                 event -> w.setClosable(closeable.getValue()));
         ((ComponentContainer) w.getContent()).addComponent(closeable);
         NativeButton contentFull = new NativeButton("Set Content Size Full",
-                new Button.ClickListener() {
-
-                    @Override
-                    public void buttonClick(ClickEvent event) {
-                        w.getContent().setSizeFull();
-                    }
-                });
+                event -> w.getContent().setSizeFull());
         contentFull.setWidth("100%");
         ((ComponentContainer) w.getContent()).addComponent(contentFull);
 
         NativeButton center = new NativeButton("Center");
-        center.addClickListener(new Button.ClickListener() {
-
-            @Override
-            public void buttonClick(ClickEvent event) {
-                w.center();
-            }
-        });
+        center.addClickListener(event -> w.center());
         ((ComponentContainer) w.getContent()).addComponent(center);
 
-        w.addCloseListener(new CloseListener() {
-
-            @Override
-            public void windowClose(CloseEvent e) {
-                Item item = addWindowAgain.addItem(w);
-                addWindowAgain.setItemCaption(w,
-                        "Window " + w.getData().toString());
-            }
+        w.addCloseListener(e -> {
+            windowList.add(w);
+            addWindowAgain.setItems(windowList);
         });
 
         return w;
index 5790f8ad508bf0b8397cd6d2210ac9954411cec0..0cd4eb9f32062a08bb21e1bc71dd15c0b454c95e 100644 (file)
@@ -12,6 +12,7 @@ import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.Button.ClickListener;
 import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.CssLayout;
 import com.vaadin.ui.DateField;
@@ -23,7 +24,6 @@ import com.vaadin.ui.VerticalLayout;
 import com.vaadin.v7.data.Item;
 import com.vaadin.v7.data.Property.ValueChangeEvent;
 import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
 import com.vaadin.v7.ui.NativeSelect;
 import com.vaadin.v7.ui.OptionGroup;
 import com.vaadin.v7.ui.PasswordField;
@@ -209,8 +209,8 @@ public class CaptionsInLayoutsWaiAria extends TestBase {
 
         components.add(new CheckBox("Default CheckBox"));
 
-        ComboBox comboBox = new ComboBox("Default ComboBox");
-        comboBox.addItem("Item1");
+        ComboBox<String> comboBox = new ComboBox<>("Default ComboBox");
+        comboBox.setItems("Item1");
         components.add(comboBox);
 
         OptionGroup radioGroup = new OptionGroup("Single Items");
index fb182cc89a572faf5f80498053cbce3fead4f50f..5aee3a2f15674ba4d8841addb88778453bdd5edf 100644 (file)
@@ -4,11 +4,13 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+import com.vaadin.server.data.Query;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.AbsoluteLayout;
 import com.vaadin.ui.Accordion;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.ComboBox;
 import com.vaadin.ui.ComponentContainer;
 import com.vaadin.ui.CssLayout;
 import com.vaadin.ui.FormLayout;
@@ -22,9 +24,6 @@ import com.vaadin.ui.SingleComponentContainer;
 import com.vaadin.ui.TabSheet;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.VerticalSplitPanel;
-import com.vaadin.v7.data.Property.ValueChangeEvent;
-import com.vaadin.v7.data.Property.ValueChangeListener;
-import com.vaadin.v7.ui.ComboBox;
 
 public class MovingComponentsWhileOldParentInvisible extends TestBase {
 
@@ -37,37 +36,24 @@ public class MovingComponentsWhileOldParentInvisible extends TestBase {
         lab = new Label("Label inside the component container");
         lab.setWidth(null);
 
-        ComboBox componentContainerSelect = new ComboBox("Container") {
-            {
-                setPageLength(0);
-            }
-        };
+        ComboBox<Class<? extends HasComponents>> componentContainerSelect = new ComboBox<>(
+                "Container");
+        componentContainerSelect.setPageLength(0);
         componentContainerSelect.setId("componentContainerSelect");
         componentContainerSelect.setWidth("300px");
-        componentContainerSelect.setImmediate(true);
-        componentContainerSelect.setNullSelectionAllowed(false);
         // componentContainer.addContainerProperty(CAPTION, String.class, "");
         // componentContainer.addContainerProperty(CLASS, Class.class, "");
 
-        for (Class<? extends HasComponents> cls : getComponentContainers()) {
-            componentContainerSelect.addItem(cls);
-        }
-        componentContainerSelect.addListener(new ValueChangeListener() {
-
-            @Override
-            @SuppressWarnings("unchecked")
-            public void valueChange(ValueChangeEvent event) {
-                HasComponents oldCC = cc;
-                cc = createComponentContainer(
-                        (Class<? extends HasComponents>) event.getProperty()
-                                .getValue());
-                addToCC(lab);
-                replaceComponent(oldCC, cc);
-            }
+        componentContainerSelect.setItems(getComponentContainers());
+        componentContainerSelect.addValueChangeListener(event -> {
+            HasComponents oldCC = cc;
+            cc = createComponentContainer(event.getValue());
+            addToCC(lab);
+            replaceComponent(oldCC, cc);
         });
 
-        componentContainerSelect.setValue(
-                componentContainerSelect.getItemIds().iterator().next());
+        componentContainerSelect.setValue(componentContainerSelect
+                .getDataSource().apply(new Query()).iterator().next());
         Button but1 = new Button("Move in and out of component container",
                 new Button.ClickListener() {
 
index 4dfc99cd1f8959b0573579286870f50a10596e09..50a20b33ef3d67bcb84a827d7890d04ad44265dc 100644 (file)
@@ -21,9 +21,9 @@ import org.junit.Test;
 import org.openqa.selenium.Keys;
 import org.openqa.selenium.interactions.Actions;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxBorderTest extends MultiBrowserTest {
     @Test
index e83a8bb12663f19dc962b218fd6f7d4bb4cc6e22..969af8eca2ba4242793af6817fc008e4335251c1 100644 (file)
@@ -19,8 +19,8 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.openqa.selenium.By;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * Test to check whether combobox is expanded when icon is clicked.
index fe06f4f32987e40af6ab5d177497ac2b37d545b0..5c0d08a9945bfcab51ae3c168256b29fce1e85bc 100644 (file)
@@ -10,8 +10,8 @@ import org.openqa.selenium.Keys;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.SingleBrowserTestPhantomJS2;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxEmptyItemsKeyboardNavigationTest
         extends SingleBrowserTestPhantomJS2 {
index 22cb44b3c9e3e614a388cecd4a997be9237e3418..5eb1c372c8f00f5988031d26643c8c531c235916 100644 (file)
@@ -21,9 +21,9 @@ import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.support.ui.ExpectedCondition;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.parallel.BrowserUtil;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * Test for identical item captions in ComboBox.
index 6a0e56e05976483b7c4d15f2d25ece42c648eee2..3ddea898b44d3225a153d64252fcd8d67423da4a 100644 (file)
@@ -23,9 +23,9 @@ import org.junit.Test;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.ButtonElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxInputPromptTest extends MultiBrowserTest {
 
@@ -60,7 +60,7 @@ public class ComboBoxInputPromptTest extends MultiBrowserTest {
     private String getInputPromptValue(ComboBoxElement comboBox) {
         WebElement input = comboBox.findElement(By.tagName("input"));
 
-        return input.getAttribute("value");
+        return input.getAttribute("placeholder");
     }
 
     private ComboBoxElement getComboBoxWithCaption(String caption) {
index aea88eb4b7fe9e7dab9333ab0c9b70ae1a231d76..39e23a4ec7569ace6b870cff07bd3f5407333fcd 100644 (file)
@@ -2,8 +2,8 @@ package com.vaadin.tests.components.combobox;
 
 import org.junit.Test;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxItemIconTest extends MultiBrowserTest {
     @Test
index b51aed8d2a54aa46fbfaa42c9f274ee93bac851a..88f4e74a2ea0db4445b513d180520743742827bc 100644 (file)
@@ -5,8 +5,8 @@ import org.openqa.selenium.Keys;
 import org.openqa.selenium.interactions.Actions;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 import com.vaadin.v7.testbench.customelements.NativeSelectElement;
 
 public class ComboBoxLargeIconsTest extends MultiBrowserTest {
index cb1ba25294d8296a14346b39b5cb728a0358943f..1200b778a11f80da7a90a76f3c4744f95bdd9505 100644 (file)
@@ -28,10 +28,10 @@ import org.openqa.selenium.interactions.Actions;
 import org.openqa.selenium.support.ui.ExpectedCondition;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.testbench.parallel.BrowserUtil;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxMouseSelectEnterTest extends MultiBrowserTest {
 
index 975452d63a108d27fc46fab1f500e831f49c6d96..054b24525a25813dba21b6dc8afff4c8fd1fdb33 100644 (file)
@@ -21,9 +21,9 @@ import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
 import com.vaadin.testbench.commands.TestBenchElementCommands;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.CheckBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxNoTextInputTest extends MultiBrowserTest {
 
@@ -38,8 +38,7 @@ public class ComboBoxNoTextInputTest extends MultiBrowserTest {
         ComboBoxElement cb = $(ComboBoxElement.class).first();
         click(cb);
         // popup is opened lazily
-        waitForElementPresent(
-                By.vaadin("//com.vaadin.v7.ui.ComboBox[0]#popup"));
+        waitForElementPresent(By.vaadin("//com.vaadin.ui.ComboBox[0]#popup"));
     }
 
     @Test
index 322425a103cb0d72f618aba041b1a2b6fd169d03..d34380b5bd8274bc7a829fa247dcc10ce0d0dc2d 100644 (file)
@@ -19,8 +19,8 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.openqa.selenium.WebElement;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxPopupWhenBodyScrollsTest extends MultiBrowserTest {
 
index 2624b337dcc235a05cdb602e224ba45528182158..858a5630c9ab1a06f09bdebfe93771d7fe92c94c 100644 (file)
@@ -17,9 +17,9 @@ package com.vaadin.tests.components.combobox;
 
 import org.junit.Test;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * When pressed down key, while positioned on the last item - should show next
index b2e9290f378bf33458d4346aa381f11440f57c0c..fc199b9a381a5c84e5044043b905316cba8531e3 100644 (file)
@@ -27,8 +27,8 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.ui.ExpectedCondition;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * When pressed down key, while positioned on the last item - should show next
index d02667cf031655131a7c9fbfad193d4bd25410bb..4ae2a4e8c510928e371325c9fd9ba0c10df4f91b 100644 (file)
@@ -9,10 +9,10 @@ import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.support.ui.ExpectedCondition;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.testbench.parallel.BrowserUtil;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxSelectingTest extends MultiBrowserTest {
 
@@ -111,7 +111,11 @@ public class ComboBoxSelectingTest extends MultiBrowserTest {
         assertThatSelectedValueIs("z5");
         // longer delay for this one because otherwise it keeps failing when run
         // on local machine
-        comboBoxElement.sendKeys(200, Keys.BACK_SPACE, Keys.BACK_SPACE,
+        int delay = 200;
+        if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) {
+            delay = 500;
+        }
+        comboBoxElement.sendKeys(delay, Keys.BACK_SPACE, Keys.BACK_SPACE,
                 Keys.TAB);
         assertThatSelectedValueIs("", "null");
 
index 6adb68f933f976c48b669b0a07a4ea3a63d3f58a..b568ecf912f358e3c3cef1e5c8c7a9ff720d9ef8 100644 (file)
@@ -24,10 +24,10 @@ import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.support.ui.ExpectedCondition;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.testbench.parallel.BrowserUtil;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxSelectingWithNewItemsAllowedTest extends MultiBrowserTest {
     private ComboBoxElement comboBoxElement;
index 137216d7181328539ae29bb35f73a93aac3a22b6..29dfee3cb77236565d67819c28bd59948336b8d4 100644 (file)
@@ -25,8 +25,8 @@ import org.junit.Test;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboBoxSuggestionPageLengthTest extends MultiBrowserTest {
 
index 9be6f28dae75536fb5a5ad6154a6af630985e05c..0eeae42508f089c116ba11c3a696e43ac7542e61 100644 (file)
@@ -24,8 +24,8 @@ import org.openqa.selenium.Keys;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * @author Vaadin Ltd
index f0c0fdf5092c3c3e4740b207a5c5316c8f61929b..671e54fca5c5a876fbf8c974865ed90c8bfdf17b 100644 (file)
@@ -19,8 +19,8 @@ import org.junit.Test;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * @author Vaadin Ltd
index 371e5aee9531c29153322db61c6ab99d61b22db5..b96e7af3aa24718371e8d16bcf696d55f72afd8e 100644 (file)
@@ -21,8 +21,8 @@ import org.junit.Test;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * @author Vaadin Ltd
index 1d175b63f8fe1d93ae5c159274a264344dc85474..d37c0e8fb62821836cb910912c85b9a8ef8a7858 100644 (file)
@@ -21,8 +21,8 @@ import org.junit.Test;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * @author Vaadin Ltd
index 3ee8bb76a143ed0df66a79e7a1e1c81070613da3..485bc107bb47ac0875e0b8c86cd14a05324ff4d4 100644 (file)
@@ -21,8 +21,8 @@ import org.junit.Test;
 import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * @author Vaadin Ltd
index 386621858bf8e59ceb8e02bf5e0abda3178e9052..0d8bc8b7b0dbf962331df10f5842ca72c9045ef8 100644 (file)
@@ -20,9 +20,9 @@ import static org.hamcrest.Matchers.is;
 
 import org.junit.Test;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.LabelElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 @SuppressWarnings("serial")
 public class ComboSelectedValueBeyondTheFirstDropdownPageTest
index 8c6f7d68d5112485145aa2fe56ac616c77d7c6aa..59653535419ad18efc740669c30853359157c577 100644 (file)
@@ -21,9 +21,9 @@ import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.interactions.Actions;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.MenuBarElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * Test that checks whether Combobox popup is closed on click to autoopen
@@ -35,6 +35,7 @@ public class ComboboxMenuBarAutoopenTest extends MultiBrowserTest {
 
     @Test
     public void closeComboboxPopupOnClickToMenuBar() {
+        setDebug(true);
         openTestURL();
 
         openPopup();
@@ -57,9 +58,7 @@ public class ComboboxMenuBarAutoopenTest extends MultiBrowserTest {
 
     private void openPopup() {
         ComboBoxElement combobox = $(ComboBoxElement.class).first();
-        combobox.click();
         combobox.openPopup();
-        combobox.focus();
 
         Actions actions = new Actions(getDriver());
         actions.moveToElement(
index ba3543e981c6e7182f5ad1bb2471577fc5389356..9739316f4d0b351223bf31aa72eb40c748e516bd 100644 (file)
@@ -19,8 +19,8 @@ import org.junit.Test;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 public class ComboboxPopupScrollingTest extends MultiBrowserTest {
 
index 0de930f882bdb75c9446df2346edf09ced720a16..bea1ee770f784ec0d8e5be5af6aa8d2f4fcca39c 100644 (file)
@@ -19,9 +19,9 @@ import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
 
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.elements.ButtonElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * Tests that changing a stylename will not cause the width parameter to be
index 51b1addba059a0ca111d72f08857623f3eb95a23..b4ff27338d7a50f40293be0cb04b883058024260 100644 (file)
@@ -21,8 +21,8 @@ import org.junit.Assert;
 import org.junit.Test;
 
 import com.vaadin.testbench.By;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 import com.vaadin.v7.testbench.customelements.NativeSelectElement;
 
 public class FilteringTurkishLocaleTest extends MultiBrowserTest {
@@ -49,7 +49,7 @@ public class FilteringTurkishLocaleTest extends MultiBrowserTest {
 
         Assert.assertEquals("There should be only one suggestion", 1,
                 suggestions.size());
-        Assert.assertEquals("İ with dot", suggestions.get(0));
+        Assert.assertEquals("İ dotted", suggestions.get(0));
     }
 
     @Test
@@ -62,7 +62,7 @@ public class FilteringTurkishLocaleTest extends MultiBrowserTest {
 
         Assert.assertEquals("There should be only one suggestion", 1,
                 suggestions.size());
-        Assert.assertEquals("I without dot", suggestions.get(0));
+        Assert.assertEquals("I dotless", suggestions.get(0));
     }
 
     private List<String> getFilterSuggestions(String string) {
index f7f5c7196ba0960a5d79f9967644039e5ce5cc65..b7a88f85fbcf6efd7043921771a66f5d7a9a78ea 100644 (file)
@@ -22,8 +22,8 @@ import org.junit.Test;
 
 import com.vaadin.testbench.By;
 import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.tests.tb3.SingleBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 import com.vaadin.v7.testbench.customelements.NativeSelectElement;
 
 public class EnumSelectTest extends SingleBrowserTest {
index 08b52edf1e2fcb7e1752fd00e5a986206dc080da..4d4f81adb6278b529b86ba2df970718f164e9d11 100644 (file)
@@ -68,10 +68,10 @@ public class ComboboxSelectedItemTextTest extends MultiBrowserTest {
 
         WebElement comboBox = vaadinElement(
                 "/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot["
-                        + indexToTest + "]/VFilterSelect[0]");
+                        + indexToTest + "]/VComboBox[0]");
         WebElement comboBoxFocus = vaadinElement(
                 "/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot["
-                        + indexToFocus + "]/VFilterSelect[0]");
+                        + indexToFocus + "]/VComboBox[0]");
 
         // Select an element from the first (to test) combobox.
 
@@ -79,7 +79,7 @@ public class ComboboxSelectedItemTextTest extends MultiBrowserTest {
         waitForPopup(comboBox);
         WebElement comboBoxPopup = vaadinElement(
                 "/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot["
-                        + indexToTest + "]/VFilterSelect[0]#popup");
+                        + indexToTest + "]/VComboBox[0]#popup");
         comboBoxPopup.findElements(By.tagName("td")).get(2).click();
 
         // Select an element from the second (to focus) combobox to remove
@@ -90,7 +90,7 @@ public class ComboboxSelectedItemTextTest extends MultiBrowserTest {
         waitForPopup(comboBoxFocus);
         comboBoxPopup = vaadinElement(
                 "/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot["
-                        + indexToFocus + "]/VFilterSelect[0]#popup");
+                        + indexToFocus + "]/VComboBox[0]#popup");
         comboBoxPopup.findElements(By.tagName("td")).get(2).click();
 
         // click the button of the first combobox. This would reveal the
index 34ac732ab34ceeaf9915032b024e6c53349b9d0e..83a39b3344471fe6e1155f3a03a9a6e8eb82eb5d 100644 (file)
@@ -23,9 +23,9 @@ import org.openqa.selenium.WebElement;
 
 import com.vaadin.testbench.By;
 import com.vaadin.testbench.commands.TestBenchElementCommands;
+import com.vaadin.testbench.customelements.ComboBoxElement;
 import com.vaadin.testbench.customelements.WindowElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.v7.testbench.customelements.ComboBoxElement;
 
 /**
  * Tests that a ComboBox at the bottom of a Window remains visible when clicked.