changeset 1241:0cbd6a3c74bb

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/2.2/MASTER/rt
author leifs
date Wed, 06 Jun 2012 13:26:28 -0700
parents 348de34f8273 a3977b2b77b5
children b14d29378d60
files
diffstat 19 files changed, 635 insertions(+), 330 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-common/src/javafx/scene/layout/GridPane.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/layout/GridPane.java	Wed Jun 06 13:26:28 2012 -0700
@@ -1589,27 +1589,47 @@
         }
 
         double available = extraHeight; // will be negative in shrinking case
-        while (Math.abs(available) > 1.0 && adjusting.size() > 0) {
-            final double portion = available / adjusting.size(); // negative in shrinking case
-            for (int i = 0; i < adjusting.size(); i++) {
-                final int index = adjusting.get(i);
-                final double limit = (shrinking? rowMinHeight[index] : rowMaxHeight[index])
-                        - rowHeights[index]; // negative in shrinking case
-                final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
-                //System.out.println("row "+index+": height="+rowHeights[index]+" extra="+extraHeight+"portion="+portion+" row mpm="+rowMinHeight[index]+"/"+rowPrefHeight[index]+"/"+rowMaxHeight[index]+" limit="+limit+" change="+change);
-                rowHeights[index] += change;
-                available -= change;
-                if (Math.abs(change) < Math.abs(portion)) {
-                    adjusted.add(index);
+        boolean handleRemainder = false;
+        int portion = 0;
+        while (available != 0 && adjusting.size() > 0) {
+            if (!handleRemainder) {
+                portion = (int)available / adjusting.size(); // negative in shrinking case
+            }
+            if (portion != 0) {
+                for (int i = 0; i < adjusting.size(); i++) {
+                    final int index = adjusting.get(i);
+                    final double limit = (shrinking? rowMinHeight[index] : rowMaxHeight[index])
+                            - rowHeights[index]; // negative in shrinking case
+                    final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
+                    //System.out.println("row "+index+": height="+rowHeights[index]+" extra="+extraHeight+"portion="+portion+" row mpm="+rowMinHeight[index]+"/"+rowPrefHeight[index]+"/"+rowMaxHeight[index]+" limit="+limit+" change="+change);
+                    rowHeights[index] += change;                
+                    available -= change;
+                    if (Math.abs(change) < Math.abs(portion)) {
+                        adjusted.add(index);
+                    }
+                    if (available == 0) {
+                        break;
+                    }
+                }
+                for (int i = 0; i < adjusted.size(); i++) {
+                    adjusting.remove(adjusted.get(i));
+                }
+                adjusted.clear();
+            } else {
+                // Handle the remainder
+                portion = (int)(available) % adjusting.size();
+                if (portion == 0) {
+                    break;
+                } else {
+                    // We have a remainder evenly distribute it.
+                    portion = shrinking ? -1 : 1;
+                    handleRemainder = true;
                 }
             }
-            for (int i = 0; i < adjusted.size(); i++) {
-                adjusting.remove(adjusted.get(i));
-            }
-            adjusted.clear();
         }
+                        
         for (int i = 0; i < rowHeights.length; i++) {
-            rowHeights[i] = snapSpace(rowHeights[i]);
+            rowHeights[i] = snapSpace(rowHeights[i]);            
         }
         return available; // might be negative in shrinking case
     }
@@ -1662,26 +1682,47 @@
                 adjusting.add(i);
             }
         }
+        
         double available = extraWidth; // will be negative in shrinking case
