changeset 112:e69ac8c4bab6

RT-17890 : ScrollPane steals MouseClicked from parent
author mickf
date Fri, 02 Dec 2011 14:28:34 +0000
parents c4437d337bad
children ad7c7e6580a3
files javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ScrollPaneSkinTest.java
diffstat 2 files changed, 129 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java	Fri Dec 02 17:51:52 2011 +1000
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java	Fri Dec 02 14:28:34 2011 +0000
@@ -346,6 +346,11 @@
                        }
                    }
                }
+               /*
+               ** we need to consume drag events, as we don't want
+               ** the scrollpane itself to be dragged on every mouse click
+               */
+               e.consume();
            }
         });
 
@@ -423,8 +428,12 @@
         TraversalEngine traversalEngine = new TraversalEngine(this, false);
         traversalEngine.addTraverseListener(this);
         setImpl_traversalEngine(traversalEngine);
+
+        // ScrollPanes do not block all MouseEvents by default, unlike most other UI Controls.
+        consumeMouseEvents(false);
     }
 
+
     @Override protected void handleControlPropertyChanged(String p) {
         super.handleControlPropertyChanged(p);
         if (p == "NODE") {
--- a/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ScrollPaneSkinTest.java	Fri Dec 02 17:51:52 2011 +1000
+++ b/javafx-ui-controls/test/com/sun/javafx/scene/control/skin/ScrollPaneSkinTest.java	Fri Dec 02 14:28:34 2011 +0000
@@ -19,8 +19,20 @@
 import javafx.stage.Stage;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
+import com.sun.javafx.pgstub.StubScene;
+import javafx.event.EventHandler;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Stage;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import javafx.scene.input.ScrollEvent;
+
 /**
  * @author mickf
  */
@@ -223,8 +235,115 @@
     }
     
     
+    private boolean scrolled;
+    /*
+    ** check if scrollPane content Horizontal position compensates for content size change
+    */
+    @Test public void checkIfScrollPaneWithinScrollPaneGetsScrollEvents() {
+
+        scrolled = false;
+
+        Rectangle rect = new Rectangle(100, 100, 100, 100);
+        rect.setOnScroll(new EventHandler<ScrollEvent>() {
+            @Override public void handle(ScrollEvent event) {
+                scrolled = true;
+            }
+        });
+        
+        final ScrollPane scrollPaneInner = new ScrollPane();
+        scrollPaneInner.setSkin(new com.sun.javafx.scene.control.skin.ScrollPaneSkin(scrollPaneInner));
+        scrollPaneInner.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+        scrollPaneInner.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+        scrollPaneInner.setPrefWidth(100);
+        scrollPaneInner.setPrefHeight(100);
+        scrollPaneInner.setPannable(true);
+        scrollPaneInner.setContent(rect);
+  
+        Pane pOuter = new Pane();
+        pOuter.setPrefWidth(600);
+        pOuter.setPrefHeight(600);
+        pOuter.getChildren().add(scrollPaneInner);
+        
+        final ScrollPane scrollPaneOuter = new ScrollPane();
+        scrollPaneOuter.setSkin(new com.sun.javafx.scene.control.skin.ScrollPaneSkin(scrollPaneOuter));
+        scrollPaneOuter.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+        scrollPaneOuter.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+        scrollPaneOuter.setPrefWidth(500);
+        scrollPaneOuter.setPrefHeight(500);
+        scrollPaneOuter.setPannable(true);
+        scrollPaneOuter.setOnScroll(new EventHandler<ScrollEvent>() {
+            @Override public void handle(ScrollEvent event) {
+                scrolled = true;
+            }
+        });
+        scrollPaneOuter.setContent(pOuter);
+                
+        Scene scene = new Scene(new Group(), 700, 700);
+        ((Group) scene.getRoot()).getChildren().clear();
+        ((Group) scene.getRoot()).getChildren().add(scrollPaneOuter);
+        scrolled = false;
+
+        Stage stage = new Stage();
+        stage.setScene(scene);
+        stage.show();
+ 
+        Event.fireEvent(rect, 
+              ScrollEvent.impl_scrollEvent(
+                          0.0, -50.0,
+                          ScrollEvent.HorizontalTextScrollUnits.NONE, 10.0,
+                          ScrollEvent.VerticalTextScrollUnits.NONE, 10.0,
+                          50, 50,
+                          50, 50,
+                          false, false, false, false));
+
+        /*
+        ** did it work?
+        */
+        assertTrue(scrollPaneInner.getVvalue() > 0.0);
+    }
     
-    
+
+    boolean sceneClicked = false;
+    /*
+    ** check if unconsumed MouseClicked events on a scrollPane reach it's parent.
+    */
+    @Test public void checkIfScrollPaneConsumesMouseClickedEvents() {
+        ScrollPane scrollPaneInner = new ScrollPane();
+        scrollPaneInner.setSkin(new com.sun.javafx.scene.control.skin.ScrollPaneSkin(scrollPaneInner));
+        scrollPaneInner.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+        scrollPaneInner.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+        scrollPaneInner.setTranslateX(70);
+        scrollPaneInner.setTranslateY(30);
+        scrollPaneInner.setPrefWidth(100);
+        scrollPaneInner.setPrefHeight(100);
+        scrollPaneInner.setPannable(true);     
+
+        Scene scene = new Scene(new Group(), 400, 400);
+        scene.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            public void handle(MouseEvent me) {
+                sceneClicked = true;
+            }
+        });
+        
+        ((Group) scene.getRoot()).getChildren().clear();
+        ((Group) scene.getRoot()).getChildren().add(scrollPaneInner);
+
+        Stage stage = new Stage();
+        stage.setScene(scene);     
+        stage.show();
+
+        Event.fireEvent(scrollPaneInner,
+              MouseEvent.impl_mouseEvent(50.0, 50.0, 50.0, 50.0,
+                         MouseButton.PRIMARY, 1,
+                         false, false, false, false, false,
+                         true, false, false,
+                         MouseEvent.MOUSE_CLICKED));
+
+        /*
+        ** did it work?
+        */
+        assertTrue(sceneClicked == true);
+    }
     
     public static final class ScrollPaneSkinMock extends ScrollPaneSkin {
         boolean propertyChanged = false;