]> source.dussan.org Git - vaadin-framework.git/commitdiff
merged table related bugfixes from 6.5 branch by hand
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 19 Apr 2011 15:48:28 +0000 (15:48 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 19 Apr 2011 15:48:28 +0000 (15:48 +0000)
svn changeset:18399/svn branch:6.6

src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java
src/com/vaadin/terminal/gwt/client/ui/SimpleFocusablePanel.java
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
tests/src/com/vaadin/tests/components/table/TableScrollsOnSelection.java

index cebdf1063f7b4c37787d7a59fb806328342a1ee6..24a98ee3efc55b8382c13c943e2abdfe1c442e4b 100644 (file)
@@ -1,20 +1,31 @@
 package com.vaadin.terminal.gwt.client.ui;
 
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Style;
 import com.google.gwt.dom.client.Style.Overflow;
 import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.event.dom.client.HasScrollHandlers;
 import com.google.gwt.event.dom.client.ScrollEvent;
 import com.google.gwt.event.dom.client.ScrollHandler;
 import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.ScrollPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.impl.FocusImpl;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
 
 /**
  * A scrollhandlers similar to {@link ScrollPanel}.
  * 
  */
 public class FocusableScrollPanel extends SimpleFocusablePanel implements
-        HasScrollHandlers {
+        HasScrollHandlers, ScrollHandler {
 
     public FocusableScrollPanel() {
         // Prevent IE standard mode bug when a AbsolutePanel is contained.
@@ -24,6 +35,85 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements
         style.setPosition(Position.RELATIVE);
     }
 
+    private DivElement focusElement;
+
+    public FocusableScrollPanel(boolean useFakeFocusElement) {
+        this();
+        if (useFakeFocusElement) {
+            focusElement = Document.get().createDivElement();
+        }
+    }
+
+    private boolean useFakeFocusElement() {
+        return focusElement != null;
+    }
+
+    @Override
+    public void setWidget(Widget w) {
+        super.setWidget(w);
+        if (useFakeFocusElement()) {
+            if (focusElement.getParentElement() == null) {
+                Style style = focusElement.getStyle();
+                if (BrowserInfo.get().isIE6()) {
+                    style.setOverflow(Overflow.HIDDEN);
+                    style.setHeight(0, Unit.PX);
+                    style.setWidth(0, Unit.PX);
+                    style.setPosition(Position.ABSOLUTE);
+
+                    addScrollHandler(this);
+                } else {
+                    style.setPosition(Position.FIXED);
+                    style.setTop(0, Unit.PX);
+                    style.setLeft(0, Unit.PX);
+                }
+                getElement().appendChild(focusElement);
+                /* Sink from focusElemet too as focusa and blur don't bubble */
+                DOM.sinkEvents(
+                        (com.google.gwt.user.client.Element) focusElement
+                                .cast(), Event.FOCUSEVENTS);
+                // revert to original, not focusable
+                getElement().setPropertyObject("tabIndex", null);
+
+            } else {
+                moveFocusElementAfterWidget();
+            }
+        }
+    }
+
+    /**
+     * Helper to keep focus element always in domChild[1]. Aids testing.
+     */
+    private void moveFocusElementAfterWidget() {
+        getElement().insertAfter(focusElement, getWidget().getElement());
+    }
+
+    @Override
+    public void setFocus(boolean focus) {
+        if (useFakeFocusElement()) {
+            if (focus) {
+                FocusImpl.getFocusImplForPanel().focus(
+                        (Element) focusElement.cast());
+            } else {
+                FocusImpl.getFocusImplForPanel().blur(
+                        (Element) focusElement.cast());
+            }
+        } else {
+            super.setFocus(focus);
+        }
+    }
+
+    @Override
+    public void setTabIndex(int tabIndex) {
+        if (useFakeFocusElement()) {
+            getElement().setTabIndex(-1);
+            if (focusElement != null) {
+                focusElement.setTabIndex(tabIndex);
+            }
+        } else {
+            super.setTabIndex(tabIndex);
+        }
+    }
+
     public HandlerRegistration addScrollHandler(ScrollHandler handler) {
         return addDomHandler(handler, ScrollEvent.getType());
     }
@@ -66,4 +156,14 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements
         getElement().setScrollTop(position);
     }
 
+    public void onScroll(ScrollEvent event) {
+        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+            public void execute() {
+                focusElement.getStyle().setTop(getScrollPosition(), Unit.PX);
+                focusElement.getStyle().setLeft(getHorizontalScrollPosition(),
+                        Unit.PX);
+            }
+        });
+    }
+
 }
