]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merged tests, fixes and javadoc updates from 6.7
authorArtur Signell <artur.signell@itmill.com>
Thu, 8 Dec 2011 13:16:30 +0000 (13:16 +0000)
committerArtur Signell <artur.signell@itmill.com>
Thu, 8 Dec 2011 13:16:30 +0000 (13:16 +0000)
svn changeset:22323/svn branch:6.8

19 files changed:
build/build.xml
src/com/vaadin/Application.java
src/com/vaadin/data/util/AbstractBeanContainer.java
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
src/com/vaadin/terminal/gwt/client/ui/VTextField.java
src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java
src/com/vaadin/ui/AbstractSelect.java
src/com/vaadin/ui/LoginForm.java
src/com/vaadin/ui/Slider.java
src/com/vaadin/ui/Table.java
src/com/vaadin/ui/Window.java
tests/testbench/com/vaadin/tests/components/table/AddNonRenderedRow.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/ProgrammaticUnselectInRange.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/ProgrammaticUnselectInRange.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/textfield/MultipleTextChangeEvents.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/treetable/AddNodesOnExpand.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/treetable/AddNodesOnExpand.java [new file with mode: 0644]

index a038edb139fadf26259843de2c89356190807614..046392fe57afb84ca87b0ee715ca931a1816957d 100644 (file)
     
     <target name="compile-widgetset" description="Compiles the widgetset given as the first parameter">
         <fail unless="widgetset" message="No widgetset parameter set"/>
+        <property name="widgetset-style" value="OBF" />
+       <property name="widgetset-localWorkers" value="4" />
+       <property name="widgetset-extraParams" value="" />
         <echo>Compiling widgetset ${widgetset}. Output directory: ${widgetsets-output-dir}</echo>
         <java classname="com.google.gwt.dev.Compiler" failonerror="yes" fork="yes" maxmemory="512m">
             <classpath refid="widgetset-compile-classpath"/>
             <arg value="-war" />
             <arg value="${widgetsets-output-dir}" />
             <arg value="-style" />
-            <arg value="OBF" />
+            <arg value="${widgetset-style}" />
             <arg value="-localWorkers" />
-            <arg value="4" />
+            <arg value="${widgetset-localWorkers}" />
+               <arg line="${widgetset-extraParams}" />
             <arg value="${widgetset}" />
 
             <jvmarg value="-Xss8M"/>
index 39a70fe27fb28fdfcd9c49056b968ee4da6e9591..cd1da8f9fd84cb2c6fe064fd9fae31ec2f87a41a 100644 (file)
@@ -209,11 +209,11 @@ public abstract class Application implements URIHandler,
      * 
      * <p>
      * If for some reason user opens another window with same url that is
-     * already open, name is modified by adding "_12345678" postfix to the name,
-     * where 12345678 is a random number. One can decide to create another
-     * window-object for those windows (recommended) or to discard the postfix.
-     * If the user has two browser windows pointing to the same window-object on
-     * server, synchronization errors are likely to occur.
+     * already open, the name is modified by adding a "_N" postfix to the name,
+     * where N is a running number starting from 1. One can decide to create
+     * another window-object for those windows (recommended) or to discard the
+     * postfix. If the user has two browser windows pointing to the same
+     * window-object on server, synchronization errors are likely to occur.
      * </p>
      * 
      * <p>
@@ -1384,7 +1384,7 @@ public abstract class Application implements URIHandler,
         }
 
         /**
-         * @return
+         * @return 
          *         "Take note of any unsaved data, and <u>click here</u> to continue."
          */
         public String getSessionExpiredMessage() {
@@ -1416,7 +1416,7 @@ public abstract class Application implements URIHandler,
         }
 
         /**
-         * @return
+         * @return 
          *         "Take note of any unsaved data, and <u>click here</u> to continue."
          */
         public String getCommunicationErrorMessage() {
@@ -1448,7 +1448,7 @@ public abstract class Application implements URIHandler,
         }
 
         /**
-         * @return
+         * @return 
          *         "Take note of any unsaved data, and <u>click here</u> to continue."
          */
         public String getAuthenticationErrorMessage() {
index b1d0b0672bb32dee2577a097a49f02c5432dfb4c..1b297d6a8886ba323587c52a77be9aeb5527440a 100644 (file)
@@ -637,6 +637,11 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
                 continue;
             }
             IDTYPE itemId = resolveBeanId(bean);
+            if (itemId == null) {
+                throw new IllegalArgumentException(
+                        "Resolved identifier for a bean must not be null");
+            }
+
             if (internalAddItemAtEnd(itemId, createBeanItem(bean), false) != null) {
                 modified = true;
             }