-        while (Math.abs(available) > 1.0 && adjusting.size() > 0) {            
-            final double portion = available / adjusting.size(); // negative in shrinking case
-            for (int i = 0; i < adjusting.size(); i++) {
-                final int index = adjusting.get(i);
-                final double limit = (shrinking? columnMinWidth[index] : columnMaxWidth[index])
-                        - columnWidths[index]; // negative in shrinking case
-                final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
-                columnWidths[index] += change;
-                //if (node.id.startsWith("debug.")) println("{if (shrinking) "vshrink" else "vgrow"}: {node.id} portion({portion})=available({available})/({sizeof adjusting}) change={change}");
-                available -= change;
-                if (Math.abs(change) < Math.abs(portion)) {
-                    adjusted.add(index);
+        boolean handleRemainder = false;
+        int portion = 0;
+        while (available != 0 && adjusting.size() > 0) {            
+            if (!handleRemainder) {
+                portion = (int)available / adjusting.size(); // negative in shrinking case
+            }
+            if (portion != 0) {
+                for (int i = 0; i < adjusting.size(); i++) {
+                    final int index = adjusting.get(i);
+                    final double limit = (shrinking? columnMinWidth[index] : columnMaxWidth[index])
+                            - columnWidths[index]; // negative in shrinking case
+                    final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
+                    columnWidths[index] += change;                
+                    //if (node.id.startsWith("debug.")) println("{if (shrinking) "vshrink" else "vgrow"}: {node.id} portion({portion})=available({available})/({sizeof adjusting}) change={change}");
+                    available -= change;
+                    if (Math.abs(change) < Math.abs(portion)) {
+                        adjusted.add(index);
+                    }
+                    if (available == 0) {                        
+                        break;
+                    }                    
+                }
+                for (int i = 0; i < adjusted.size(); i++) {
+                    adjusting.remove(adjusted.get(i));
+                }
+                adjusted.clear();
+            } else {
+                // Handle the remainder
+                portion = (int)(available) % adjusting.size();
+                if (portion == 0) {
+                    break;
+                } else {
+                    // We have a remainder evenly distribute it.
+                    portion = shrinking ? -1 : 1;
+                    handleRemainder = true;
                 }
             }
-            for (int i = 0; i < adjusted.size(); i++) {
-                adjusting.remove(adjusted.get(i));
-            }
-            adjusted.clear();
         }
+               
         for (int i = 0; i < columnWidths.length; i++) {
             columnWidths[i] = snapSpace(columnWidths[i]);
         }
--- a/javafx-ui-common/test/unit/javafx/scene/layout/GridPaneTest.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-common/test/unit/javafx/scene/layout/GridPaneTest.java	Wed Jun 06 13:26:28 2012 -0700
@@ -1782,7 +1782,7 @@
         assertEquals(100, child1_0.getLayoutBounds().getHeight(), 1e-100);
         assertEquals(366, child2_0.getLayoutX(), 1e-100);
         assertEquals(0, child2_0.getLayoutY(), 1e-100);
-        assertEquals(233, child2_0.getLayoutBounds().getWidth(), 1e-100);
+        assertEquals(234, child2_0.getLayoutBounds().getWidth(), 1e-100);
         assertEquals(129, child2_0.getLayoutBounds().getHeight(), 1e-100);
 
         assertEquals(0, child0_1.getLayoutX(), 1e-100);
@@ -1795,7 +1795,7 @@
         assertEquals(300, child1_1.getLayoutBounds().getHeight(), 1e-100);
         assertEquals(366, child2_1.getLayoutX(), 1e-100);
         assertEquals(129, child2_1.getLayoutY(), 1e-100);
-        assertEquals(233, child2_1.getLayoutBounds().getWidth(), 1e-100);
+        assertEquals(234, child2_1.getLayoutBounds().getWidth(), 1e-100);
         assertEquals(300, child2_1.getLayoutBounds().getHeight(), 1e-100);
     }
 
@@ -2239,4 +2239,69 @@
         assertEquals(100, cw[0], 1e-100);
         assertEquals(50, cw[1], 1e-100);
     }
+    
+    @Test public void test_RT20931_cellHeightTotalShouldEqualColumnHeight() {
+        ColumnConstraints c1 = new ColumnConstraints();
+        c1.setMinWidth(10);
+        c1.setHgrow(Priority.SOMETIMES);
+        
+        ColumnConstraints c2 = new ColumnConstraints();
+        c2.setMinWidth(10);
+        c2.setHgrow(Priority.SOMETIMES);
+                
+        RowConstraints r1 = new RowConstraints();
+        r1.setMinHeight(10);
+        r1.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r2 = new RowConstraints();
+        r2.setMinHeight(10);
+        r2.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r3 = new RowConstraints();
+        r3.setMinHeight(10);
+        r3.setVgrow(Priority.SOMETIMES);        
+        
+        gridpane.getColumnConstraints().addAll(c1, c2);
+        gridpane.getRowConstraints().addAll(r1, r2, r3);
+        
+        gridpane.resize(150, 73);
+        gridpane.layout();        
+        double[] rh = gridpane.getRowHeights();
+
+        assertEquals(25, rh[0], 1e-100);
+        assertEquals(24, rh[1], 1e-100);
+        assertEquals(24, rh[2], 1e-100);
+    }
+    
+    @Test public void test_RT20931_cellWidthTotalShouldEqualRowWidth() {
+        ColumnConstraints c1 = new ColumnConstraints();
+        c1.setMinWidth(10);
+        c1.setHgrow(Priority.SOMETIMES);
+        
+        ColumnConstraints c2 = new ColumnConstraints();
+        c2.setMinWidth(10);
+        c2.setHgrow(Priority.SOMETIMES);
+                
+        RowConstraints r1 = new RowConstraints();
+        r1.setMinHeight(10);
+        r1.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r2 = new RowConstraints();
+        r2.setMinHeight(10);
+        r2.setVgrow(Priority.SOMETIMES);
+        
+        RowConstraints r3 = new RowConstraints();
+        r3.setMinHeight(10);
+        r3.setVgrow(Priority.SOMETIMES);        
+        
+        gridpane.getColumnConstraints().addAll(c1, c2);
+        gridpane.getRowConstraints().addAll(r1, r2, r3);
+        
+        gridpane.resize(151, 73);
+        gridpane.layout();        
+        double[] cw = gridpane.getColumnWidths();
+
+        assertEquals(76, cw[0], 1e-100);
+        assertEquals(75, cw[1], 1e-100);
+    }    
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TextInputControlBehavior.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TextInputControlBehavior.java	Wed Jun 06 13:26:28 2012 -0700
@@ -119,17 +119,31 @@
 
     @Override public void callAction(String name) {
         TextInputControl textInputControl = getControl();
+        boolean done = false;
+
+        setCaretAnimating(false);
+
         if (textInputControl.isEditable()) {
-            setCaretAnimating(false);
             setEditing(true);
-            final IndexRange selection = textInputControl.getSelection();
-            final int start = selection.getStart();
-            final int end = selection.getEnd();
-
+            done = true;
             if ("InputCharacter".equals(name)) defaultKeyTyped(lastEvent);
             else if ("Cut".equals(name)) cut();
-            else if ("Copy".equals(name)) textInputControl.copy();
             else if ("Paste".equals(name)) paste();
+            else if ("DeletePreviousChar".equals(name)) deletePreviousChar();
+            else if ("DeleteNextChar".equals(name)) deleteNextChar();
+            else if ("DeletePreviousWord".equals(name)) deletePreviousWord();
+            else if ("DeleteNextWord".equals(name)) deleteNextWord();
+            else if ("DeleteSelection".equals(name)) deleteSelection();
+            else if ("Undo".equals(name)) undoManager.undo();
+            else if ("Redo".equals(name)) undoManager.redo();
+            else {
+                done = false;
+            }
+            setEditing(false);
+        }
+        if (!done) {
+            done = true;
+            if ("Copy".equals(name)) textInputControl.copy();
             else if ("SelectBackward".equals(name)) textInputControl.selectBackward();
             else if ("SelectForward".equals(name)) textInputControl.selectForward();
             else if ("PreviousWord".equals(name)) previousWord();
@@ -140,11 +154,6 @@
             else if ("SelectAll".equals(name)) textInputControl.selectAll();
             else if ("Home".equals(name)) textInputControl.home();
             else if ("End".equals(name)) textInputControl.end();
-            else if ("DeletePreviousChar".equals(name)) deletePreviousChar();
-            else if ("DeleteNextChar".equals(name)) deleteNextChar();
-            else if ("DeletePreviousWord".equals(name)) deletePreviousWord();
-            else if ("DeleteNextWord".equals(name)) deleteNextWord();
-            else if ("DeleteSelection".equals(name)) deleteSelection();
             else if ("Forward".equals(name)) textInputControl.forward();
             else if ("Backward".equals(name)) textInputControl.backward();
             else if ("Fire".equals(name)) fire(lastEvent);
@@ -153,25 +162,16 @@
             else if ("SelectEnd".equals(name)) selectEnd();
             else if ("SelectHomeExtend".equals(name)) selectHomeExtend();
             else if ("SelectEndExtend".equals(name)) selectEndExtend();
-            else if ("Undo".equals(name)) undoManager.undo();
-            else if ("Redo".equals(name)) undoManager.redo();
             else if ("ToParent".equals(name)) forwardToParent(lastEvent);
             /*DEBUG*/else if ("UseVK".equals(name) && isEmbedded()) {
                 ((com.sun.javafx.scene.control.skin.TextInputControlSkin)textInputControl.getSkin()).toggleUseVK();
             } else {
-                setEditing(false);
-                super.callAction(name);
+                done = false;
             }
-            setEditing(false);
-            setCaretAnimating(true);
-        } else if ("Copy".equals(name)) {
-            // If the key event is for the "copy" action then we go ahead
-            // and execute it, but for all other key events which occur
-            // when not editable, we don't allow.
-            textInputControl.copy();
-        } else if (name.startsWith("Traverse")) {
-            // Call super.callAction() for any focus traversal actions even if
-            // it's not editable
+        }
+        setCaretAnimating(true);
+
+        if (!done) {
             super.callAction(name);
         }
         // Note, I don't have to worry about "Consume" here.
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/FXVKSkin.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/FXVKSkin.java	Wed Jun 06 13:26:28 2012 -0700
@@ -68,7 +68,7 @@
 import static javafx.scene.input.KeyCode.*;
 import static javafx.scene.input.MouseEvent.*;
 
-import static com.sun.javafx.scene.control.skin.resources.ControlResources.*;
+import static com.sun.javafx.scene.control.skin.resources.EmbeddedResources.*;
 
 public class FXVKSkin extends SkinBase<FXVK, BehaviorBase<FXVK>> {
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/MenuBarSkin.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/MenuBarSkin.java	Wed Jun 06 13:26:28 2012 -0700
@@ -54,9 +54,11 @@
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.HBox;
 import javafx.stage.Stage;
+import javafx.beans.value.WeakChangeListener;
 
 import com.sun.javafx.menu.MenuBase;
 import com.sun.javafx.scene.control.GlobalMenuAdapter;
+import com.sun.javafx.scene.control.WeakEventHandler;
 import com.sun.javafx.scene.control.behavior.BehaviorBase;
 import com.sun.javafx.scene.traversal.Direction;
 import com.sun.javafx.scene.traversal.TraversalEngine;
@@ -143,7 +145,10 @@
         });
     }
 