index 8511df2196ce11c6ea8fe93d7513cfcea14107a6..25c10ae1bb41234367484af36b5c5a2436b1f8f6 100644 (file)
@@ -30,7 +30,7 @@ public class SimpleFocusablePanel extends SimplePanel implements
     public SimpleFocusablePanel() {
         // make focusable, as we don't need access key magic we don't need to
         // use FocusImpl.createFocusable
-        getElement().setTabIndex(0);
+        setTabIndex(0);
     }
 
     public HandlerRegistration addFocusHandler(FocusHandler handler) {
@@ -64,4 +64,8 @@ public class SimpleFocusablePanel extends SimplePanel implements
     public void focus() {
         setFocus(true);
     }
+
+    public void setTabIndex(int tabIndex) {
+        getElement().setTabIndex(tabIndex);
+    }
 }
index 3e31f08b3daddf84c3f9f25d113a2b9718cb56c6..e544c7abf6b8214e2b0e57af66801c3a8d851139 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Set;
 
 import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.dom.client.NodeList;
@@ -97,8 +98,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
  * TODO implement unregistering for child components in Cells
  */
 public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
-        VHasDropHandler, KeyPressHandler, KeyDownHandler, FocusHandler,
-        BlurHandler, Focusable, KeyUpHandler {
+        VHasDropHandler, FocusHandler, BlurHandler, Focusable {
 
     public static final String CLASSNAME = "v-table";
     public static final String CLASSNAME_SELECTION_FOCUS = CLASSNAME + "-focus";
@@ -278,8 +278,96 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
     private final TableFooter tFoot = new TableFooter();
 
-    private final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel();
+    private final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(
+            true);
 
+    private KeyPressHandler navKeyPressHandler = new KeyPressHandler() {
+        public void onKeyPress(KeyPressEvent keyPressEvent) {
+            // This is used for Firefox only, since Firefox auto-repeat
+            // works correctly only if we use a key press handler, other
+            // browsers handle it correctly when using a key down handler
+            if (!BrowserInfo.get().isGecko()) {
+                return;
+            }
+
+            NativeEvent event = keyPressEvent.getNativeEvent();
+            if (!enabled) {
+                // Cancel default keyboard events on a disabled Table
+                // (prevents scrolling)
+                event.preventDefault();
+            } else if (hasFocus) {
+                // Key code in Firefox/onKeyPress is present only for
+                // special keys, otherwise 0 is returned
+                int keyCode = event.getKeyCode();
+                if (keyCode == 0 && event.getCharCode() == ' ') {
+                    // Provide a keyCode for space to be compatible with
+                    // FireFox keypress event
+                    keyCode = CHARCODE_SPACE;
+                }
+
+                if (handleNavigation(keyCode,
+                        event.getCtrlKey() || event.getMetaKey(),
+                        event.getShiftKey())) {
+                    event.preventDefault();
+                }
+
+                startScrollingVelocityTimer();
+            }
+        }
+
+    };
+
+    private KeyUpHandler navKeyUpHandler = new KeyUpHandler() {
+
+        public void onKeyUp(KeyUpEvent keyUpEvent) {
+            NativeEvent event = keyUpEvent.getNativeEvent();
+            int keyCode = event.getKeyCode();
+
+            if (!isFocusable()) {
+                cancelScrollingVelocityTimer();
+            } else if (isNavigationKey(keyCode)) {
+                if (keyCode == getNavigationDownKey()
+                        || keyCode == getNavigationUpKey()) {
+                    /*
+                     * in multiselect mode the server may still have value from
+                     * previous page. Clear it unless doing multiselection or
+                     * just moving focus.
+                     */
+                    if (!event.getShiftKey() && !event.getCtrlKey()) {
+                        instructServerToForgetPreviousSelections();
+                    }
+                    sendSelectedRows();
+                }
+                cancelScrollingVelocityTimer();
+                navKeyDown = false;
+            }
+        }
+    };
+
+    private KeyDownHandler navKeyDownHandler = new KeyDownHandler() {
+
+        public void onKeyDown(KeyDownEvent keyDownEvent) {
+            NativeEvent event = keyDownEvent.getNativeEvent();
+            // This is not used for Firefox
+            if (BrowserInfo.get().isGecko()) {
+                return;
+            }
+
+            if (!enabled) {
+                // Cancel default keyboard events on a disabled Table
+                // (prevents scrolling)
+                event.preventDefault();
+            } else if (hasFocus) {
+                if (handleNavigation(event.getKeyCode(), event.getCtrlKey()
+                        || event.getMetaKey(), event.getShiftKey())) {
+                    navKeyDown = true;
+                    event.preventDefault();
+                }
+
+                startScrollingVelocityTimer();
+            }
+        }
+    };
     private int totalRows;
 
     private Set<String> collapsedColumns;
@@ -326,6 +414,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
     public VScrollTable() {
         scrollBodyPanel.setStyleName(CLASSNAME + "-body-wrapper");
+        scrollBodyPanel.addFocusHandler(this);
+        scrollBodyPanel.addBlurHandler(this);
+
+        scrollBodyPanel.addScrollHandler(this);
+        scrollBodyPanel.setStyleName(CLASSNAME + "-body");
 
         /*
          * Firefox auto-repeat works correctly only if we use a key press
@@ -333,16 +426,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
          * handler
          */
         if (BrowserInfo.get().isGecko()) {
-            scrollBodyPanel.addKeyPressHandler(this);
+            scrollBodyPanel.addKeyPressHandler(navKeyPressHandler);
         } else {
-            scrollBodyPanel.addKeyDownHandler(this);
+            scrollBodyPanel.addKeyDownHandler(navKeyDownHandler);
         }
-        scrollBodyPanel.addKeyUpHandler(this);
-
-        scrollBodyPanel.addFocusHandler(this);
-        scrollBodyPanel.addBlurHandler(this);
-
-        scrollBodyPanel.addScrollHandler(this);
+        scrollBodyPanel.addKeyUpHandler(navKeyUpHandler);
 
         scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS);
         scrollBodyPanel.addDomHandler(new TouchStartHandler() {
@@ -351,8 +439,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             }
         }, TouchStartEvent.getType());
 
-        scrollBodyPanel.setStyleName(CLASSNAME + "-body");
-
         setStyleName(CLASSNAME);
 
         add(tHead);
@@ -903,17 +989,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
         if (focusedRow != null) {
             if (!focusedRow.isAttached()) {
-                // focused row has orphaned, can't focus
-                focusedRow = null;
-                if (SELECT_MODE_SINGLE == selectMode
-                        && selectedRowKeys.size() > 0) {
-                    // try to focusa row currently selected and in viewport
-                    String selectedRowKey = selectedRowKeys.iterator().next();
-                    if (selectedRowKey != null) {
-                        setRowFocus(getRenderedRowByKey(selectedRowKey));
-                    }
-                }
-                // TODO what should happen in multiselect mode?
+                // focused row has been orphaned, can't focus
+                focusRowFromBody();
             }
         }
 
@@ -937,6 +1014,24 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
     }
 