index c919d82923edf55b02fade068b82fb63b1fbf7d1..38872c73a1dbd7bf929d3194924b3439d54a9776 100644 (file)
@@ -1094,6 +1094,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     }
                     if (selected != row.isSelected()) {
                         row.toggleSelection();
+                        if (!isSingleSelectMode() && !selected) {
+                            // Update selection range in case a row is
+                            // unselected from the middle of a range - #8076
+                            removeRowFromUnsentSelectionRanges(row);
+                        }
                     }
                 }
             }
@@ -4132,7 +4137,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 VScrollTableRow r = (VScrollTableRow) renderedRows.get(ix);
                 r.setIndex(r.getIndex() + rows);
             }
-            fixSpacers();
+            setContainerHeight();
             return inserted;
         }
 
@@ -4140,6 +4145,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 int rows) {
             unlinkAllRowsStartingAt(firstIndex);
             insertRows(rowData, firstIndex, rows);
+            setContainerHeight();
         }
 
         /**
@@ -4258,7 +4264,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 VScrollTableRow r = (VScrollTableRow) renderedRows.get(ix);
                 r.setIndex(r.getIndex() - count);
             }
-            fixSpacers();
+            setContainerHeight();
         }
 
         protected void unlinkAllRowsStartingAt(int index) {
@@ -4851,44 +4857,44 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 }
             }
 
-            private void handleClickEvent(Event event, Element targetTdOrTr) {
-                if (client.hasEventListeners(VScrollTable.this,
+            /**
+             * If there are registered click listeners, sends a click event and
+             * returns true. Otherwise, does nothing and returns false.
+             * 
+             * @param event
+             * @param targetTdOrTr
+             * @param immediate
+             *            Whether the event is sent immediately
+             * @return Whether a click event was sent
+             */
+            private boolean handleClickEvent(Event event, Element targetTdOrTr,
+                    boolean immediate) {
+                if (!client.hasEventListeners(VScrollTable.this,
                         ITEM_CLICK_EVENT_ID)) {
-                    boolean doubleClick = (DOM.eventGetType(event) == Event.ONDBLCLICK);
-
-                    /* This row was clicked */
-                    client.updateVariable(paintableId, "clickedKey", ""
-                            + rowKey, false);
-
-                    if (getElement() == targetTdOrTr.getParentElement()) {
-                        /* A specific column was clicked */
-                        int childIndex = DOM.getChildIndex(getElement(),
-                                targetTdOrTr);
-                        String colKey = null;
-                        colKey = tHead.getHeaderCell(childIndex).getColKey();
-                        client.updateVariable(paintableId, "clickedColKey",
-                                colKey, false);
-                    }
-
-                    MouseEventDetails details = new MouseEventDetails(event);
+                    // Don't send an event if nobody is listening
+                    return false;
+                }
 
-                    boolean imm = true;
-                    if (immediate && event.getButton() == Event.BUTTON_LEFT
-                            && !doubleClick && isSelectable() && !isSelected()) {
-                        /*
-                         * A left click when the table is selectable and in
-                         * immediate mode on a row that is not currently
-                         * selected will cause a selection event to be fired
-                         * after this click event. By making the click event
-                         * non-immediate we avoid sending two separate messages
-                         * to the server.
-                         */
-                        imm = false;
-                    }
+                // This row was clicked
+                client.updateVariable(paintableId, "clickedKey", "" + rowKey,
+                        false);
 
-                    client.updateVariable(paintableId, "clickEvent",
-                            details.toString(), imm);
+                if (getElement() == targetTdOrTr.getParentElement()) {
+                    // A specific column was clicked
+                    int childIndex = DOM.getChildIndex(getElement(),
+                            targetTdOrTr);
+                    String colKey = null;
+                    colKey = tHead.getHeaderCell(childIndex).getColKey();
+                    client.updateVariable(paintableId, "clickedColKey", colKey,
+                            false);
                 }
+
+                MouseEventDetails details = new MouseEventDetails(event);
+
+                client.updateVariable(paintableId, "clickEvent",
+                        details.toString(), immediate);
+
+                return true;
             }
 
             private void handleTooltips(final Event event, Element target) {
@@ -4940,9 +4946,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                                 && (actionKeys != null || client
                                         .hasEventListeners(VScrollTable.this,
                                                 ITEM_CLICK_EVENT_ID))) {
-                            // Prevent browser context menu only if there are
-                            // action handlers or item click listeners
-                            // registered
+                            /*
+                             * Prevent browser context menu only if there are
+                             * action handlers or item click listeners
+                             * registered
+                             */
                             event.stopPropagation();
                             event.preventDefault();
                         }