-
+    private WeakEventHandler weakSceneKeyEventHandler;
+    private WeakEventHandler weakSceneMouseEventHandler;
+    private EventHandler keyEventHandler;
+    private EventHandler mouseEventHandler;
 
     /***************************************************************************
      *                                                                         *
@@ -156,8 +161,9 @@
         
         container = new HBox();
         getChildren().add(container);
-     
-        control.getScene().addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
+        
+        // Key navigation 
+        keyEventHandler = new EventHandler<KeyEvent>() {
             @Override public void handle(KeyEvent event) {
                 // process right left and may be tab key events
                 if (openMenu != null) {
@@ -212,19 +218,25 @@
                     }
                 }
             }
-        });
+        };
+        weakSceneKeyEventHandler = new WeakEventHandler(control.getScene(), KeyEvent.KEY_PRESSED, 
+                keyEventHandler);
+        control.getScene().addEventFilter(KeyEvent.KEY_PRESSED, weakSceneKeyEventHandler);
+        
         // When we click else where in the scene - menu selection should be cleared.
-        control.getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
-            @Override
-            public void handle(MouseEvent t) {
+        mouseEventHandler = new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent t) {
                 if (!container.localToScene(container.getLayoutBounds()).contains(t.getX(), t.getY())) {
                     unSelectMenus();
                     firstF10 = true;
                 }
             }
-        });
+        };
+        weakSceneMouseEventHandler = new WeakEventHandler(control.getScene(), MouseEvent.MOUSE_CLICKED, 
+                mouseEventHandler);
+        
         // When the parent window looses focus - menu selection should be cleared
-        control.getScene().getWindow().focusedProperty().addListener(new ChangeListener<Boolean>() {
+        control.getScene().getWindow().focusedProperty().addListener(new WeakChangeListener(new ChangeListener<Boolean>() {
             @Override
             public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
               if (!t1) {
@@ -232,7 +244,7 @@
                   firstF10 = true;
               }
             }
-        });
+        }));
         
         rebuildUI();
         control.getMenus().addListener(new ListChangeListener<Menu>() {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/PaginationSkin.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/PaginationSkin.java	Wed Jun 06 13:26:28 2012 -0700
@@ -325,6 +325,10 @@
             animate = false;
         }
 
+        // Remove the children in the pane before we create a new page.
+        currentStackPane.getChildren().clear();
+        nextStackPane.getChildren().clear();
+        
         pagination.setCurrentPageIndex(currentIndex);
         createPage(currentStackPane, currentIndex);
 
@@ -635,9 +639,6 @@
                 timeline.setOnFinished(new EventHandler<ActionEvent>() {
                     @Override
                     public void handle(ActionEvent arg0) {
-                        // Create a new page by removing the children.
-                        currentStackPane.getChildren().clear();
-                        nextStackPane.getChildren().clear();
                         resetIndexes(false);
                         navigation.initializePageIndicators();
                         navigation.updatePageIndicators();
@@ -645,13 +646,10 @@
                 });
                 return;
             }
-            // Create a new page by removing the children.
-            currentStackPane.getChildren().clear();
-            nextStackPane.getChildren().clear();
             resetIndexes(false);
             navigation.initializePageIndicators();
             navigation.updatePageIndicators();
-        } else if (p == "PAGE_COUNT") {
+        } else if (p == "PAGE_COUNT") {          
             resetIndexes(false);
             navigation.initializePageIndicators();
             navigation.updatePageIndicators();
@@ -807,11 +805,9 @@
 
         // Create the indicators using fromIndex and toIndex.
         private void initializePageIndicators() {
-            if (!indicatorButtons.getToggles().isEmpty()) {
-                previousIndicatorCount = 0;
-                controlBox.getChildren().clear();
-                indicatorButtons.getToggles().clear();
-            }
+            previousIndicatorCount = 0;
+            controlBox.getChildren().clear();
+            indicatorButtons.getToggles().clear();
 
             controlBox.getChildren().add(leftArrowButton);
             for (int i = fromIndex; i <= toIndex; i++) {
@@ -878,8 +874,12 @@
             int indicatorCount = 0;
             for (int i = 0; i < getSkinnable().getMaxPageIndicatorCount(); i++) {
                 int index = i < indicatorButtons.getToggles().size() ? i : indicatorButtons.getToggles().size() - 1;
-                IndicatorButton ib = (IndicatorButton)indicatorButtons.getToggles().get(index);
-                double iw = snapSize(Utils.boundedSize(ib.prefWidth(-1), ib.minWidth(-1), ib.maxWidth(-1)));
+                double iw = minButtonSize;
+                if (index != -1) {
+                    IndicatorButton ib = (IndicatorButton)indicatorButtons.getToggles().get(index);
+                    iw = snapSize(Utils.boundedSize(ib.prefWidth(-1), ib.minWidth(-1), ib.maxWidth(-1)));
+                }
+
                 x += (iw + controlBox.getSpacing());
                 if (x >= w) {
                     break;
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextAreaSkin.java	Wed Jun 06 13:26:28 2012 -0700
@@ -272,11 +272,10 @@
                     Bounds b = caretPath.getBoundsInParent();
                     if (caretPos < anchorPos) {
                         selectionHandle2.setLayoutX(b.getMinX() - selectionHandle2.getWidth() / 2);
-                        selectionHandle2.setLayoutY(b.getMaxY());
+                        selectionHandle2.setLayoutY(b.getMaxY() - 1);
                     } else {
                         selectionHandle1.setLayoutX(b.getMinX() - selectionHandle1.getWidth() / 2);
-                        //selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight());
-                        selectionHandle1.setLayoutY(b.getMaxY());
+                        selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight() + 1);
                     }
                 }
             }
@@ -342,11 +341,10 @@
                 if (selection.getLength() > 0) {
                     if (caretPos < anchorPos) {
                         selectionHandle1.setLayoutX(b.getMinX() - selectionHandle1.getWidth() / 2);
-                        //selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight());
-                        selectionHandle1.setLayoutY(b.getMaxY());
+                        selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight() + 1);
                     } else {
                         selectionHandle2.setLayoutX(b.getMinX() - selectionHandle2.getWidth() / 2);
-                        selectionHandle2.setLayoutY(b.getMaxY());
+                        selectionHandle2.setLayoutY(b.getMaxY() - 1);
                     }
                 } else {
                     caretHandle.setLayoutX(b.getMinX() - caretHandle.getWidth() / 2 + 1);
@@ -629,7 +627,7 @@
         if (textArea.isFocused()) setCaretAnimating(true);
 
         if (PlatformUtil.isEmbedded()) {
-            //selectionHandle1.setRotate(180);
+            selectionHandle1.setRotate(180);
 
             EventHandler<MouseEvent> handlePressHandler = new EventHandler<MouseEvent>() {
                 @Override public void handle(MouseEvent e) {
@@ -646,8 +644,9 @@
             caretHandle.setOnMouseDragged(new EventHandler<MouseEvent>() {
                 @Override public void handle(MouseEvent e) {
                     Text textNode = getTextNode();
-                    Point2D p = new Point2D(caretHandle.getLayoutX() + e.getX() + pressX - textNode.getLayoutX(),
-                                            caretHandle.getLayoutY() + e.getY() - pressY - 6 - getTextTranslateY());
+                    Point2D tp = textNode.localToScene(0, 0);
+                    Point2D p = new Point2D(e.getSceneX() - tp.getX() + 10/*??*/ - pressX + caretHandle.getWidth() / 2,
+                                            e.getSceneY() - tp.getY() - pressY - 6);
                     HitInfo hit = textNode.impl_hitTestChar(translateCaretPosition(p));
                     int pos = hit.getCharIndex();
                     if (pos > 0) {
@@ -670,8 +669,7 @@
                     Text textNode = getTextNode();
                     Point2D tp = textNode.localToScene(0, 0);
                     Point2D p = new Point2D(e.getSceneX() - tp.getX() + 10/*??*/ - pressX + selectionHandle1.getWidth() / 2,
-                                            //e.getSceneY() - tp.getY() - pressY + selectionHandle1.getHeight() + 5);
-                                            e.getSceneY() - tp.getY() - pressY - 6);
+                                            e.getSceneY() - tp.getY() - pressY + selectionHandle1.getHeight() + 5);
                     HitInfo hit = textNode.impl_hitTestChar(translateCaretPosition(p));
                     int pos = hit.getCharIndex();
                     if (textArea.getAnchor() < textArea.getCaretPosition()) {
@@ -958,12 +956,25 @@
     }
 
     private void scrollCaretToVisible() {
-            Bounds bounds = caretPath.getLayoutBounds();
-            TextArea textArea = getSkinnable();
+        TextArea textArea = getSkinnable();
+        Bounds bounds = caretPath.getLayoutBounds();
+        double x = bounds.getMinX() - textArea.getScrollLeft();
+        double y = bounds.getMinY() - textArea.getScrollTop();
+        double w = bounds.getWidth();
+        double h = bounds.getHeight();
 
-            scrollBoundsToVisible(new Rectangle2D(bounds.getMinX() - textArea.getScrollLeft(),
-                                                  bounds.getMinY() - textArea.getScrollTop(),
-                                                  bounds.getWidth(), bounds.getHeight()));
+        if (PlatformUtil.isEmbedded()) {
+            if (caretHandle.isVisible()) {
+                h += caretHandle.getHeight();
+            } else if (selectionHandle1.isVisible() && selectionHandle2.isVisible()) {
+                x -= selectionHandle1.getWidth() / 2;
+                y -= selectionHandle1.getHeight();
+                w += selectionHandle1.getWidth() / 2 + selectionHandle2.getWidth() / 2;
+                h += selectionHandle1.getHeight() + selectionHandle2.getHeight();
+            }
+        }
+
+        scrollBoundsToVisible(new Rectangle2D(x, y, w, h));
     }
 
     private void scrollBoundsToVisible(Rectangle2D bounds) {
@@ -1049,11 +1060,11 @@
     // Callbacks from Behavior class
 
     private double getTextTranslateX() {
-        return 0;
+        return contentView.getInsets().getLeft();
     }
 
     private double getTextTranslateY() {
-        return 0;
+        return contentView.getInsets().getTop();
     }
 
     private double getTextLeft() {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextFieldSkin.java	Wed Jun 06 13:26:28 2012 -0700
@@ -236,7 +236,7 @@
         textGroup.getChildren().addAll(selectionHighlightPath, textNode, caretPath);
         getChildren().add(textGroup);
         if (PlatformUtil.isEmbedded()) {
-            /*textGroup.*/getChildren().addAll(caretHandle, selectionHandle1, selectionHandle2);
+            getChildren().addAll(caretHandle, selectionHandle1, selectionHandle2);
         }
 
         // Add text
@@ -346,6 +346,8 @@
         });
 
         if (PlatformUtil.isEmbedded()) {
+            selectionHandle1.setRotate(180);
+
             EventHandler<MouseEvent> handlePressHandler = new EventHandler<MouseEvent>() {
                 @Override public void handle(MouseEvent e) {
                     pressX = e.getX();
@@ -749,9 +751,10 @@
                                caretHandle.prefHeight(-1));
 
             Bounds b = caretPath.getBoundsInParent();
-            selectionHandle1.setLayoutY(b.getMaxY() - 3);
-            selectionHandle2.setLayoutY(b.getMaxY() - 3);
-            caretHandle.setLayoutY(b.getMaxY() - 3);
+            caretHandle.setLayoutY(b.getMaxY() - 1);
+            //selectionHandle1.setLayoutY(b.getMaxY() - 1);
+            selectionHandle1.setLayoutY(b.getMinY() - selectionHandle1.getHeight() + 1);
+            selectionHandle2.setLayoutY(b.getMaxY() - 1);
         }
     }
 
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TextInputControlSkin.java	Wed Jun 06 13:26:28 2012 -0700
@@ -85,6 +85,7 @@
 import com.sun.javafx.tk.FontMetrics;
 import com.sun.javafx.tk.Toolkit;
 