+    private void focusRowFromBody() {
+        if (selectedRowKeys.size() == 1) {
+            // try to focus a row currently selected and in viewport
+            String selectedRowKey = selectedRowKeys.iterator().next();
+            if (selectedRowKey != null) {
+                VScrollTableRow renderedRow = getRenderedRowByKey(selectedRowKey);
+                if (renderedRow == null || !renderedRow.isInViewPort()) {
+                    setRowFocus(scrollBody.getRowByRowIndex(firstRowInViewPort));
+                } else {
+                    setRowFocus(renderedRow);
+                }
+            }
+        } else {
+            // multiselect mode
+            setRowFocus(scrollBody.getRowByRowIndex(firstRowInViewPort));
+        }
+    }
+
     protected VScrollTableBody createScrollBody() {
         return new VScrollTableBody();
     }
@@ -2595,11 +2690,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
             String colKey;
             private boolean collapsed;
+            private VScrollTableRow currentlyFocusedRow;
 
             public VisibleColumnAction(String colKey) {
                 super(VScrollTable.TableHead.this);
                 this.colKey = colKey;
                 caption = tHead.getHeaderCell(colKey).getCaption();
+                currentlyFocusedRow = focusedRow;
             }
 
             @Override
@@ -2620,6 +2717,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                                 .size()]), false);
                 // let rowRequestHandler determine proper rows
                 rowRequestHandler.refreshContent();
