changeset 5035:e346d89c380b

RT-32869: Contextmenu of TextField not working in TableView Reviewed-by: psomashe
author jgiles
date Tue, 17 Sep 2013 10:25:21 +1200
parents 6e2462521fe1
children 3911a222bf96
files modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java modules/controls/src/test/java/javafx/scene/control/cell/TextFieldTableCellTest.java
diffstat 3 files changed, 91 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Tue Sep 17 10:23:41 2013 +1200
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Tue Sep 17 10:25:21 2013 +1200
@@ -606,7 +606,30 @@
                     scrollBarOn();
                 }
                 if (isFocusTraversable()) {
-                    requestFocus();
+                    // We check here to see if the current focus owner is within
+                    // this VirtualFlow, and if so we back-off from requesting
+                    // focus back to the VirtualFlow itself. This is particularly
+                    // relevant given the bug identified in RT-32869. In this
+                    // particular case TextInputControl was clearing selection
+                    // when the focus on the TextField changed, meaning that the
+                    // right-click context menu was not showing the correct
+                    // options as there was no selection in the TextField.
+                    boolean doFocusRequest = true;
+                    Node focusOwner = getScene().getFocusOwner();
+                    if (focusOwner != null) {
+                        Parent parent = focusOwner.getParent();
+                        while (parent != null) {
+                            if (parent.equals(VirtualFlow.this)) {
+                                doFocusRequest = false;
+                                break;
+                            }
+                            parent = parent.getParent();
+                        }
+                    }
+
+                    if (doFocusRequest) {
+                        requestFocus();
+                    }
                 }
 
                 lastX = e.getX();
--- a/modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java	Tue Sep 17 10:23:41 2013 +1200
+++ b/modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java	Tue Sep 17 10:25:21 2013 +1200
@@ -43,8 +43,25 @@
 public final class MouseEventFirer {
     private final EventTarget target;
 
+    private final Scene scene;
+    private final Bounds targetBounds;
+
     public MouseEventFirer(EventTarget target) {
         this.target = target;
+
+        // Force the target node onto a stage so that it is accessible
+        if (target instanceof Node) {
+            Node n = (Node)target;
+            new StageLoader(n);
+            scene = n.getScene();
+            targetBounds = n.getLayoutBounds();
+        } else if (target instanceof Scene) {
+            scene = (Scene)target;
+            new StageLoader(scene);
+            targetBounds = new BoundingBox(0, 0, scene.getWidth(), scene.getHeight());
+        } else {
+            throw new RuntimeException("EventTarget of invalid type");
+        }
     }
 
     public void fireMousePressAndRelease(KeyModifier... modifiers) {
@@ -122,21 +139,6 @@
     }
     
     private void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
-        Scene scene = null;
-        Bounds targetBounds = null;
-        
-        // Force the target node onto a stage so that it is accessible
-        if (target instanceof Node) {
-            Node n = (Node)target;
-            new StageLoader(n);
-            scene = n.getScene();
-            targetBounds = n.getLayoutBounds();
-        } else if (target instanceof Scene) {
-            scene = (Scene)target;
-            new StageLoader(scene);
-            targetBounds = new BoundingBox(0, 0, scene.getWidth(), scene.getHeight());
-        }
-
         // calculate bounds
         final Stage stage = (Stage) scene.getWindow();
         
--- a/modules/controls/src/test/java/javafx/scene/control/cell/TextFieldTableCellTest.java	Tue Sep 17 10:23:41 2013 +1200
+++ b/modules/controls/src/test/java/javafx/scene/control/cell/TextFieldTableCellTest.java	Tue Sep 17 10:25:21 2013 +1200
@@ -25,10 +25,17 @@
 
 package javafx.scene.control.cell;
 
+import com.sun.javafx.scene.control.infrastructure.MouseEventFirer;
+import com.sun.javafx.scene.control.infrastructure.VirtualFlowTestUtils;
+import com.sun.javafx.scene.control.skin.VirtualFlow;
+import javafx.beans.property.ReadOnlyStringWrapper;
+import javafx.beans.value.ObservableValue;
 import javafx.collections.FXCollections;
 import javafx.scene.control.TableCell;
 import javafx.scene.control.TableColumn;
 import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.input.MouseButton;
 import javafx.util.Callback;
 import javafx.util.StringConverter;
 import org.junit.Before;
@@ -375,4 +382,47 @@
         assertFalse(cell.isEditing());
         assertNull(cell.getGraphic());
     }
+
+
+    /**************************************************************************
+     *
+     * Tests for specific bugs
+     *
+     **************************************************************************/
+
+    @Test public void test_rt_32869() {
+        TableColumn tc = new TableColumn();
+        tc.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<String, String>, ObservableValue<String>>() {
+                        @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<String, String> param) {
+                return new ReadOnlyStringWrapper("Dummy Text");
+            }
+        });
+
+        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
+        tableView.getColumns().add(tc);
+        tableView.setEditable(true);
+        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
+        cell.updateTableView(tableView);
+        cell.updateIndex(0);
+        cell.updateTableColumn(tc);
+        cell.setEditable(true);
+
+        tableView.edit(0, tc);
+        assertTrue(cell.isEditing());
+        assertNotNull(cell.getGraphic());
+
+        TextField textField = (TextField) cell.getGraphic();
+        MouseEventFirer mouse = new MouseEventFirer(textField);
+
+        textField.requestFocus();
+        textField.selectAll();
+        assertEquals("Dummy Text", textField.getSelectedText());
+
+        assertEquals("Dummy Text", textField.getSelectedText());
+
+        mouse.fireMousePressed(MouseButton.SECONDARY);
+        assertEquals("Dummy Text", textField.getSelectedText());
+        mouse.fireMouseReleased(MouseButton.SECONDARY);
+        assertEquals("Dummy Text", textField.getSelectedText());
+    }
 }