changeset 1074:a7a2d369bcd4

Fix for RT-19955: Configuring a PopupWindow so that it consumes the event used for hiding
author Lubomir Nerad <lubomir.nerad@oracle.com>
date Wed, 16 May 2012 13:37:38 +0200
parents 5f70f96074ea
children 68089c99e4ca 2ab615afad9e
files javafx-ui-common/src/com/sun/javafx/stage/PopupEventRedirector.java javafx-ui-common/src/javafx/stage/PopupWindow.java javafx-ui-common/test/unit/javafx/scene/Scenegraph_eventHandlers_Test.java javafx-ui-common/test/unit/javafx/scene/input/DragAndDropTest.java javafx-ui-common/test/unit/javafx/scene/input/MouseDragEventTest.java javafx-ui-common/test/unit/javafx/stage/PopupTest.java
diffstat 6 files changed, 122 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-common/src/com/sun/javafx/stage/PopupEventRedirector.java	Wed May 16 13:33:58 2012 +0200
+++ b/javafx-ui-common/src/com/sun/javafx/stage/PopupEventRedirector.java	Wed May 16 13:37:38 2012 +0200
@@ -94,13 +94,17 @@
 
         if ((event.getEventType() == KeyEvent.KEY_PRESSED)
                 && ESCAPE_KEY_COMBINATION.match(event)) {
-            handleEscapeKeyPressedEvent();
+            handleEscapeKeyPressedEvent(event);
         }
     }
 
-    private void handleEscapeKeyPressedEvent() {
+    private void handleEscapeKeyPressedEvent(final Event event) {
         if (popupWindow.isHideOnEscape()) {
             popupWindow.doAutoHide();
+
+            if (popupWindow.getConsumeAutoHidingEvents()) {
+                event.consume();
+            }
         }
     }
 
@@ -121,10 +125,9 @@
 
             popupWindow.doAutoHide();
 
-            // we can consume the press which caused the autohide here,
-            // if we do that it won't have any effect in the target window
-            // from discussions, not consuming it seems preferable
-            // event.consume();
+            if (popupWindow.getConsumeAutoHidingEvents()) {
+                event.consume();
+            }
         }
     }
 
--- a/javafx-ui-common/src/javafx/stage/PopupWindow.java	Wed May 16 13:33:58 2012 +0200
+++ b/javafx-ui-common/src/javafx/stage/PopupWindow.java	Wed May 16 13:37:38 2012 +0200
@@ -246,6 +246,28 @@
     public final BooleanProperty hideOnEscapeProperty() { return hideOnEscape; }
 
     /**
+     * Specifies whether the event, which caused the Popup to hide, should be
+     * consumed. Having the event consumed prevents it from triggering some
+     * additional UI response in the Popup's owner window.
+     * @defaultValue true
+     */
+    private BooleanProperty consumeAutoHidingEvents =
+            new SimpleBooleanProperty(this, "consumeAutoHidingEvents",
+                                      true);
+
+    public final void setConsumeAutoHidingEvents(boolean value) {
+        consumeAutoHidingEvents.set(value);
+    }
+
+    public final boolean getConsumeAutoHidingEvents() {
+        return consumeAutoHidingEvents.get();
+    }
+
+    public final BooleanProperty consumeAutoHidingEventsProperty() {
+        return consumeAutoHidingEvents;
+    }
+
+    /**
      * Show the popup.
      * @param owner The owner of the popup. This must not be null.
      */
--- a/javafx-ui-common/test/unit/javafx/scene/Scenegraph_eventHandlers_Test.java	Wed May 16 13:33:58 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/Scenegraph_eventHandlers_Test.java	Wed May 16 13:37:38 2012 +0200
@@ -45,6 +45,7 @@
 import org.junit.runners.Parameterized.Parameters;
 
 import com.sun.javafx.test.PropertyReference;