+                lazyRevertFocusToRow(currentlyFocusedRow);
             }
 
             public void setCollapsed(boolean b) {
@@ -3772,7 +3870,26 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 setElement(rowElement);
                 DOM.sinkEvents(getElement(), Event.MOUSEEVENTS
                         | Event.TOUCHEVENTS | Event.ONDBLCLICK
-                        | Event.ONCONTEXTMENU | Event.ONKEYDOWN);
+                        | Event.ONCONTEXTMENU);
+            }
+
+            /**
+             * Detects whether row is visible in tables viewport.
+             * 
+             * @return
+             */
+            public boolean isInViewPort() {
+                int absoluteTop = getAbsoluteTop();
+                int scrollPosition = scrollBodyPanel.getScrollPosition();
+                if (absoluteTop < scrollPosition) {
+                    return false;
+                }
+                int maxVisible = scrollPosition
+                        + scrollBodyPanel.getOffsetHeight() - getOffsetHeight();
+                if (absoluteTop > maxVisible) {
+                    return false;
+                }
+                return true;
             }
 
             /**
@@ -4077,7 +4194,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                         if (targetCellOrRowFound) {
                             mDown = false;
                             handleClickEvent(event, targetTdOrTr);
-                            scrollBodyPanel.setFocus(true);
                             if (event.getButton() == Event.BUTTON_LEFT
                                     && isSelectable()) {
 
@@ -4256,6 +4372,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     case Event.ONMOUSEDOWN:
                         if (targetCellOrRowFound) {
                             setRowFocus(this);
+                            ensureFocus();
                             if (dragmode != 0
                                     && (event.getButton() == NativeEvent.BUTTON_LEFT)) {
                                 startRowDrag(event, type, targetTdOrTr);
@@ -4265,10 +4382,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                                     && selectMode == SELECT_MODE_MULTI
                                     && multiselectmode == MULTISELECT_MODE_DEFAULT) {
 
-                                // because we are preventing the default (due to
-                                // prevent text selection) we must ensure
-                                // gaining the focus.
-                                ensureFocus();
                                 // Prevent default text selection in Firefox
                                 event.preventDefault();
 
@@ -4351,10 +4464,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 } else {
                     ev.createDragImage(getElement(), true);
                 }
-                // because we are preventing the default (due to
-                // prevent text selection) we must ensure
-                // gaining the focus.
-                ensureFocus();
                 if (type == Event.ONMOUSEDOWN) {
                     event.preventDefault();
                 }
@@ -4535,7 +4644,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 for (int i = 0; i < actions.length; i++) {
                     final String actionKey = actionKeys[i];
                     final TreeAction a = new TreeAction(this,
-                            String.valueOf(rowKey), actionKey);
+                            String.valueOf(rowKey), actionKey) {
+                        @Override
+                        public void execute() {
+                            super.execute();
+                            lazyRevertFocusToRow(VScrollTableRow.this);
+                        }
+                    };
                     a.setCaption(getActionCaption(actionKey));
                     a.setIconUrl(getActionIcon(actionKey));
                     actions[i] = a;
@@ -4629,7 +4744,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
          * focus only if not currently focused.
          */
         protected void ensureFocus() {
-            focus();
+            if (!hasFocus) {
+                scrollBodyPanel.setFocus(true);
+            }
         }
     }
 
@@ -4648,14 +4765,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         selectedRowRanges.clear();
         // also notify server that it clears all previous selections (the client
         // side does not know about the invisible ones)