@@ -4957,13 +4965,19 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     switch (type) {
                     case Event.ONDBLCLICK:
                         if (targetCellOrRowFound) {
-                            handleClickEvent(event, targetTdOrTr);
+                            handleClickEvent(event, targetTdOrTr, true);
                         }
                         break;
                     case Event.ONMOUSEUP:
                         if (targetCellOrRowFound) {
                             mDown = false;
-                            handleClickEvent(event, targetTdOrTr);
+                            /*
+                             * Queue here, send at the same time as the
+                             * corresponding value change event - see #7127
+                             */
+                            boolean clickEventSent = handleClickEvent(event,
+                                    targetTdOrTr, false);
+
                             if (event.getButton() == Event.BUTTON_LEFT
                                     && isSelectable()) {
 
@@ -5052,7 +5066,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                                             .setPropertyJSO("onselectstart",
                                                     null);
                                 }
-                                sendSelectedRows();
+                                // Queue value change
+                                sendSelectedRows(false);
+                            }
+                            /*
+                             * Send queued click and value change events if any
+                             * If a click event is sent, send value change with
+                             * it regardless of the immediate flag, see #7127
+                             */
+                            if (immediate || clickEventSent) {
+                                client.sendPendingVariableChanges();
                             }
                         }
                         break;
index 41d48041fcd19b1cb7309c26b5aa0079018e4e21..5894e003499c27f30db01d8155063aef50223459 100644 (file)
@@ -249,15 +249,15 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
         final String text = uidl.getStringVariable("text");
 
         /*
-         * We skip the text content update if field has been repainted, but text has
-         * not been changed. Additional sanity check verifies there is no change
-         * in the que (in which case we count more on the server side value).
+         * We skip the text content update if field has been repainted, but text
+         * has not been changed. Additional sanity check verifies there is no
+         * change in the que (in which case we count more on the server side
+         * value).
          */