+import com.sun.javafx.test.MouseEventGenerator;
 
 @RunWith(Parameterized.class)
 public final class Scenegraph_eventHandlers_Test {
@@ -55,6 +56,8 @@
 
     @Parameters
     public static Collection data() {
+        final MouseEventGenerator mouseEventGenerator =
+                new MouseEventGenerator();
         return Arrays.asList(new Object[][] {
             {
                 KeyEvent.KEY_PRESSED,
@@ -71,31 +74,38 @@
             }, {
                 MouseEvent.MOUSE_PRESSED,
                 "onMousePressed",
-                createTestMouseEvent(MouseEvent.MOUSE_PRESSED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_PRESSED, 0, 0)
             }, {
                 MouseEvent.MOUSE_RELEASED,
                 "onMouseReleased",
-                createTestMouseEvent(MouseEvent.MOUSE_RELEASED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_RELEASED, 0, 0)
             }, {
                 MouseEvent.MOUSE_CLICKED,
                 "onMouseClicked",
-                createTestMouseEvent(MouseEvent.MOUSE_CLICKED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_CLICKED, 0, 0)
             }, {
                 MouseEvent.MOUSE_ENTERED,
                 "onMouseEntered",
-                createTestMouseEvent(MouseEvent.MOUSE_ENTERED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_ENTERED, 0, 0)
             }, {
                 MouseEvent.MOUSE_EXITED,
                 "onMouseExited",
-                createTestMouseEvent(MouseEvent.MOUSE_EXITED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_EXITED, 0, 0)
             }, {
                 MouseEvent.MOUSE_MOVED,
                 "onMouseMoved",
-                createTestMouseEvent(MouseEvent.MOUSE_MOVED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_MOVED, 0, 0)
             }, {
                 MouseEvent.MOUSE_DRAGGED,
                 "onMouseDragged",
-                createTestMouseEvent(MouseEvent.MOUSE_DRAGGED)
+                mouseEventGenerator.generateMouseEvent(
+                        MouseEvent.MOUSE_DRAGGED, 0, 0)
             }
         });
     }
@@ -313,29 +323,6 @@
                                       keyEventType);
     }
 