-        instructServerToForgotPreviousSelections();
+        instructServerToForgetPreviousSelections();
     }
 
     /**
      * Used in multiselect mode when the client side knows that all selections
      * are in the next request.
      */
-    private void instructServerToForgotPreviousSelections() {
+    private void instructServerToForgetPreviousSelections() {
         client.updateVariable(paintableId, "clearSelections", true, false);
     }
 
@@ -4831,6 +4948,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement());
                 }
             });
+
+            if (BrowserInfo.get().isIE()) {
+                /*
+                 * IE does not fire onscroll event if scroll position is
+                 * reverted to 0 due to the content element size growth. Ensure
+                 * headers are in sync with content manually. Safe to use null
+                 * event as we don't actually use the event object in listener.
+                 */
+                onScroll(null);
+            }
         }
     };
 
@@ -5261,7 +5388,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             // Apply focus style to new selection
             row.addStyleName(CLASSNAME_SELECTION_FOCUS);
 
-            // Trying to set focus on already focused row
+            /*
+             * Trying to set focus on already focused row
+             */
             if (row == focusedRow) {
                 return false;
             }
@@ -5582,86 +5711,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         scrollBodyPanel.setScrollPosition(newPixels);
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google
-     * .gwt.event.dom.client.KeyPressEvent)
-     */
-    public void onKeyPress(KeyPressEvent event) {
-        // This is used for Firefox only
-        if (!BrowserInfo.get().isGecko()) {
-            return;
-        }
-
-        if (!enabled) {
-            // Cancel default keyboard events on a disabled Table (prevents
-            // scrolling)
-            event.preventDefault();
-        } else if (hasFocus) {
-            // Key code in Firefox/onKeyPress is present only for special keys,
-            // otherwise 0 is returned
-            NativeEvent nativeEvent = event.getNativeEvent();
-            int keyCode = nativeEvent.getKeyCode();
-            if (keyCode == 0 && nativeEvent.getCharCode() == ' ') {
-                // Provide a keyCode for space to be compatible with FireFox
-                // keypress event
-                keyCode = CHARCODE_SPACE;
-            }
-
-            if (handleNavigation(keyCode,
-                    event.isControlKeyDown() || event.isMetaKeyDown(),
-                    event.isShiftKeyDown())) {
-                event.preventDefault();
-            }
-
-            // Start the velocityTimer
-            if (scrollingVelocityTimer == null) {
-                scrollingVelocityTimer = new Timer() {
-                    @Override
-                    public void run() {
-                        scrollingVelocity++;
-                    }
-                };
-                scrollingVelocityTimer.scheduleRepeating(100);
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
-     * .event.dom.client.KeyDownEvent)
-     */
-    public void onKeyDown(KeyDownEvent event) {
-        if (!enabled) {
-            // Cancel default keyboard events on a disabled Table (prevents
-            // scrolling)
-            event.preventDefault();
-        } else if (hasFocus) {
-            if (handleNavigation(event.getNativeEvent().getKeyCode(),
-                    event.isControlKeyDown() || event.isMetaKeyDown(),
-                    event.isShiftKeyDown())) {
-                navKeyDown = true;
-                event.preventDefault();
-            }
-
-            // Start the velocityTimer
-            if (scrollingVelocityTimer == null) {
-                scrollingVelocityTimer = new Timer() {
-                    @Override
-                    public void run() {
-                        scrollingVelocity++;
-                    }
-                };
-                scrollingVelocityTimer.scheduleRepeating(100);
-            }
-        }
-    }
-
     /*
      * (non-Javadoc)
      * 
@@ -5671,12 +5720,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      */
     public void onFocus(FocusEvent event) {
         if (isFocusable()) {
-            scrollBodyPanel.addStyleName("focused");
             hasFocus = true;
 
             // Focus a row if no row is in focus
             if (focusedRow == null) {
-                setRowFocus((VScrollTableRow) scrollBody.iterator().next());
+                focusRowFromBody();
             } else {
                 setRowFocus(focusedRow);
             }
@@ -5691,7 +5739,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * .dom.client.BlurEvent)
      */
     public void onBlur(BlurEvent event) {
-        scrollBodyPanel.removeStyleName("focused");
         hasFocus = false;
         navKeyDown = false;
 
@@ -5777,9 +5824,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
 
         if (tabIndex == 0 && !isFocusable()) {
-            scrollBodyPanel.getElement().setTabIndex(-1);
+            scrollBodyPanel.setTabIndex(-1);
         } else {
-            scrollBodyPanel.getElement().setTabIndex(tabIndex);
+            scrollBodyPanel.setTabIndex(tabIndex);
         }
 
         if (BrowserInfo.get().getOperaVersion() >= 11) {
@@ -5789,36 +5836,24 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
     }
 
-    public void onKeyUp(KeyUpEvent event) {
-        int keyCode = event.getNativeKeyCode();
-
-        if (!isFocusable()) {
-            if (scrollingVelocityTimer != null) {
-                // Remove velocityTimer if it exists and the Table is disabled
-                scrollingVelocityTimer.cancel();
-                scrollingVelocityTimer = null;
-                scrollingVelocity = 10;
-            }
-        } else if (isNavigationKey(keyCode)) {
-            if (keyCode == getNavigationDownKey()
-                    || keyCode == getNavigationUpKey()) {
-                /*
-                 * in multiselect mode the server may still have value from
-                 * previous page. Clear it unless doing multiselection or just
-                 * moving focus.
-                 */
-                if (!event.getNativeEvent().getShiftKey()
-                        && !event.getNativeEvent().getCtrlKey()) {
-                    instructServerToForgotPreviousSelections();
+    public void startScrollingVelocityTimer() {
+        if (scrollingVelocityTimer == null) {
+            scrollingVelocityTimer = new Timer() {
+                @Override
+                public void run() {
+                    scrollingVelocity++;
                 }
-                sendSelectedRows();
-            }
-            if (scrollingVelocityTimer != null) {
-                scrollingVelocityTimer.cancel();
-                scrollingVelocityTimer = null;
-                scrollingVelocity = 10;
-            }
-            navKeyDown = false;
+            };
+            scrollingVelocityTimer.scheduleRepeating(100);
+        }
+    }
+
+    public void cancelScrollingVelocityTimer() {
+        if (scrollingVelocityTimer != null) {
+            // Remove velocityTimer if it exists and the Table is disabled
+            scrollingVelocityTimer.cancel();
+            scrollingVelocityTimer = null;
+            scrollingVelocity = 10;
         }
     }
 
@@ -5837,4 +5872,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 || keyCode == getNavigationEndKey()
                 || keyCode == getNavigationStartKey();
     }
+
+    public void lazyRevertFocusToRow(final VScrollTableRow currentlyFocusedRow) {
+        Scheduler.get().scheduleFinally(new ScheduledCommand() {
+            public void execute() {
+                if (currentlyFocusedRow != null) {
+                    setRowFocus(currentlyFocusedRow);
+                } else {
+                    VConsole.log("no row?");
+                    focusRowFromBody();
+                }
+                scrollBody.ensureFocus();
+            }
+        });
+    }
 }
index 9d3aed00bb81d0ae51ec07d883ebc5ac57be737c..c76fe05d473d318c047e412470ae0e711109d15b 100644 (file)
@@ -4,14 +4,12 @@ import com.vaadin.data.Item;
 import com.vaadin.data.util.IndexedContainer;\r
 import com.vaadin.tests.components.TestBase;\r
 import com.vaadin.ui.Table;\r
-import com.vaadin.ui.Window;\r
 \r
 public class TableScrollsOnSelection extends TestBase {\r
 \r
     @Override\r
     protected void setup() {\r
-        Window mainWindow = new Window("Playground Application");\r
-        setMainWindow(mainWindow);\r
+        getMainWindow().getContent().setSizeUndefined();\r
 \r
         IndexedContainer cont = new IndexedContainer();\r
         cont.addContainerProperty("number", String.class, null);\r
@@ -23,7 +21,7 @@ public class TableScrollsOnSelection extends TestBase {
         table.setPageLength(0);\r
         table.setContainerDataSource(cont);\r
         table.setSelectable(true);\r
-        mainWindow.addComponent(table);\r
+        addComponent(table);\r
     }\r
 \r
     @Override\r