+import static com.sun.javafx.PlatformUtil.*;
 import static com.sun.javafx.scene.control.skin.resources.ControlResources.*;
 
 /**
@@ -92,7 +93,7 @@
  */
 public abstract class TextInputControlSkin<T extends TextInputControl, B extends TextInputControlBehavior<T>> extends SkinBase<T, B> {
 
-    private static final boolean macOS = PlatformUtil.isMac();
+    private static final boolean macOS = isMac();
     /**
      * The font to use with this control. In 1.3 and prior we had a font property
      * on the TextInputControl itself, however now we just do it via CSS
@@ -235,7 +236,7 @@
     protected StackPane selectionHandle2 = null;
 
     public Point2D getMenuPosition() {
-        if (PlatformUtil.isEmbedded()) {
+        if (isEmbedded()) {
             if (caretHandle.isVisible()) {
                 return new Point2D(caretHandle.getLayoutX() + caretHandle.getWidth() / 2,
                                    caretHandle.getLayoutY());
@@ -252,7 +253,7 @@
     }
 
 
-    private static boolean useFXVK = PlatformUtil.isEmbedded();
+    private static boolean useFXVK = isEmbedded();
 
     /* For testing only */
     static int vkType = -1;
@@ -300,15 +301,15 @@
             { bind(textInput.focusedProperty(), textInput.anchorProperty(), textInput.caretPositionProperty(),
                     textInput.disabledProperty(), textInput.editableProperty(), displayCaret, blink);}
             @Override protected boolean computeValue() {
-                // RT-10682: On mac, we hide the caret during selection, but on windows we show it
+                // RT-10682: On Windows, we show the caret during selection, but on others we hide it
                 return !blink.get() && displayCaret.get() && textInput.isFocused() &&
-                        (!macOS || (textInput.getCaretPosition() == textInput.getAnchor())) &&
+                        (isWindows() || (textInput.getCaretPosition() == textInput.getAnchor())) &&
                         !textInput.isDisabled() &&
                         textInput.isEditable();
             }
         };
 