-    private static Event createTestMouseEvent(
-            final EventType<MouseEvent> mouseEventType) {
-        MouseButton button = MouseButton.NONE;
-        boolean primaryButtonDown = false;
-        int clickCount = 0;
-
-        if ((mouseEventType == MouseEvent.MOUSE_RELEASED)
-                || (mouseEventType == MouseEvent.MOUSE_CLICKED)) {
-            button = MouseButton.PRIMARY;
-            clickCount = 1;
-        } else if (mouseEventType == MouseEvent.MOUSE_PRESSED) {
-            button = MouseButton.PRIMARY;
-            primaryButtonDown = true;
-            clickCount = 1;
-        }
-
-        return MouseEvent.impl_mouseEvent(0, 0, 0, 0,
-                                          button, clickCount,
-                                          false, false, false, false,
-                                          false, primaryButtonDown,
-                                          false, false, false, mouseEventType);
-    }
-
     private static void setEventHandler(
             final Object bean,
             final PropertyReference handlerPropertyReference,
--- a/javafx-ui-common/test/unit/javafx/scene/input/DragAndDropTest.java	Wed May 16 13:33:58 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/input/DragAndDropTest.java	Wed May 16 13:37:38 2012 +0200
@@ -56,6 +56,7 @@
 import com.sun.javafx.tk.TKDragSourceListener;
 import com.sun.javafx.tk.TKDropTargetListener;
 import com.sun.javafx.tk.Toolkit;
+import com.sun.javafx.test.MouseEventGenerator;
 
 public class DragAndDropTest {
     
@@ -1251,37 +1252,6 @@
         
     }
     
-    // Event generators
-    
-    private static class MouseEventGenerator {
-        private boolean primaryButtonDown = false;
-
-        public MouseEvent generateMouseEvent(EventType<MouseEvent> type,
-                double x, double y) {
-
-            MouseButton button = MouseButton.NONE;
-            if (type == MouseEvent.MOUSE_PRESSED ||
-                    type == MouseEvent.MOUSE_RELEASED ||
-                    type == MouseEvent.MOUSE_CLICKED) {
-                button = MouseButton.PRIMARY;
-            }
-
-            if (type == MouseEvent.MOUSE_PRESSED) {
-                primaryButtonDown = true;
-            }
-
-            MouseEvent event = MouseEvent.impl_mouseEvent(x, y, x, y, button,
-                    1, false, false, false, false, false, primaryButtonDown,
-                    false, false, false, type);
-
-            if (type == MouseEvent.MOUSE_RELEASED) {
-                primaryButtonDown = false;
-            }
-
-            return event;
-        }
-    }
-    
     private static class DragEventGenerator {
         public DragEvent generateDragEvent(double x,
                 double y, Dragboard db, TransferMode tm) {
--- a/javafx-ui-common/test/unit/javafx/scene/input/MouseDragEventTest.java	Wed May 16 13:33:58 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/scene/input/MouseDragEventTest.java	Wed May 16 13:37:38 2012 +0200
@@ -32,6 +32,8 @@
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
 
+import com.sun.javafx.test.MouseEventGenerator;
+
 import static org.junit.Assert.*;
 import org.junit.Test;
 
@@ -530,37 +532,6 @@
         w.clear();
     }
 
-
-    private static class MouseEventGenerator {
-        private boolean primaryButtonDown = false;
-
-        public MouseEvent generateMouseEvent(EventType<MouseEvent> type,
-                double x, double y) {
-
-            MouseButton button = MouseButton.NONE;
-            if (type == MouseEvent.MOUSE_PRESSED ||
-                    type == MouseEvent.MOUSE_RELEASED ||
-                    type == MouseEvent.MOUSE_DRAGGED) {
-                button = MouseButton.PRIMARY;
-            }
-
-            if (type == MouseEvent.MOUSE_PRESSED ||
-                    type == MouseEvent.MOUSE_DRAGGED) {
-                primaryButtonDown = true;
-            }
-
-            if (type == MouseEvent.MOUSE_RELEASED) {
-                primaryButtonDown = false;
-            }
-
-            MouseEvent event = MouseEvent.impl_mouseEvent(x, y, x, y, button,
-                    1, false, false, false, false, false, primaryButtonDown,
-                    false, false, false, type);
-
-            return event;
-        }
-    }
-
     private class World {
         private HandledNode scene;
         private HandledNode source;
--- a/javafx-ui-common/test/unit/javafx/stage/PopupTest.java	Wed May 16 13:33:58 2012 +0200
+++ b/javafx-ui-common/test/unit/javafx/stage/PopupTest.java	Wed May 16 13:37:38 2012 +0200
@@ -27,6 +27,8 @@
 
 import com.sun.javafx.pgstub.StubToolkit.ScreenConfiguration;
 import com.sun.javafx.test.MouseEventGenerator;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
 import javafx.scene.input.MouseEvent;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -381,4 +383,73 @@
         assertEquals(200, popup.getWidth(), 1e-100);
         assertEquals(300, popup.getHeight(), 1e-100);
     }
+
+    @Test
+    public void testConsumeAutoHidingEventsProperty() {
+        final EventCounter mouseEventCounter = new EventCounter();
+        final EventCounter keyEventCounter = new EventCounter();
+
+        stage.addEventHandler(MouseEvent.MOUSE_PRESSED, mouseEventCounter);
+        stage.addEventHandler(KeyEvent.KEY_PRESSED, keyEventCounter);
+        try {
+            final MouseEventGenerator mouseEventGenerator =
+                    new MouseEventGenerator();
+
+            final Popup popup = new Popup();
+            popup.setAutoHide(true);
+
+            assertTrue(popup.getConsumeAutoHidingEvents());
+
+            popup.show(stage);
+            Event.fireEvent(stage,
+                            mouseEventGenerator.generateMouseEvent(
+                                MouseEvent.MOUSE_PRESSED, 0, 0));
+            assertEquals(0, mouseEventCounter.getValue());
+
+            popup.show(stage);
+            Event.fireEvent(stage,
+                            KeyEvent.impl_keyEvent(
+                                stage, KeyEvent.CHAR_UNDEFINED,
+                                KeyCode.ESCAPE.getName(),
+                                KeyCode.ESCAPE.impl_getCode(),
+                                false, false, false, false,
+                                KeyEvent.KEY_PRESSED));
+            assertEquals(0, keyEventCounter.getValue());
+
+            popup.setConsumeAutoHidingEvents(false);
+
+            popup.show(stage);
+            Event.fireEvent(stage,
+                            mouseEventGenerator.generateMouseEvent(
+                                MouseEvent.MOUSE_PRESSED, 0, 0));
+            assertEquals(1, mouseEventCounter.getValue());
+
+            popup.show(stage);
+            Event.fireEvent(stage,
+                            KeyEvent.impl_keyEvent(
+                                stage, KeyEvent.CHAR_UNDEFINED,
+                                KeyCode.ESCAPE.getName(),
+                                KeyCode.ESCAPE.impl_getCode(),
+                                false, false, false, false,
+                                KeyEvent.KEY_PRESSED));
+            assertEquals(1, keyEventCounter.getValue());
+            
+        } finally {
+            stage.removeEventHandler(MouseEvent.MOUSE_PRESSED,
+                                     mouseEventCounter);
+            stage.removeEventHandler(KeyEvent.KEY_PRESSED, keyEventCounter);
+        }
+    }
+
+    private static final class EventCounter implements EventHandler<Event> {
+        private int counter;
+
+        public int getValue() {
+            return counter;
+        }
+
+        public void handle(final Event event) {
+            ++counter;
+        }
+    }
 }