-        if (!(uidl.getBooleanAttribute(ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) && valueBeforeEdit != null && text
-                .equals(valueBeforeEdit))) {
+        if (!(uidl.getBooleanAttribute(ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS)
+                && valueBeforeEdit != null && text.equals(valueBeforeEdit))) {
             updateFieldContent(text);
         }
-        
 
         if (uidl.hasAttribute("selpos")) {
             final int pos = uidl.getIntAttribute("selpos");
@@ -587,7 +587,20 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
     }
 
     public void onBeforeShortcutAction(Event e) {
+        // Remember current value to detect changes
+        String oldValue = valueBeforeEdit;
+
         valueChange(false);
+
+        /*
+         * The valueChange method updates valueBeforeEdit when a "text" variable
+         * is sent. This will cause a text change event to be simulated on the
+         * server. In that case, we should avoid sending the same text as a
+         * normal text change event. (#8035)
+         */
+        if (oldValue != valueBeforeEdit) {
+            lastTextChangeString = valueBeforeEdit;
+        }
     }
 
     // Here for backward compatibility; to be moved to TextArea
index bcb972ca6a914e19514e224ebc95d0f8b5baa643..5786dc421ab664de8f67960ec26c14269538d763 100644 (file)
@@ -9,6 +9,8 @@ import java.util.NoSuchElementException;
 import com.google.gwt.dom.client.DivElement;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.BorderStyle;
 import com.google.gwt.dom.client.TableElement;
 import com.google.gwt.user.client.ui.Panel;
 import com.google.gwt.user.client.ui.Widget;
@@ -222,6 +224,36 @@ public class ChildComponentContainer extends Panel {
          * does not include
          */
         int w = Util.getRequiredWidth(widgetDIV);
+
+        // IE7 ignores the width of the content if there's a border (#3915)
+        if (BrowserInfo.get().isIE7()) {
+            // Also read the inner width of the target element
+            int clientWidth = widget.getElement().getClientWidth();
+
+            // If the widths are different, there might be a border involved and
+            // then the width should be calculated without borders
+            if (w != clientWidth) {
+                // Remember old border style and remove current border
+                Style style = widget.getElement().getStyle();
+                String oldBorderStyle = style.getBorderStyle();
+                style.setBorderStyle(BorderStyle.NONE);
+
+                // Calculate width without borders
+                int newWidth = Util.getRequiredWidth(widgetDIV);
+
+                // Restore old border style
+                style.setProperty("borderStyle", oldBorderStyle);
+
+                // Borders triggered the bug if the element is wider without
+                // borders
+                if (newWidth > w) {
+                    // Use new measured width + the border width calculated as
+                    // the difference between previous inner and outer widths
+                    w = newWidth + (w - clientWidth);
+                }
+            }
+        }
+
         int h = Util.getRequiredHeight(widgetDIV);
 
         widgetSize.setWidth(w);
index 646d898a54b8058a79cd9974e7d3ef15dbde3453..9cf08490755fcc49086193bda7d255d18e5b0818 100644 (file)
@@ -1624,7 +1624,7 @@ public abstract class AbstractSelect extends AbstractField implements
      * 
      * <p>
      * Data interface does not support nulls as item ids. Selecting the item
-     * idetified by this id is the same as selecting no items at all. This
+     * identified by this id is the same as selecting no items at all. This
      * setting only affects the single select mode.
      * </p>
      * 
index 509a072c275ef66b374d0d3886bcaff76444c8c5..3004504b9d9b44293d463465f5fd04043b3c620e 100644 (file)
@@ -34,8 +34,6 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
  * Login page html can be overridden by replacing protected getLoginHTML method.
  * As the login page is actually an iframe, styles must be handled manually. By
  * default component tries to guess the right place for theme css.
- * <p>
- * Note, this is a new Ajax terminal specific component and is likely to change.
  * 
  * @since 5.3
  */
index c07913d5fe7b116a0bda9da7358139be3edd2079..74dbcd99bb1c7d04e7cc3d8fd8a8f221e2055c53 100644 (file)
@@ -46,7 +46,6 @@ import com.vaadin.terminal.gwt.client.ui.VSlider;
  * 
  * @author IT Mill Ltd.
  */
-@SuppressWarnings("serial")
 @ClientWidget(VSlider.class)
 public class Slider extends AbstractField {
 
@@ -110,7 +109,7 @@ public class Slider extends AbstractField {
     private final boolean arrows = false;
 
     /**
-     * Default Slider constructor. Sets all values to defaults and the slide
+     * Default slider constructor. Sets all values to defaults and the slide
      * handle at minimum value.
      * 
      */
@@ -120,11 +119,13 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Create a new slider with the caption given as parameter. All slider
-     * values set to defaults.
+     * Create a new slider with the caption given as parameter.
+     * 
+     * The range of the slider is set to 0-100 and only integer values are
+     * allowed.
      * 
      * @param caption
-     *            The caption for this Slider (e.g. "Volume").
+     *            The caption for this slider (e.g. "Volume").
      */
     public Slider(String caption) {
         this();
@@ -132,11 +133,14 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Create a new slider with given range and resolution
+     * Create a new slider with the given range and resolution.
      * 
      * @param min
+     *            The minimum value of the slider
      * @param max
+     *            The maximum value of the slider
      * @param resolution
+     *            The number of digits after the decimal point.
      */
     public Slider(double min, double max, int resolution) {
         this();
@@ -146,10 +150,12 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Create a new slider with given range
+     * Create a new slider with the given range that only allows integer values.
      * 
      * @param min
+     *            The minimum value of the slider
      * @param max
+     *            The maximum value of the slider
      */
     public Slider(int min, int max) {
         this();
@@ -159,11 +165,15 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Create a new slider with given caption and range
+     * Create a new slider with the given caption and range that only allows
+     * integer values.
      * 
      * @param caption
+     *            The caption for the slider
      * @param min
+     *            The minimum value of the slider
      * @param max
+     *            The maximum value of the slider
      */
     public Slider(String caption, int min, int max) {
         this(min, max);
@@ -171,20 +181,20 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Gets the biggest possible value in Sliders range.
+     * Gets the maximum slider value
      * 
-     * @return the biggest value slider can have
+     * @return the largest value the slider can have
      */
     public double getMax() {
         return max;
     }
 
     /**
-     * Set the maximum value of the Slider. If the current value of the Slider
-     * is out of new bounds, the value is set to new minimum.
+     * Set the maximum slider value. If the current value of the slider is
+     * larger than this, the value is set to the new maximum.
      * 
      * @param max
-     *            New maximum value of the Slider.
+     *            The new maximum slider value
      */
     public void setMax(double max) {
         this.max = max;
@@ -204,20 +214,20 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Gets the minimum value in Sliders range.
+     * Gets the minimum slider value
      * 
-     * @return the smalles value slider can have
+     * @return the smallest value the slider can have
      */
     public double getMin() {
         return min;
     }
 
     /**
-     * Set the minimum value of the Slider. If the current value of the Slider
-     * is out of new bounds, the value is set to new minimum.
+     * Set the minimum slider value. If the current value of the slider is
+     * smaller than this, the value is set to the new minimum.
      * 
-     * @param min
-     *            New minimum value of the Slider.
+     * @param max
+     *            The new minimum slider value
      */
     public void setMin(double min) {
         this.min = min;
@@ -237,18 +247,21 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Get the current orientation of the Slider (horizontal or vertical).
+     * Get the current orientation of the slider (horizontal or vertical).
      * 
-     * @return orientation
+     * @return {@link #ORIENTATION_HORIZONTAL} or
+     *         {@link #ORIENTATION_HORIZONTAL}
      */
     public int getOrientation() {
         return orientation;
     }
 
     /**
-     * Set the orientation of the Slider.
+     * Set the orientation of the slider.
      * 
-     * @param int new orientation
+     * @param The
+     *            new orientation, either {@link #ORIENTATION_HORIZONTAL} or
+     *            {@link #ORIENTATION_VERTICAL}
      */
     public void setOrientation(int orientation) {
         this.orientation = orientation;
@@ -256,7 +269,8 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Get the current resolution of the Slider.
+     * Get the current resolution of the slider. The resolution is the number of
+     * digits after the decimal point.
      * 
      * @return resolution
      */
@@ -265,7 +279,8 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Set a new resolution for the Slider.
+     * Set a new resolution for the slider. The resolution is the number of
+     * digits after the decimal point.
      * 
      * @param resolution
      */
@@ -278,14 +293,15 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Set the value of this Slider.
+     * Sets the value of the slider.
      * 
      * @param value
-     *            New value of Slider. Must be within Sliders range (min - max),
-     *            otherwise throws an exception.
+     *            The new value of the slider.
      * @param repaintIsNotNeeded
      *            If true, client-side is not requested to repaint itself.
      * @throws ValueOutOfBoundsException
+     *             If the given value is not inside the range of the slider.
+     * @see #setMin(double) {@link #setMax(double)}
      */
     public void setValue(Double value, boolean repaintIsNotNeeded)
             throws ValueOutOfBoundsException {
@@ -308,31 +324,33 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Set the value of this Slider.
+     * Sets the value of the slider.
      * 
      * @param value
-     *            New value of Slider. Must be within Sliders range (min - max),
-     *            otherwise throws an exception.
+     *            The new value of the slider.
      * @throws ValueOutOfBoundsException
+     *             If the given value is not inside the range of the slider.
+     * @see #setMin(double) {@link #setMax(double)}
      */
     public void setValue(Double value) throws ValueOutOfBoundsException {
         setValue(value, false);
     }
 
     /**
-     * Set the value of this Slider.
+     * Sets the value of the slider.
      * 
      * @param value
-     *            New value of Slider. Must be within Sliders range (min - max),
-     *            otherwise throws an exception.
+     *            The new value of the slider.
      * @throws ValueOutOfBoundsException
+     *             If the given value is not inside the range of the slider.
+     * @see #setMin(double) {@link #setMax(double)}
      */
     public void setValue(double value) throws ValueOutOfBoundsException {
         setValue(new Double(value), false);
     }
 
     /**
-     * Get the current Slider size.
+     * Get the current slider size.
      * 
      * @return size in pixels or -1 for auto sizing.
      * @deprecated use standard getWidth/getHeight instead
@@ -343,7 +361,7 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Set the size for this Slider.
+     * Set the size for this slider.
      * 
      * @param size
      *            in pixels, or -1 auto sizing.
@@ -364,7 +382,7 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Get the handle size of this Slider.
+     * Get the handle size of this slider.
      * 
      * @return handle size in percentages.
      * @deprecated The size is dictated by the current theme.
@@ -375,7 +393,7 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * Set the handle size of this Slider.
+     * Set the handle size of this slider.
      * 
      * @param handleSize
      *            in percentages relative to slider base size.
@@ -467,7 +485,8 @@ public class Slider extends AbstractField {
     }
 
     /**
-     * ValueOutOfBoundsException
+     * Thrown when the value of the slider is about to be set to a value that is
+     * outside the valid range of the slider.
      * 
      * @author IT Mill Ltd.
      * 
@@ -486,6 +505,11 @@ public class Slider extends AbstractField {
             value = valueOutOfBounds;
         }
 
+        /**
+         * Gets the value that is outside the valid range of the slider.
+         * 
+         * @return the value that is out of bounds
+         */
         public Double getValue() {
             return value;
         }
index cd07465d076fbd948653f3bd5549ce9c7a825566..26a56a8f4d65d16cef7a2d757b5832b6d17fc82c 100644 (file)
@@ -4013,6 +4013,9 @@ public class Table extends AbstractSelect implements Action.Container,
      */
     public void setTableFieldFactory(TableFieldFactory fieldFactory) {
         this.fieldFactory = fieldFactory;
+
+        // Assure visual refresh
+        refreshRowCache();
     }
 
     /**
index ddd1f6fc3bece77031e7a98fc44a40a23f62873c..d8d23b8b477b45ece3be864625fc59f03fd80428 100644 (file)
@@ -1281,8 +1281,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler,
      * user closes the window.
      * 
      * <p>
-     * Since Vaadin 6.5, removing windows using {@link #removeWindow(Window)}
-     * does fire the CloseListener.
+     * Since Vaadin 6.5, removing a window using {@link #removeWindow(Window)}
+     * fires the CloseListener.
      * </p>
      */
     public interface CloseListener extends Serializable {
diff --git a/tests/testbench/com/vaadin/tests/components/table/AddNonRenderedRow.java b/tests/testbench/com/vaadin/tests/components/table/AddNonRenderedRow.java
new file mode 100644 (file)
index 0000000..5486d62
--- /dev/null
@@ -0,0 +1,48 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Table;
+
+public class AddNonRenderedRow extends TestBase {
+    int index = 0;
+
+    private final Table table = new Table();
+
+    @Override
+    public void setup() {
+
+        table.setPageLength(5);
+        table.addContainerProperty("rowID", Integer.class, null);
+        for (int i = 0; i < 4; i++) {
+            addRow();
+        }
+
+        Button addrowButton = new Button("Add row");
+        addrowButton.addListener(new ClickListener() {
+            public void buttonClick(ClickEvent pEvent) {
+                addRow();
+            }
+        });
+
+        addComponent(table);
+        addComponent(addrowButton);
+    }
+
+    private void addRow() {
+        table.addItem(new Object[] { Integer.valueOf(++index) }, null);
+        // table.refreshRowCache();
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Adding a row to the table should work even when the added rows are not visible.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return Integer.valueOf(8077);
+    }
+}
\ No newline at end of file
diff --git a/tests/testbench/com/vaadin/tests/components/table/ProgrammaticUnselectInRange.html b/tests/testbench/com/vaadin/tests/components/table/ProgrammaticUnselectInRange.html
new file mode 100644 (file)
index 0000000..8d185b6
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.table.ProgrammaticUnselectInRange?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>23,5</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>24,3:shift</td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VLabel[0]</td>
+       <td>Item 2 is selected</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VLabel[0]</td>
+       <td>Item 2 is not selected</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[4]/domChild[0]/domChild[0]</td>
+       <td>32,8:ctrl</td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentstableProgrammaticUnselectInRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VLabel[0]</td>
+       <td>Item 2 is not selected</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/table/ProgrammaticUnselectInRange.java b/tests/testbench/com/vaadin/tests/components/table/ProgrammaticUnselectInRange.java
new file mode 100644 (file)
index 0000000..758fa4b
--- /dev/null
@@ -0,0 +1,67 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+
+public class ProgrammaticUnselectInRange extends TestBase {
+
+    private static final String PROPERTY = "property";
+
+    final Label selectionLabel = new Label();
+    final Table table = new Table();
+
+    @Override
+    protected void setup() {
+        table.addContainerProperty(PROPERTY, Integer.class, "");
+
+        table.setMultiSelect(true);
+        table.setSelectable(true);
+        table.setImmediate(true);
+        table.setPageLength(5);
+
+        for (int i = 0; i < 5; i++) {
+            Integer value = Integer.valueOf(i + 1);
+            table.addItem(new Object[] { value }, value);
+        }
+        table.addListener(new Property.ValueChangeListener() {
+            public void valueChange(ValueChangeEvent event) {
+                updateSelectionLabel();
+            }
+        });
+
+        addComponent(table);
+        addComponent(selectionLabel);
+        addComponent(new Button("Deselect item 2", new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                table.unselect(Integer.valueOf(2));
+            }
+        }));
+
+        updateSelectionLabel();
+    }
+
+    private void updateSelectionLabel() {
+        if (table.isSelected(Integer.valueOf(2))) {
+            selectionLabel.setValue("Item 2 is selected");
+        } else {
+            selectionLabel.setValue("Item 2 is not selected");
+        }
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Selecting items 1 - 3 using shift click, deselecting item 2 using the button and selecting item 5 using ctrl should keep item 2 deselected according to the server";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.html b/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.html
new file mode 100644 (file)
index 0000000..83a02ec
--- /dev/null
@@ -0,0 +1,362 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>TableClickValueChangeInteraction</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">TableClickValueChangeInteraction</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.table.TableClickValueChangeInteraction?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>38,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>35,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>24,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>39,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>37,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>51,16</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[6]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>19,10</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[7]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>43,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[8]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>36,7</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[9]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>27,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[10]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>13,7</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[11]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>43,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[12]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>27,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[13]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>53,16</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[14]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>40,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[15]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>45,10</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>ClickedItem0</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>39,7</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>37,6</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>33,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>17,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>49,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>53,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[6]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>21,12</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[7]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>32,13</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[8]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>45,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[9]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>22,10</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[10]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>28,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[11]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>15,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[12]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>35,5</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[13]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>26,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[14]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>55,13</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[15]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>22,7</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>ClickedItem1</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>41,12</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>28,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>16,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>38,12</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>47,6</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>30,7</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[6]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>16,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[7]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>68,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[8]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>36,10</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[9]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>48,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[10]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>27,12</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[11]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>19,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[12]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>22,10</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[13]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>39,13</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[14]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>35,15</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[15]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
+       <td>19,15</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>ClickedItem1Again</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>30,8</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>20,13</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>19,15</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>43,15</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>44,15</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[5]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>62,12</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[6]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>29,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[7]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>25,13</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[8]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>22,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[9]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>30,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[10]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>21,6</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[11]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>32,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[12]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>34,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[13]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>45,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[14]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>31,6</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableClickValueChangeInteraction::/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[15]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>45,10</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>ClickedItem2</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java b/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java
new file mode 100644 (file)
index 0000000..e0449de
--- /dev/null
@@ -0,0 +1,86 @@
+package com.vaadin.tests.components.table;\r
+\r
+import com.vaadin.data.Property.ValueChangeEvent;\r
+import com.vaadin.data.Property.ValueChangeListener;\r
+import com.vaadin.event.ItemClickEvent;\r
+import com.vaadin.event.ItemClickEvent.ItemClickListener;\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.Component;\r
+import com.vaadin.ui.GridLayout;\r
+import com.vaadin.ui.Label;\r
+import com.vaadin.ui.Layout;\r
+import com.vaadin.ui.Table;\r
+import com.vaadin.ui.VerticalLayout;\r
+import com.vaadin.ui.Window;\r
+\r
+public class TableClickValueChangeInteraction extends TestBase {\r
+\r
+    final Window mainWindow = new Window();\r
+\r
+    @Override\r
+    public void setup() {\r
+        setMainWindow(mainWindow);\r
+\r
+        GridLayout layout = new GridLayout(4, 4);\r
+        layout.setSpacing(true);\r
+        layout.setMargin(true);\r
+        mainWindow.setContent(layout);\r
+\r
+        for (int i = 0; i < 16; ++i) {\r
+            mainWindow.addComponent(makeTable((i & 8) > 0, (i & 4) > 0,\r
+                    (i & 2) > 0, (i & 1) > 0));\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "Table selection breaks if ItemClickListener requests repaint";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 7127;\r
+    }\r
+\r
+    private Component makeTable(boolean immediate, boolean selectable,\r
+            boolean listenClicks, boolean listenValueChanges) {\r
+\r
+        final Table table = new Table((immediate ? "I" : "i")\r
+                + (selectable ? "S" : "s") + (listenClicks ? "C" : "c")\r
+                + (listenValueChanges ? "V" : "v"));\r
+        final Label clickLabel = new Label("Click?");\r
+        final Label valueChangeLabel = new Label("Value?");\r
+\r
+        table.addContainerProperty("foo", String.class, null);\r
+        for (int i = 0; i < 3; i++) {\r
+            table.addItem("item" + i).getItemProperty("foo")\r
+                    .setValue("An item " + i);\r
+        }\r
+        table.setImmediate(immediate);\r
+        table.setSelectable(selectable);\r
+        table.setWidth("100px");\r
+        table.setHeight("100px");\r
+        if (listenClicks) {\r
+            table.addListener(new ItemClickListener() {\r
+                public void itemClick(ItemClickEvent event) {\r
+                    table.requestRepaint();\r
+                    clickLabel.setValue("Click " + event.getItemId());\r
+                }\r
+            });\r
+        }\r
+        if (listenValueChanges) {\r
+            table.addListener(new ValueChangeListener() {\r
+                public void valueChange(ValueChangeEvent event) {\r
+                    valueChangeLabel.setValue("Value " + event.getProperty());\r
+                }\r
+            });\r
+        }\r
+\r
+        Layout result = new VerticalLayout();\r
+        result.addComponent(table);\r
+        result.addComponent(clickLabel);\r
+        result.addComponent(valueChangeLabel);\r
+        return result;\r
+    }\r
+}
\ No newline at end of file
diff --git a/tests/testbench/com/vaadin/tests/components/textfield/MultipleTextChangeEvents.java b/tests/testbench/com/vaadin/tests/components/textfield/MultipleTextChangeEvents.java
new file mode 100644 (file)
index 0000000..62d3a16
--- /dev/null
@@ -0,0 +1,57 @@
+package com.vaadin.tests.components.textfield;
+
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.Log;
+import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
+import com.vaadin.ui.TextField;
+
+public class MultipleTextChangeEvents extends TestBase {
+
+    private final Log log = new Log(5);
+
+    @Override
+    public void setup() {
+        TextField tf = new TextField();
+        tf.setTextChangeEventMode(TextChangeEventMode.TIMEOUT);
+        tf.setTextChangeTimeout(500);
+        tf.addListener(new TextChangeListener() {
+            public void textChange(TextChangeEvent event) {
+                log.log("TextChangeEvent: " + event.getText());
+            }
+        });
+        getMainWindow().addActionHandler(new MyHandler());
+
+        addComponent(log);
+        addComponent(tf);
+    }
+
+    class MyHandler implements Handler {
+        private static final long serialVersionUID = 1L;
+        Action actionenter = new ShortcutAction("Enter",
+                ShortcutAction.KeyCode.ENTER, null);
+
+        public Action[] getActions(Object theTarget, Object theSender) {
+            return new Action[] { actionenter };
+        }
+
+        public void handleAction(Action theAction, Object theSender,
+                Object theTarget) {
+            log.log("Enter");
+        }
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Entering something into the textfield and quickly pressing enter should only send one TextChangeEvent";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return Integer.valueOf(8035);
+    }
+}
\ No newline at end of file
diff --git a/tests/testbench/com/vaadin/tests/components/treetable/AddNodesOnExpand.html b/tests/testbench/com/vaadin/tests/components/treetable/AddNodesOnExpand.html
new file mode 100644 (file)
index 0000000..efcbded
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.treetable.AddNodesOnExpand?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstreetableAddNodesOnExpand::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>11,7</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentstreetableAddNodesOnExpand::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>11,7</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>collapsed</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/treetable/AddNodesOnExpand.java b/tests/testbench/com/vaadin/tests/components/treetable/AddNodesOnExpand.java
new file mode 100644 (file)
index 0000000..5bf0370
--- /dev/null
@@ -0,0 +1,55 @@
+package com.vaadin.tests.components.treetable;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.Tree.CollapseEvent;
+import com.vaadin.ui.Tree.ExpandEvent;
+import com.vaadin.ui.TreeTable;
+
+public class AddNodesOnExpand extends TestBase {
+    private TreeTable treetable;
+
+    @Override
+    public void setup() {
+        treetable = new TreeTable();
+        treetable.setImmediate(true);
+        treetable.setWidth("100%");
+        treetable.setHeight(null);
+        treetable.setPageLength(0);
+        treetable.addContainerProperty("foo", String.class, "");
+        treetable.addListener(new Tree.ExpandListener() {
+            public void nodeExpand(ExpandEvent event) {
+                Object openedItemId = event.getItemId();
+                if (!treetable.hasChildren(openedItemId)) {
+                    for (int j = 0; j < 3; j++) {
+                        treetable.addItem(openedItemId + "-" + j);
+                        treetable.setParent(openedItemId + "-" + j,
+                                openedItemId);
+                    }
+                }
+            }
+        });
+        treetable.addListener(new Tree.CollapseListener() {
+            public void nodeCollapse(CollapseEvent event) {
+                /* Uncomment this to "fix" the TreeTable */
+                // orgTree.refreshRowCache();
+            }
+        });
+
+        for (int i = 0; i < 3; i++) {
+            treetable.addItem(Integer.valueOf(i));
+        }
+
+        addComponent(treetable);
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Expanding a node and then collapsing it should not cause scrollbars to appear";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return Integer.valueOf(8041);
+    }
+}
\ No newline at end of file