-        if (PlatformUtil.isEmbedded()) {
+        if (isEmbedded()) {
             caretHandle      = new StackPane();
             selectionHandle1 = new StackPane();
             selectionHandle2 = new StackPane();
@@ -604,20 +605,25 @@
     final MenuItem deleteMI = new ContextMenuItem("DeleteSelection");
     final MenuItem selectWordMI = new ContextMenuItem("SelectWord");
     final MenuItem selectAllMI = new ContextMenuItem("SelectAll");
+    final MenuItem separatorMI = new SeparatorMenuItem();
 
     public void populateContextMenu(ContextMenu contextMenu) {
-        boolean hasText = (getSkinnable().getLength() > 0);
-        boolean hasSelection = (getSkinnable().getSelection().getLength() > 0);
+        TextInputControl textInputControl = getSkinnable();
+        boolean editable = textInputControl.isEditable();
+        boolean hasText = (textInputControl.getLength() > 0);
+        boolean hasSelection = (textInputControl.getSelection().getLength() > 0);
         boolean maskText = (maskText("A") != "A");
         ObservableList<MenuItem> items = contextMenu.getItems();
 
-        if (PlatformUtil.isEmbedded()) {
+        if (isEmbedded()) {
             items.clear();
             if (!maskText && hasSelection) {
-                items.add(cutMI);
+                if (editable) {
+                    items.add(cutMI);
+                }
                 items.add(copyMI);
             }
-            if (Clipboard.getSystemClipboard().hasString()) {
+            if (editable && Clipboard.getSystemClipboard().hasString()) {
                 items.add(pasteMI);
             }
             if (hasText) {
@@ -629,9 +635,11 @@
             selectWordMI.getProperties().put("refreshMenu", Boolean.TRUE);
             selectAllMI.getProperties().put("refreshMenu", Boolean.TRUE);
         } else {
-            if (items.size() == 0) {
-                items.addAll(undoMI, redoMI, cutMI, copyMI, pasteMI, deleteMI,
-                             new SeparatorMenuItem(), selectAllMI);
+            if (editable) {
+                items.setAll(undoMI, redoMI, cutMI, copyMI, pasteMI, deleteMI,
+                             separatorMI, selectAllMI);
+            } else {
+                items.setAll(copyMI, separatorMI, selectAllMI);
             }
             undoMI.setDisable(!getBehavior().canUndo());
             redoMI.setDisable(!getBehavior().canRedo());
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java	Wed Jun 06 13:26:28 2012 -0700
@@ -554,7 +554,17 @@
                             virtualDelta = event.getTextDeltaY() * lastHeight;
                             break;
                         case LINES:
-                            virtualDelta = event.getTextDeltaY() * lastCellLength;
+                            /*
+                            ** if we've selected a cell, then use
+                            ** it's length for the scroll, otherwise
+                            ** use the length of the first visible cell
+                            */
+                            if (lastCellLength != -1) {
+                                virtualDelta = event.getTextDeltaY() * lastCellLength;
+                            }
+                            else if (getFirstVisibleCell() != null) {
+                                virtualDelta = event.getTextDeltaY() * getCellLength(getFirstVisibleCell());
+                            }
                             break;
                         case NONE:
                             virtualDelta = event.getDeltaY();
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/embedded.css	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/embedded.css	Wed Jun 06 13:26:28 2012 -0700
@@ -92,39 +92,53 @@
 }
 
 
+
+/*******************************************************************************
+ *                                                                             *
+ * TextField, PasswordField, TextArea                                                                   *
+ *                                                                             *
+ ******************************************************************************/
+
+.text-field {
+    -fx-padding: 6 5 6 5; /* Adding 10px to bottom for handles */
+}
+
+.text-area .content {
+    -fx-padding: 13 5 13 5; /* Adding 10px to top and bottom for handles */
+}
+
+
 .caret-handle {
-    -fx-background-color: black /*#ACACAC*/,
+    -fx-background-color: transparent,
+                          black /*#ACACAC*/,
                           linear-gradient(to bottom, #AFAFAF 0%, #DFDFDF 100%);
-    -fx-background-insets: 0, 1;
-    -fx-shape: "M11.974,2.579L20,12.358V28H4V12.356L11.974,2.579z";
+    -fx-background-insets: -4 -18 -8 -18, 0, 1;
+    -fx-shape: "M11.974,2.579L20,12.358V20H4V12.356L11.974,2.579z";
 /*
     -fx-shape: "M11.972,1L3,12v17h18V12L11.972,1L11.972,1z";
     -fx-padding: 0.375em 0.291em 0.375em 0.291em;
 */
-    -fx-padding: 0.45em 0.3em 0.45em 0.3em;
+    -fx-padding: 0.32em 0.3em 0.32em 0.3em;
     -fx-cursor: hand;
 }
 
+
+
 .selection-handle {
-    -fx-background-color: transparent, #0071bc /*-fx-accent*/,
+    -fx-background-color: transparent,
+                          #0071bc /*-fx-accent*/,
                           linear-gradient(to bottom, #0063AA 0%, #008AED 100%);
-    -fx-background-insets: 0, 0, 1;
-    -fx-shape: "M10.974,2.579L19,12.358V28H3V12.356L10.974,2.579z";
+    -fx-background-insets: -4 -18 -8 -18, 0, 1;
+    -fx-shape: "M10.974,2.579L19,12.358V20H3V12.356L10.974,2.579z";
 /*
     -fx-shape: "M10.972,1L2,12v17h18V12L10.972,1L10.972,1z";
     -fx-padding: 0.375em 0.291em 0.375em 0.291em;
 */
-    -fx-padding: 0.45em 0.3em 0.45em 0.3em;
+    -fx-padding: 0.32em 0.3em 0.32em 0.3em;
     -fx-cursor: hand;
 }
 
-#selection-handle-1 {
-    -fx-background-insets: -4 0 -4 -4, 0, 1;
-}
 
-#selection-handle-2 {
-    -fx-background-insets: -4 -4 -4 0, 0, 1;
-}
 
 /*******************************************************************************
  *                                                                             *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/EmbeddedResources.java	Wed Jun 06 13:26:28 2012 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.javafx.scene.control.skin.resources;
+
+import java.util.ResourceBundle;
+
+public final class EmbeddedResources {
+
+    private static ResourceBundle embeddedResourceBundle;
+
+    public static ResourceBundle getBundle() {
+        if (embeddedResourceBundle == null) {
+            embeddedResourceBundle = ResourceBundle.getBundle("com/sun/javafx/scene/control/skin/resources/embedded");
+        }
+        return embeddedResourceBundle;
+    }
+
+    public static String getString(String key) {
+        return getBundle().getString(key);
+    }
+}
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/controls.properties	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/controls.properties	Wed Jun 06 13:26:28 2012 -0700
@@ -18,176 +18,3 @@
 TextInputControl.menu.SelectAll=Select All
 TextInputControl.menu.SelectWord=Select
 
-# Virtual Keyboard for embedded FX. This will not be localized for FX 2.2.
-#
-# Note: There can at most be only one of each of the special keys: BACKSPACE ENTER SHIFT SYM
-#
-# TODO: use sect, deg, reg, tm only once
-#
-FXVK.text.row1.key01=q 1 [
-FXVK.text.row1.key02=w 2 ]
-FXVK.text.row1.key03=e 3 { egrave eacute ecirc euml
-FXVK.text.row1.key04=r 4 } reg
-FXVK.text.row1.key05=t 5 < tm
-FXVK.text.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
-FXVK.text.row1.key07=u 7 laquo ugrave uacute ucirc uuml
-FXVK.text.row1.key08=i 8 raquo igrave iacute icirc iuml
-FXVK.text.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
-FXVK.text.row1.key10=p 0 ~ para pi
-
-FXVK.text.row2.key01=a # agrave aacute acirc atilde auml aring
-FXVK.text.row2.key02=s $ euro pound yen scedil scaron szlig sigma
-FXVK.text.row2.key03=d % eth
-FXVK.text.row2.key04=f &
-FXVK.text.row2.key05=g * sect
-FXVK.text.row2.key06=h ( middot
-FXVK.text.row2.key07=j ) deg
-FXVK.text.row2.key08=k _ neq
-FXVK.text.row2.key09=l @
-
-FXVK.text.row3.key01=SHIFT
-FXVK.text.row3.key02=z / iexcl
-FXVK.text.row3.key03=x \\ iquest
-FXVK.text.row3.key04=c ; permil ccedil copy cent
-FXVK.text.row3.key05=v : reg
-FXVK.text.row3.key06=b = tm
-FXVK.text.row3.key07=n + ntilde
-FXVK.text.row3.key08=m - micro
-FXVK.text.row3.key09=' "
-FXVK.text.row3.key10=BACKSPACE
-
-FXVK.text.row4.key01=SYM
-FXVK.text.row4.key01.width=1.5
-FXVK.text.row4.key02=space
-FXVK.text.row4.key02.width=5
-FXVK.text.row4.key03=, !
-FXVK.text.row4.key04=. ?
-FXVK.text.row4.key05=ENTER
-FXVK.text.row4.key05.width=1.5
-
-
-
-FXVK.numeric.row1.key01=1
-FXVK.numeric.row1.key01.width=1.5
-FXVK.numeric.row1.key02=2
-FXVK.numeric.row1.key02.width=1.5
-FXVK.numeric.row1.key03=3
-FXVK.numeric.row1.key03.width=1.5
-FXVK.numeric.row1.key04=/
-FXVK.numeric.row1.key04.width=1.5
-
-FXVK.numeric.row2.key01=4
-FXVK.numeric.row2.key01.width=1.5
-FXVK.numeric.row2.key02=5
-FXVK.numeric.row2.key02.width=1.5
-FXVK.numeric.row2.key03=6
-FXVK.numeric.row2.key03.width=1.5
-FXVK.numeric.row2.key04=-
-FXVK.numeric.row2.key04.width=1.5
-
-FXVK.numeric.row3.key01=7
-FXVK.numeric.row3.key01.width=1.5
-FXVK.numeric.row3.key02=8
-FXVK.numeric.row3.key02.width=1.5
-FXVK.numeric.row3.key03=9
-FXVK.numeric.row3.key03.width=1.5
-FXVK.numeric.row3.key04=BACKSPACE
-FXVK.numeric.row3.key04.width=1.5
-
-FXVK.numeric.row4.key01=+
-FXVK.numeric.row4.key01.width=1.5
-FXVK.numeric.row4.key02=0
-FXVK.numeric.row4.key02.width=1.5
-FXVK.numeric.row4.key03=. ,
-FXVK.numeric.row4.key03.width=1.5
-FXVK.numeric.row4.key04=ENTER
-FXVK.numeric.row4.key04.width=1.5
-
-
-FXVK.url.row1.key01=q 1 [
-FXVK.url.row1.key02=w 2 ]
-FXVK.url.row1.key03=e 3 { egrave eacute ecirc euml
-FXVK.url.row1.key04=r 4 } reg
-FXVK.url.row1.key05=t 5 < tm
-FXVK.url.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
-FXVK.url.row1.key07=u 7 laquo ugrave uacute ucirc uuml
-FXVK.url.row1.key08=i 8 raquo igrave iacute icirc iuml
-FXVK.url.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
-FXVK.url.row1.key10=p 0 ~ para pi
-
-FXVK.url.row2.key01=a # agrave aacute acirc atilde auml aring
-FXVK.url.row2.key02=s $ euro pound yen scedil scaron szlig sigma
-FXVK.url.row2.key03=d % eth
-FXVK.url.row2.key04=f & 
-FXVK.url.row2.key05=g * sect
-FXVK.url.row2.key06=h ( middot
-FXVK.url.row2.key07=j ) deg
-FXVK.url.row2.key08=k " neq
-FXVK.url.row2.key09=l @
-
-FXVK.url.row3.key01=SHIFT
-FXVK.url.row3.key02=z iexcl
-FXVK.url.row3.key03=x iquest
-FXVK.url.row3.key04=c ; permil ccedil copy cent
-FXVK.url.row3.key05=v : reg
-FXVK.url.row3.key06=b = tm
-FXVK.url.row3.key07=n + ntilde
-FXVK.url.row3.key08=m ' micro
-FXVK.url.row3.key09=- _
-FXVK.url.row3.key10=BACKSPACE
-
-FXVK.url.row4.key01=SYM
-FXVK.url.row4.key01.width=1.5
-FXVK.url.row4.key02=www. http://
-FXVK.url.row4.key02.width=1.5
-FXVK.url.row4.key03=. ,
-FXVK.url.row4.key03.width=1.5
-FXVK.url.row4.key04=.com .org .net .gov .edu
-FXVK.url.row4.key04.width=1.5
-FXVK.url.row4.key05=/ \\
-FXVK.url.row4.key05.width=1.5
-FXVK.url.row4.key06=ENTER
-FXVK.url.row4.key06.width=2.5
-
-
-FXVK.email.row1.key01=q 1 [
-FXVK.email.row1.key02=w 2 ]
-FXVK.email.row1.key03=e 3 { egrave eacute ecirc euml
-FXVK.email.row1.key04=r 4 } reg
-FXVK.email.row1.key05=t 5 < tm
-FXVK.email.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
-FXVK.email.row1.key07=u 7 laquo ugrave uacute ucirc uuml
-FXVK.email.row1.key08=i 8 raquo igrave iacute icirc iuml
-FXVK.email.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
-FXVK.email.row1.key10=p 0 ~ para pi
-
-FXVK.email.row2.key01=a # agrave aacute acirc atilde auml aring
-FXVK.email.row2.key02=s $ euro pound yen scedil scaron szlig sigma
-FXVK.email.row2.key03=d % eth
-FXVK.email.row2.key04=f & 
-FXVK.email.row2.key05=g * sect
-FXVK.email.row2.key06=h ( middot
-FXVK.email.row2.key07=j ) deg
-FXVK.email.row2.key08=k _ neq
-FXVK.email.row2.key09=l "
-
-FXVK.email.row3.key01=SHIFT
-FXVK.email.row3.key02=z / iexcl
-FXVK.email.row3.key03=x \\ iquest
-FXVK.email.row3.key04=c ; permil ccedil copy cent
-FXVK.email.row3.key05=v : reg
-FXVK.email.row3.key06=b = tm
-FXVK.email.row3.key07=n + ntilde
-FXVK.email.row3.key08=m - micro
-FXVK.email.row3.key09=@ '
-FXVK.email.row3.key10=BACKSPACE
-
-FXVK.email.row4.key01=SYM
-FXVK.email.row4.key01.width=1.5
-FXVK.email.row4.key02=space
-FXVK.email.row4.key02.width=4
-FXVK.email.row4.key03=, !
-FXVK.email.row4.key04=. ?
-FXVK.email.row4.key05=.com .org .net .gov .edu
-FXVK.email.row4.key06=ENTER
-FXVK.email.row4.key06.width=1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/resources/embedded.properties	Wed Jun 06 13:26:28 2012 -0700
@@ -0,0 +1,173 @@
+# Virtual Keyboard for embedded FX. This will not be localized for FX 2.2.
+#
+# Note: There can at most be only one of each of the special keys: BACKSPACE ENTER SHIFT SYM
+#
+# TODO: use sect, deg, reg, tm only once
+#
+FXVK.text.row1.key01=q 1 [
+FXVK.text.row1.key02=w 2 ]
+FXVK.text.row1.key03=e 3 { egrave eacute ecirc euml
+FXVK.text.row1.key04=r 4 } reg
+FXVK.text.row1.key05=t 5 < tm
+FXVK.text.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
+FXVK.text.row1.key07=u 7 laquo ugrave uacute ucirc uuml
+FXVK.text.row1.key08=i 8 raquo igrave iacute icirc iuml
+FXVK.text.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
+FXVK.text.row1.key10=p 0 ~ para pi
+
+FXVK.text.row2.key01=a # agrave aacute acirc atilde auml aring
+FXVK.text.row2.key02=s $ euro pound yen scedil scaron szlig sigma
+FXVK.text.row2.key03=d % eth
+FXVK.text.row2.key04=f &
+FXVK.text.row2.key05=g * sect
+FXVK.text.row2.key06=h ( middot
+FXVK.text.row2.key07=j ) deg
+FXVK.text.row2.key08=k _ neq
+FXVK.text.row2.key09=l @
+
+FXVK.text.row3.key01=SHIFT
+FXVK.text.row3.key02=z / iexcl
+FXVK.text.row3.key03=x \\ iquest
+FXVK.text.row3.key04=c ; permil ccedil copy cent
+FXVK.text.row3.key05=v : reg
+FXVK.text.row3.key06=b = tm
+FXVK.text.row3.key07=n + ntilde
+FXVK.text.row3.key08=m - micro
+FXVK.text.row3.key09=' "
+FXVK.text.row3.key10=BACKSPACE
+
+FXVK.text.row4.key01=SYM
+FXVK.text.row4.key01.width=1.5
+FXVK.text.row4.key02=space
+FXVK.text.row4.key02.width=5
+FXVK.text.row4.key03=, !
+FXVK.text.row4.key04=. ?
+FXVK.text.row4.key05=ENTER
+FXVK.text.row4.key05.width=1.5
+
+
+
+FXVK.numeric.row1.key01=1
+FXVK.numeric.row1.key01.width=1.5
+FXVK.numeric.row1.key02=2
+FXVK.numeric.row1.key02.width=1.5
+FXVK.numeric.row1.key03=3
+FXVK.numeric.row1.key03.width=1.5
+FXVK.numeric.row1.key04=/
+FXVK.numeric.row1.key04.width=1.5
+
+FXVK.numeric.row2.key01=4
+FXVK.numeric.row2.key01.width=1.5
+FXVK.numeric.row2.key02=5
+FXVK.numeric.row2.key02.width=1.5
+FXVK.numeric.row2.key03=6
+FXVK.numeric.row2.key03.width=1.5
+FXVK.numeric.row2.key04=-
+FXVK.numeric.row2.key04.width=1.5
+
+FXVK.numeric.row3.key01=7
+FXVK.numeric.row3.key01.width=1.5
+FXVK.numeric.row3.key02=8
+FXVK.numeric.row3.key02.width=1.5
+FXVK.numeric.row3.key03=9
+FXVK.numeric.row3.key03.width=1.5
+FXVK.numeric.row3.key04=BACKSPACE
+FXVK.numeric.row3.key04.width=1.5
+
+FXVK.numeric.row4.key01=+
+FXVK.numeric.row4.key01.width=1.5
+FXVK.numeric.row4.key02=0
+FXVK.numeric.row4.key02.width=1.5
+FXVK.numeric.row4.key03=. ,
+FXVK.numeric.row4.key03.width=1.5
+FXVK.numeric.row4.key04=ENTER
+FXVK.numeric.row4.key04.width=1.5
+
+
+FXVK.url.row1.key01=q 1 [
+FXVK.url.row1.key02=w 2 ]
+FXVK.url.row1.key03=e 3 { egrave eacute ecirc euml
+FXVK.url.row1.key04=r 4 } reg
+FXVK.url.row1.key05=t 5 < tm
+FXVK.url.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
+FXVK.url.row1.key07=u 7 laquo ugrave uacute ucirc uuml
+FXVK.url.row1.key08=i 8 raquo igrave iacute icirc iuml
+FXVK.url.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
+FXVK.url.row1.key10=p 0 ~ para pi
+
+FXVK.url.row2.key01=a # agrave aacute acirc atilde auml aring
+FXVK.url.row2.key02=s $ euro pound yen scedil scaron szlig sigma
+FXVK.url.row2.key03=d % eth
+FXVK.url.row2.key04=f & 
+FXVK.url.row2.key05=g * sect
+FXVK.url.row2.key06=h ( middot
+FXVK.url.row2.key07=j ) deg
+FXVK.url.row2.key08=k " neq
+FXVK.url.row2.key09=l @
+
+FXVK.url.row3.key01=SHIFT
+FXVK.url.row3.key02=z iexcl
+FXVK.url.row3.key03=x iquest
+FXVK.url.row3.key04=c ; permil ccedil copy cent
+FXVK.url.row3.key05=v : reg
+FXVK.url.row3.key06=b = tm
+FXVK.url.row3.key07=n + ntilde
+FXVK.url.row3.key08=m ' micro
+FXVK.url.row3.key09=- _
+FXVK.url.row3.key10=BACKSPACE
+
+FXVK.url.row4.key01=SYM
+FXVK.url.row4.key01.width=1.5
+FXVK.url.row4.key02=www. http://
+FXVK.url.row4.key02.width=1.5
+FXVK.url.row4.key03=. ,
+FXVK.url.row4.key03.width=1.5
+FXVK.url.row4.key04=.com .org .net .gov .edu
+FXVK.url.row4.key04.width=1.5
+FXVK.url.row4.key05=/ \\
+FXVK.url.row4.key05.width=1.5
+FXVK.url.row4.key06=ENTER
+FXVK.url.row4.key06.width=2.5
+
+
+FXVK.email.row1.key01=q 1 [
+FXVK.email.row1.key02=w 2 ]
+FXVK.email.row1.key03=e 3 { egrave eacute ecirc euml
+FXVK.email.row1.key04=r 4 } reg
+FXVK.email.row1.key05=t 5 < tm
+FXVK.email.row1.key06=y 6 > ygrave yacute ycirc ymacron yuml yhook
+FXVK.email.row1.key07=u 7 laquo ugrave uacute ucirc uuml
+FXVK.email.row1.key08=i 8 raquo igrave iacute icirc iuml
+FXVK.email.row1.key09=o 9 ` ograve oacute ocirc otilde ouml oslash deg
+FXVK.email.row1.key10=p 0 ~ para pi
+
+FXVK.email.row2.key01=a # agrave aacute acirc atilde auml aring
+FXVK.email.row2.key02=s $ euro pound yen scedil scaron szlig sigma
+FXVK.email.row2.key03=d % eth
+FXVK.email.row2.key04=f & 
+FXVK.email.row2.key05=g * sect
+FXVK.email.row2.key06=h ( middot
+FXVK.email.row2.key07=j ) deg
+FXVK.email.row2.key08=k _ neq
+FXVK.email.row2.key09=l "
+
+FXVK.email.row3.key01=SHIFT
+FXVK.email.row3.key02=z / iexcl
+FXVK.email.row3.key03=x \\ iquest
+FXVK.email.row3.key04=c ; permil ccedil copy cent
+FXVK.email.row3.key05=v : reg
+FXVK.email.row3.key06=b = tm
+FXVK.email.row3.key07=n + ntilde
+FXVK.email.row3.key08=m - micro
+FXVK.email.row3.key09=@ '
+FXVK.email.row3.key10=BACKSPACE
+
+FXVK.email.row4.key01=SYM
+FXVK.email.row4.key01.width=1.5
+FXVK.email.row4.key02=space
+FXVK.email.row4.key02.width=4
+FXVK.email.row4.key03=, !
+FXVK.email.row4.key04=. ?
+FXVK.email.row4.key05=.com .org .net .gov .edu
+FXVK.email.row4.key06=ENTER
+FXVK.email.row4.key06.width=1.5
--- a/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Wed Jun 06 13:26:28 2012 -0700
@@ -74,7 +74,20 @@
  * <p>As the ComboBox internally renders content with a ListView, API exists in
  * the ComboBox class to allow for a custom cell factory to be set. For more
  * information on cell factories, refer to the {@link Cell} and {@link ListCell}
- * classes.
+ * classes. It is important to note that if a cell factory is set on a ComboBox,
+ * cells will only be used in the ListView that shows when the ComboBox is 
+ * clicked. If you also want to customize the rendering of the 'button' area
+ * of the ComboBox, you can set a custom {@link ListCell} instance in the 
+ * {@link #buttonCellProperty() button cell} property. One way of doing this
+ * is with the following code (note the use of {@code setButtonCell}:
+ * 
+ * <pre>
+ * {@code
+ * Callback<ListView<String>, ListCell<String>> cellFactory = ...;
+ * ComboBox comboBox = new ComboBox();
+ * comboBox.setItems(items);
+ * comboBox.setButtonCell(cellFactory.call(null));
+ * comboBox.setCellFactory(cellFactory);}</pre>
  * 
  * <p>Because a ComboBox can be {@link #editableProperty() editable}, and the
  * default means of allowing user input is via a {@link TextField}, a 
--- a/javafx-ui-controls/src/javafx/scene/control/Pagination.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/Pagination.java	Wed Jun 06 13:26:28 2012 -0700
@@ -69,7 +69,7 @@
  * The control can be customized to display numeric page indicators or bullet style indicators by
  * setting the style class {@link STYLE_CLASS_BULLET}.  The 
  * {@link #maxPageIndicatorCountProperty() maxPageIndicatorCountProperty} can be used to change 
- * the number of page indicators.  The property value can also be changed 
+ * the maximum number of page indicators.  The property value can also be changed 
  * via CSS using -fx-max-page-indicator-count.
  *</p> 
  * 
@@ -185,11 +185,10 @@
     }
     
     /**
-     * The maximum number of page indicators to use for this pagination control.  This
-     * value must be greater than or equal to 1.  The page indicators will 
-     * be unselected when the {@link #currentPageIndexProperty currentPageIndex} 
-     * is greater than the maxPageIndicatorCount.  The number of page indicators will be
-     * reduced if maxPageIndicatorCount cannot fit within this control. 
+     * The maximum number of page indicators to use for this pagination control.  
+     * The maximum number of pages indicators will remain unchanged if the value is less than 1 
+     * or greater than the {@link #pageCount}.  The number of page indicators will be
+     * reduced to fit the control if the {@code maxPageIndicatorCount} cannot fit.
      * 
      * The default is 10 page indicators.
      */    
@@ -198,7 +197,7 @@
             maxPageIndicatorCount = new StyleableIntegerProperty(DEFAULT_MAX_PAGE_INDICATOR_COUNT) {
 
                 @Override protected void invalidated() {
-                    if (getMaxPageIndicatorCount() < 1) {
+                    if (getMaxPageIndicatorCount() < 1 || getMaxPageIndicatorCount() > getPageCount()) {
                         setMaxPageIndicatorCount(oldMaxPageIndicatorCount);
                     }
                     oldMaxPageIndicatorCount = getMaxPageIndicatorCount();
@@ -253,14 +252,14 @@
      * The default is an {@link INDETERMINATE} number of pages.
      */    
     public final IntegerProperty pageCountProperty() { return pageCount; }
-
-    private int oldPageIndex;
+    
     private final IntegerProperty currentPageIndex = new SimpleIntegerProperty(this, "currentPageIndex", 0) {
         @Override protected void invalidated() {
             if (getCurrentPageIndex() < 0) {
-                setCurrentPageIndex(oldPageIndex);
+                setCurrentPageIndex(0);
+            } else if (getCurrentPageIndex() > getPageCount() - 1) {
+                setCurrentPageIndex(getPageCount() - 1);
             }
-            oldPageIndex = getCurrentPageIndex();
         }
     };
     
@@ -276,9 +275,9 @@
     public final int getCurrentPageIndex() { return currentPageIndex.get(); }
     
     /**
-     * The current page index to display for this pagination control.  This value
-     * must be greater than or equal to 0.  The page indicators will be unselected when
-     * the currentPageIndex is greater than the {@link #maxPageIndicatorCountProperty maxPageIndicatorCount}.
+     * The current page index to display for this pagination control.  The first page will be 
+     * the current page if the value is less than 0.  Similarly the last page 
+     * will be the current page if the value is greater than the {@link #pageCount}
      * 
      * The default is 0 for the first page.
      */    
@@ -305,6 +304,8 @@
      * control.  The callback function should load and return the contents the page index.
      * Null should be returned if the page index does not exist.  The currentPageIndex 
      * will not change when null is returned.
+     * 
+     * The default is null if there is no page factory set.
      */    
     public final ObjectProperty<Callback<Integer, Node>> pageFactoryProperty() { return pageFactory; }
 
--- a/javafx-ui-controls/src/javafx/scene/control/UAStylesheetLoader.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/UAStylesheetLoader.java	Wed Jun 06 13:26:28 2012 -0700
@@ -64,12 +64,13 @@
                         if (com.sun.javafx.PlatformUtil.isEmbedded()) {
                             url = SkinBase.class.getResource("caspian/embedded.css");
                             StyleManager.getInstance().addUserAgentStylesheet(url.toExternalForm());
+                            
+                            if (com.sun.javafx.Utils.isQVGAScreen()) {
+                                url = SkinBase.class.getResource("caspian/embedded-qvga.css");
+                                StyleManager.getInstance().addUserAgentStylesheet(url.toExternalForm());
+                            }
                         }
                         
-                        if (com.sun.javafx.Utils.isQVGAScreen()) {
-                            url = SkinBase.class.getResource("caspian/embedded-qvga.css");
-                            StyleManager.getInstance().addUserAgentStylesheet(url.toExternalForm());
-                        }
                         stylesheetLoaded = true;
                     return null;
                 }
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/VirtualFlowTest.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/VirtualFlowTest.java	Wed Jun 06 13:26:28 2012 -0700
@@ -14,8 +14,10 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 
+import javafx.event.Event;
 import javafx.scene.control.IndexedCell;
 import javafx.scene.control.SkinStub;
+import javafx.scene.input.ScrollEvent;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -866,6 +868,55 @@
             if (i != 29) assertEquals("Bad index: " + i, 25, flow.getCellLength(i), 0.0);
         }
     }
+
+    /*
+    ** if we scroll the flow by a number of LINES,
+    ** without having done anything to select a cell
+    ** the flow should scroll.
+    */ 
+    @Test public void testInitialScrollEventActuallyScrolls() {
+        /*
+        ** re-initialize this, as it must be the first
+        ** interaction with the flow
+        */
+        flow = new VirtualFlow();
+        flow.setVertical(true);
+        flow.setCreateCell(new Callback<VirtualFlow, IndexedCell>() {
+            @Override public IndexedCell call(VirtualFlow p) {
+                return new CellStub(flow) {
+                    @Override protected double computeMinWidth(double height) { return computePrefWidth(height); }
+                    @Override protected double computeMaxWidth(double height) { return computePrefWidth(height); }
+                    @Override protected double computePrefWidth(double height) {
+                        return flow.isVertical() ? (c.getIndex() == 29 ? 200 : 100) : (c.getIndex() == 29 ? 100 : 25);
+                    }
+
+                    @Override protected double computeMinHeight(double width) { return computePrefHeight(width); }
+                    @Override protected double computeMaxHeight(double width) { return computePrefHeight(width); }
+                    @Override protected double computePrefHeight(double width) {
+                        return flow.isVertical() ? (c.getIndex() == 29 ? 100 : 25) : (c.getIndex() == 29 ? 200 : 100);
+                    }
+                };
+            }
+        });
+        
+        flow.setCellCount(100);
+        flow.resize(300, 300);
+        pulse();
+       
+        double originalValue = flow.getPosition();
+
+        Event.fireEvent(flow, 
+              ScrollEvent.impl_scrollEvent(ScrollEvent.SCROLL,
+                          0.0, -10.0, 0.0, -10.0,
+                          ScrollEvent.HorizontalTextScrollUnits.NONE, 0.0,
+                          ScrollEvent.VerticalTextScrollUnits.LINES, -1.0,
+                          0,
+                          0, 0,
+                          0, 0,
+                          false, false, false, false, true, false));
+
+        assertTrue(originalValue != flow.getPosition());
+    }
 }
 
 class CellStub extends IndexedCell {
@@ -878,6 +929,7 @@
     private void init(VirtualFlow flow) {
         this.flow = flow;
         setSkin(new SkinStub<CellStub>(this));
+        updateItem(this, false);
     }
 
     @Override
--- a/javafx-ui-controls/test/javafx/scene/control/PaginationTest.java	Tue Jun 05 16:41:13 2012 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/PaginationTest.java	Wed Jun 06 13:26:28 2012 -0700
@@ -208,7 +208,7 @@
         pagination.setCurrentPageIndex(4);
     }
 
-    @Test public void setMaxPageIndicatorCountToZero() {
+    @Test public void setCountToZero() {
         pagination.setPageCount(0);
 
         root.setPrefSize(400, 400);
@@ -226,9 +226,40 @@
 
         pagination.setCurrentPageIndex(5);
         pagination.setCurrentPageIndex(-1);
-        assertEquals(5, pagination.getCurrentPageIndex());
+        assertEquals(0, pagination.getCurrentPageIndex());
     }
 
+    @Test public void setCurrentPageIndexGreaterThanPageCount() {
+        pagination.setPageCount(100);
+        root.setPrefSize(400, 400);
+        root.getChildren().add(pagination);
+        show();
+
+        pagination.setCurrentPageIndex(5);
+        pagination.setCurrentPageIndex(100);
+        assertEquals(99, pagination.getCurrentPageIndex());
+    }
+    
+    @Test public void setMaxPageIndicatorCountLessThanZero() {
+        pagination.setPageCount(100);
+        root.setPrefSize(400, 400);
+        root.getChildren().add(pagination);
+        show();
+
+        pagination.setMaxPageIndicatorCount(-1);
+        assertEquals(10, pagination.getMaxPageIndicatorCount());
+    }
+
+    @Test public void setMaxPageIndicatorCountGreaterThanPageCount() {
+        pagination.setPageCount(100);
+        root.setPrefSize(400, 400);
+        root.getChildren().add(pagination);
+        show();
+        
+        pagination.setMaxPageIndicatorCount(101);
+        assertEquals(10, pagination.getMaxPageIndicatorCount());
+    }
+    
     @Test public void pageCountIsLessThanMaxPageIndicatorCount_RT21660() {
         pagination.setPageCount(5);
         root.setPrefSize(400, 400);