1 /*
   2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.control.skin;
  27 
  28 import static org.junit.Assert.assertEquals;
  29 import static org.junit.Assert.assertTrue;
  30 
  31 import javafx.beans.value.ObservableValue;
  32 import javafx.event.Event;
  33 import javafx.event.EventType;
  34 import javafx.scene.Group;
  35 import javafx.scene.Scene;
  36 import javafx.scene.control.Button;
  37 import javafx.scene.control.CheckBox;
  38 import javafx.scene.control.Label;
  39 import javafx.scene.control.RadioButton;
  40 import javafx.scene.control.ScrollPane;
  41 import javafx.scene.input.*;
  42 import javafx.scene.layout.HBox;
  43 import javafx.scene.layout.Pane;
  44 import javafx.scene.layout.StackPane;
  45 import javafx.scene.layout.VBox;
  46 import javafx.scene.shape.Rectangle;
  47 import javafx.stage.Stage;
  48 
  49 import org.junit.Before;
  50 import org.junit.Ignore;
  51 import org.junit.Test;
  52 
  53 
  54 /**
  55  * @author mickf
  56  */
  57 public class ScrollPaneSkinTest {
  58     private ScrollPane scrollPane;
  59     private ScrollPaneSkinMock skin;
  60 
  61     @Before public void setup() {
  62         scrollPane = new ScrollPane();
  63         skin = new ScrollPaneSkinMock(scrollPane);
  64         scrollPane.setSkin(skin);
  65     }
  66 
  67     /*
  68     ** RT-16641 : root cause, you shouldn't be able to drag
  69     ** contents if they don't fill the scrollpane
  70     */
  71     @Test public void shouldntDragContentSmallerThanViewport() {
  72         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
  73         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
  74 
  75         StackPane sp = new StackPane();
  76         sp.setPrefWidth(80);
  77         sp.setPrefHeight(80);
  78 
  79         scrollPane.setContent(sp);
  80         scrollPane.setTranslateX(70);
  81         scrollPane.setTranslateY(30);
  82         scrollPane.setPrefWidth(100);
  83         scrollPane.setPrefHeight(100);
  84         scrollPane.setPannable(true);
  85 
  86         MouseEventGenerator generator = new MouseEventGenerator();
  87 
  88         Scene scene = new Scene(new Group(), 400, 400);
  89         ((Group) scene.getRoot()).getChildren().clear();
  90         ((Group) scene.getRoot()).getChildren().add(scrollPane);
  91         Stage stage = new Stage();
  92         stage.setScene(scene);
  93         stage.show();
  94 
  95         double originalValue = scrollPane.getVvalue();
  96 
  97         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50));
  98         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 75, 75));
  99         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 75, 75));
 100 
 101         assertEquals(originalValue, scrollPane.getVvalue(), 0.01);
 102 
 103     }
 104 
 105     /*
 106      * check we can drag contents that are larger than the scrollpane
 107      */
 108     @Test public void shouldDragContentLargerThanViewport() {
 109         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 110         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 111 
 112         StackPane sp = new StackPane();
 113         sp.setPrefWidth(180);
 114         sp.setPrefHeight(180);
 115 
 116         scrollPane.setContent(sp);
 117         scrollPane.setTranslateX(70);
 118         scrollPane.setTranslateY(30);
 119         scrollPane.setPrefWidth(100);
 120         scrollPane.setPrefHeight(100);
 121         scrollPane.setPannable(true);
 122 
 123         MouseEventGenerator generator = new MouseEventGenerator();
 124 
 125         Scene scene = new Scene(new Group(), 400, 400);
 126         ((Group) scene.getRoot()).getChildren().clear();
 127         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 128         Stage stage = new Stage();
 129         stage.setScene(scene);
 130         stage.show();
 131 
 132         double originalValue = scrollPane.getVvalue();
 133 
 134         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 75, 75));
 135         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 50, 50));
 136         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50));
 137 
 138         assertTrue(originalValue < scrollPane.getVvalue());
 139     }
 140 
 141 
 142     boolean continueTest;
 143     class myPane extends Pane {
 144         public void growH() {
 145             setHeight(300);
 146         }
 147        public void growW() {
 148             setWidth(300);
 149         }
 150 
 151     }
 152     myPane pInner;
 153 
 154     /*
 155     ** check if scrollPane content vertical position compensates for content size change
 156     */
 157     @Test public void checkPositionOnContentSizeChangeHeight() {
 158         pInner = new myPane();
 159         pInner.setPrefWidth(200);
 160         pInner.setPrefHeight(200);
 161 
 162         scrollPane.setContent(pInner);
 163         scrollPane.setPrefWidth(100);
 164         scrollPane.setPrefHeight(100);
 165 
 166         Scene scene = new Scene(new Group(), 400, 400);
 167         ((Group) scene.getRoot()).getChildren().clear();
 168         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 169         Stage stage = new Stage();
 170         stage.setScene(scene);
 171         stage.show();
 172 
 173         double originalValue = 0.5;
 174         scrollPane.setVvalue(originalValue);
 175 
 176         continueTest = false;
 177         scrollPane.vvalueProperty().addListener((observable, oldBounds, newBounds) -> {
 178             continueTest = true;
 179         });
 180 
 181         /*
 182         ** increase the height of the content
 183         */
 184         pInner.growH();
 185 
 186         int count = 0;
 187         while (continueTest == false && count < 10) {
 188             try {
 189                 Thread.sleep(100);
 190             }
 191             catch (Exception e) {}
 192             count++;
 193         }
 194 
 195         /*
 196         ** did it work?
 197         */
 198         assertTrue(originalValue > scrollPane.getVvalue() && scrollPane.getVvalue() > 0.0);
 199     }
 200 
 201 
 202     /*
 203     ** check if scrollPane content Horizontal position compensates for content size change
 204     */
 205     @Test public void checkPositionOnContentSizeChangeWidth() {
 206 
 207         pInner = new myPane();
 208         pInner.setPrefWidth(200);
 209         pInner.setPrefHeight(200);
 210 
 211         scrollPane.setContent(pInner);
 212         scrollPane.setPrefWidth(100);
 213         scrollPane.setPrefHeight(100);
 214 
 215         Scene scene = new Scene(new Group(), 400, 400);
 216         ((Group) scene.getRoot()).getChildren().clear();
 217         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 218         Stage stage = new Stage();
 219         stage.setScene(scene);
 220         stage.show();
 221 
 222         double originalValue = 0.5;
 223         scrollPane.setHvalue(originalValue);
 224 
 225         continueTest = false;
 226         scrollPane.hvalueProperty().addListener((observable, oldBounds, newBounds) -> {
 227             continueTest = true;
 228         });
 229 
 230         /*
 231         ** increase the width of the content
 232         */
 233         pInner.growW();
 234 
 235         int count = 0;
 236         while (continueTest == false && count < 10) {
 237             try {
 238                 Thread.sleep(100);
 239             }
 240             catch (Exception e) {}
 241             count++;
 242         }
 243 
 244         /*
 245         ** did it work?
 246         */
 247         assertTrue(originalValue > scrollPane.getHvalue() && scrollPane.getHvalue() > 0.0);
 248     }
 249 
 250 
 251     private boolean scrolled;
 252     /*
 253     ** check if scrollPane content Horizontal position compensates for content size change
 254     */
 255     @Test public void checkIfScrollPaneWithinScrollPaneGetsScrollEvents() {
 256 
 257         scrolled = false;
 258 
 259         Rectangle rect = new Rectangle(100, 100, 100, 100);
 260         rect.setOnScroll(event -> {
 261             scrolled = true;
 262         });
 263 
 264         final ScrollPane scrollPaneInner = new ScrollPane();
 265         scrollPaneInner.setSkin(new ScrollPaneSkin(scrollPaneInner));
 266         scrollPaneInner.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 267         scrollPaneInner.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 268         scrollPaneInner.setPrefWidth(100);
 269         scrollPaneInner.setPrefHeight(100);
 270         scrollPaneInner.setPannable(true);
 271         scrollPaneInner.setContent(rect);
 272 
 273         Pane pOuter = new Pane();
 274         pOuter.setPrefWidth(600);
 275         pOuter.setPrefHeight(600);
 276         pOuter.getChildren().add(scrollPaneInner);
 277 
 278         final ScrollPane scrollPaneOuter = new ScrollPane();
 279         scrollPaneOuter.setSkin(new ScrollPaneSkin(scrollPaneOuter));
 280         scrollPaneOuter.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 281         scrollPaneOuter.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 282         scrollPaneOuter.setPrefWidth(500);
 283         scrollPaneOuter.setPrefHeight(500);
 284         scrollPaneOuter.setPannable(true);
 285         scrollPaneOuter.setOnScroll(event -> {
 286             scrolled = true;
 287         });
 288         scrollPaneOuter.setContent(pOuter);
 289 
 290         Scene scene = new Scene(new Group(), 700, 700);
 291         ((Group) scene.getRoot()).getChildren().clear();
 292         ((Group) scene.getRoot()).getChildren().add(scrollPaneOuter);
 293         scrolled = false;
 294 
 295         Stage stage = new Stage();
 296         stage.setScene(scene);
 297         stage.show();
 298 
 299         Event.fireEvent(rect,
 300               new ScrollEvent(ScrollEvent.SCROLL,
 301                           50, 50,
 302                           50, 50,
 303                           false, false, false, false, true, false,
 304                           0.0, -50.0, 0.0, -50.0,
 305                           ScrollEvent.HorizontalTextScrollUnits.NONE, 10.0,
 306                           ScrollEvent.VerticalTextScrollUnits.NONE, 10.0,
 307                           0, null));
 308 
 309         /*
 310         ** did it work?
 311         */
 312         assertTrue(scrollPaneInner.getVvalue() > 0.0);
 313     }
 314 
 315 
 316     boolean sceneClicked = false;
 317     /*
 318     ** check if unconsumed MouseClicked events on a scrollPane reach it's parent.
 319     */
 320     @Test public void checkIfScrollPaneConsumesMouseClickedEvents() {
 321         ScrollPane scrollPaneInner = new ScrollPane();
 322         scrollPaneInner.setSkin(new ScrollPaneSkin(scrollPaneInner));
 323         scrollPaneInner.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 324         scrollPaneInner.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 325         scrollPaneInner.setTranslateX(70);
 326         scrollPaneInner.setTranslateY(30);
 327         scrollPaneInner.setPrefWidth(100);
 328         scrollPaneInner.setPrefHeight(100);
 329         scrollPaneInner.setPannable(true);
 330 
 331         Scene scene = new Scene(new Group(), 400, 400);
 332         scene.setOnMouseClicked(me -> {
 333             sceneClicked = true;
 334         });
 335 
 336         ((Group) scene.getRoot()).getChildren().clear();
 337         ((Group) scene.getRoot()).getChildren().add(scrollPaneInner);
 338 
 339         Stage stage = new Stage();
 340         stage.setScene(scene);
 341         stage.show();
 342 
 343         Event.fireEvent(scrollPaneInner,
 344               new MouseEvent(MouseEvent.MOUSE_CLICKED, 50.0, 50.0, 50.0, 50.0,
 345                          MouseButton.PRIMARY, 1,
 346                          false, false, false, false, false,
 347                          true, false, false, false, false, null
 348                          ));
 349 
 350         /*
 351         ** did it work?
 352         */
 353         assertTrue(sceneClicked == true);
 354     }
 355 
 356     /*
 357     ** check if ScrollPane gets focus on unconsumed mousePressed
 358     */
 359     @Test public void checkIfScrollPaneFocusesPressedEvents() {
 360         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 361         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 362 
 363         StackPane sp = new StackPane();
 364         sp.setPrefWidth(80);
 365         sp.setPrefHeight(80);
 366 
 367         scrollPane.setContent(sp);
 368         scrollPane.setTranslateX(70);
 369         scrollPane.setTranslateY(30);
 370         scrollPane.setPrefWidth(100);
 371         scrollPane.setPrefHeight(100);
 372         scrollPane.setPannable(true);
 373 
 374         MouseEventGenerator generator = new MouseEventGenerator();
 375 
 376         Scene scene = new Scene(new Group(), 400, 400);
 377         ((Group) scene.getRoot()).getChildren().clear();
 378         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 379         Stage stage = new Stage();
 380         stage.setScene(scene);
 381         stage.show();
 382 
 383         double originalValue = scrollPane.getVvalue();
 384 
 385         Event.fireEvent(sp, generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50));
 386 
 387         /*
 388         ** did it work?
 389         */
 390         assertTrue(scene.getFocusOwner() == scrollPane);
 391     }
 392 
 393     /*
 394     ** check if ScrollPane gets focus on unconsumed mousePressed
 395     */
 396     @Test public void checkIfScrollPaneViewportIsRounded() {
 397         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 398         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
 399 
 400         StackPane sp = new StackPane();
 401         sp.setPrefWidth(80);
 402         sp.setPrefHeight(80);
 403 
 404         scrollPane.setContent(sp);
 405         scrollPane.setTranslateX(70);
 406         scrollPane.setTranslateY(30);
 407         scrollPane.setPrefViewportWidth(100.5);
 408         scrollPane.setPrefHeight(100);
 409         scrollPane.setPannable(true);
 410 
 411         Scene scene = new Scene(new Group(), 400, 400);
 412         ((Group) scene.getRoot()).getChildren().clear();
 413         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 414         Stage stage = new Stage();
 415         stage.setScene(scene);
 416         stage.show();
 417 
 418         /*
 419         ** did it work?
 420         */
 421         assertTrue(scrollPane.getViewportBounds().getWidth() == Math.ceil(100.5));
 422     }
 423 
 424     /*
 425     ** check ScrollBars missing if fitToHeight is true but height is > minHeight
 426     */
 427     @Test public void checkNoScrollbarsWhenFitToAndSizeOK() {
 428         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 429         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 430 
 431         StackPane sp = new StackPane();
 432         sp.setPrefWidth(80);
 433         sp.setPrefHeight(80);
 434         sp.setMinWidth(40);
 435         sp.setMinHeight(40);
 436 
 437         scrollPane.setPrefSize(50, 50);
 438         scrollPane.setContent(sp);
 439         scrollPane.setPannable(true);
 440         scrollPane.setFitToWidth(true);
 441         scrollPane.setFitToHeight(true);
 442 
 443         Scene scene = new Scene(new Group(), 400, 400);
 444         ((Group) scene.getRoot()).getChildren().clear();
 445         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 446         Stage stage = new Stage();
 447         stage.setScene(scene);
 448         stage.show();
 449 
 450         /*
 451         ** did it work?
 452         */
 453         assertTrue(!skin.isHSBarVisible() & !skin.isVSBarVisible());
 454     }
 455 
 456     /*
 457     ** check if ScrollBars appear if fitToHeight is true but height is < minHeight
 458     */
 459     @Test public void checkIfScrollbarsWhenFitToHeightAndHeightLessMin() {
 460         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 461         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 462 
 463         StackPane sp = new StackPane();
 464         sp.setPrefWidth(80);
 465         sp.setPrefHeight(80);
 466         sp.setMinWidth(40);
 467         sp.setMinHeight(40);
 468 
 469         // see comments in checkIfScrollbarsWhenFitToWidthAndWidthLessMin for why width is 60
 470         scrollPane.setPrefSize(60, 30);
 471         scrollPane.setContent(sp);
 472         scrollPane.setPannable(true);
 473         scrollPane.setFitToWidth(true);
 474         scrollPane.setFitToHeight(true);
 475 
 476         Scene scene = new Scene(new Group(), 400, 400);
 477         ((Group) scene.getRoot()).getChildren().clear();
 478         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 479         Stage stage = new Stage();
 480         stage.setScene(scene);
 481         stage.show();
 482 
 483         /*
 484         ** did it work?
 485         */
 486         assertTrue(!skin.isHSBarVisible() & skin.isVSBarVisible());
 487     }
 488 
 489     /*
 490     ** check if ScrollBars appear if fitToWidth is true but width is < minWidth
 491     */
 492     @Test public void checkIfScrollbarsWhenFitToWidthAndWidthLessMin() {
 493         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 494         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 495 
 496         StackPane sp = new StackPane();
 497         sp.setPrefWidth(80);
 498         sp.setPrefHeight(80);
 499         sp.setMinWidth(40);
 500         sp.setMinHeight(40);
 501 
 502         // set width < content minWidth, should get horizontal scroll bar
 503         // set height > content minHeight, should not get vertical scroll bar
 504         // Note that the scrollPane's height has to be big enough to fit both the
 505         // horizontal ScrollBar and the re-sized content. If the ScrollBar's height
 506         // is 16, then the scrollPane's prefHeight needs to be 16 plus the content's
 507         // minHeight of 40 plus one pixel (since the content and the ScrollBar don't
 508         // overlap), all of which adds up to 57. Originally, this test had the height
 509         // set to 50 which caused the vertical ScrollBar to be visible.
 510         scrollPane.setPrefSize(30, 60);
 511         scrollPane.setContent(sp);
 512         scrollPane.setPannable(true);
 513         scrollPane.setFitToWidth(true);
 514         scrollPane.setFitToHeight(true);
 515 
 516         Scene scene = new Scene(new Group(), 400, 400);
 517         ((Group) scene.getRoot()).getChildren().clear();
 518         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 519         Stage stage = new Stage();
 520         stage.setScene(scene);
 521         stage.show();
 522 
 523         /*
 524         ** did it work?
 525         */
 526         assertTrue(skin.isHSBarVisible() & !skin.isVSBarVisible());
 527     }
 528 
 529     /*
 530     ** check if ScrollBars appear if fitToHeight & fitToWidth are true but height is < minHeight & width is < minWidth
 531     */
 532     @Test public void checkIfScrollbarsWhenBothFitToAndBothLessMin() {
 533         scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 534         scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
 535 
 536         StackPane sp = new StackPane();
 537         sp.setPrefWidth(80);
 538         sp.setPrefHeight(80);
 539         sp.setMinWidth(40);
 540         sp.setMinHeight(40);
 541 
 542         scrollPane.setPrefSize(60, 30);
 543         scrollPane.setContent(sp);
 544         scrollPane.setPannable(true);
 545         scrollPane.setFitToWidth(true);
 546         scrollPane.setFitToHeight(true);
 547 
 548         Scene scene = new Scene(new Group(), 400, 400);
 549         ((Group) scene.getRoot()).getChildren().clear();
 550         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 551         Stage stage = new Stage();
 552         stage.setScene(scene);
 553         stage.show();
 554 
 555         /*
 556         ** did it work?
 557         */
 558         assertTrue(!skin.isHSBarVisible() & skin.isVSBarVisible());
 559     }
 560 
 561     /*
 562     ** check if ScrollBars appear if fitToHeight & fitToWidth are true but height is < minHeight & width is < minWidth
 563     */
 564     @Test public void checkWeHandleNullContent() {
 565 
 566 
 567         scrollPane.setFitToWidth(true);
 568 
 569         Scene scene = new Scene(scrollPane);
 570 
 571         Stage stage = new Stage();
 572         stage.setScene(scene);
 573 
 574         stage.setWidth(600);
 575         stage.setHeight(600);
 576 
 577         stage.show();
 578 
 579     }
 580 
 581 
 582     /*
 583     ** check if 'reduced-size' scrollbars leave a gap
 584     ** at the right edge
 585     */
 586     @Test public void checkForScrollBarGaps() {
 587 
 588         HBox hbox1 = new HBox(20);
 589         VBox vbox1a = new VBox(10);
 590         vbox1a.getChildren().addAll(new Label("one"), new Button("two"), new CheckBox("three"), new RadioButton("four"), new Label("five"));
 591         VBox vbox1b = new VBox(10);
 592         vbox1b.getChildren().addAll(new Label("one"), new Button("two"), new CheckBox("three"), new RadioButton("four"), new Label("five"));
 593         hbox1.getChildren().addAll(vbox1a, vbox1b);
 594         scrollPane.setContent(hbox1);
 595         scrollPane.setStyle("-fx-background-color: red;-fx-border-color:green;");
 596         scrollPane.setFocusTraversable(false);
 597         scrollPane.setPrefSize(50, 50);
 598 
 599 
 600         Scene scene = new Scene(new Group(), 400, 400);
 601         ((Group) scene.getRoot()).getChildren().clear();
 602         ((Group) scene.getRoot()).getChildren().add(scrollPane);
 603         Stage stage = new Stage();
 604         stage.setScene(scene);
 605         stage.show();
 606 
 607 
 608         /*
 609         ** did it work?
 610         ** check that the scrollbar is right at the border of the scrollpane, and
 611         ** not at the padding.
 612         */
 613         ScrollPaneSkinMock skin = (ScrollPaneSkinMock) scrollPane.getSkin();
 614 
 615         double skinWidth = scrollPane.getWidth();
 616         double right = scrollPane.getPadding().getRight();
 617         // 1 px of padding is on the outside - see RT-21251
 618         double vsbPosAndWidth = (right >= 1 ? 1 : 0) + skin.getVsbX()+skin.getVsbWidth()+(scrollPane.getInsets().getRight() - right);
 619         assertEquals(skinWidth,  vsbPosAndWidth, 0.1);
 620 
 621         double skinHeight = scrollPane.getHeight();
 622         // 1 px of padding is on the outside - see RT-21251
 623         double bottom = scrollPane.getPadding().getBottom();
 624         double hsbPosAndHeight = (bottom >= 1 ? 1 : 0) + skin.getHsbY()+skin.getHsbHeight()+(scrollPane.getInsets().getBottom() - bottom);
 625         assertEquals(skinHeight,  hsbPosAndHeight, 0.1);
 626 
 627     }
 628 
 629     /*
 630     ** check if scrollPane content Horizontal position compensates for content size change
 631     ** ignored, as we do swipe through ScrollEvents.
 632     */
 633     @Ignore
 634     @Test public void checkIfSwipeDownEventsChangeAnything() {
 635 
 636         scrolled = false;
 637 
 638         Rectangle rect = new Rectangle(200, 200, 200, 200);
 639 
 640         final ScrollPane scrollPaneInner = new ScrollPane();
 641         scrollPaneInner.setSkin(new ScrollPaneSkin(scrollPaneInner));
 642         scrollPaneInner.setPrefWidth(100);
 643         scrollPaneInner.setPrefHeight(100);
 644         scrollPaneInner.setPannable(true);
 645         scrollPaneInner.setContent(rect);
 646         scrollPaneInner.setOnSwipeUp(event -> {
 647             scrolled = true;
 648         });
 649         scrollPaneInner.setOnSwipeDown(event -> {
 650             scrolled = true;
 651         });
 652         scrollPaneInner.setOnSwipeLeft(event -> {
 653             scrolled = true;
 654         });
 655         scrollPaneInner.setOnSwipeRight(event -> {
 656             scrolled = true;
 657         });
 658         Pane pOuter = new Pane();
 659         pOuter.setPrefWidth(600);
 660         pOuter.setPrefHeight(600);
 661 
 662         Scene scene = new Scene(new Group(), 700, 700);
 663         ((Group) scene.getRoot()).getChildren().clear();
 664         ((Group) scene.getRoot()).getChildren().add(scrollPaneInner);
 665 
 666         Stage stage = new Stage();
 667         stage.setScene(scene);
 668         stage.show();
 669 
 670         Event.fireEvent(rect,
 671          new SwipeEvent(SwipeEvent.SWIPE_DOWN,
 672             0.0, -50.0,
 673             0.0, -50.0,
 674             false,
 675             false,
 676             false,
 677             false,
 678             false,
 679             1,
 680             null
 681             ));
 682 
 683         /*
 684         ** did it work?
 685         */
 686         assertTrue(scrollPaneInner.getVvalue() > 0.0);
 687     }
 688 
 689     /*
 690     ** check if scrollPane content Horizontal position compensates for content size change
 691     ** ignored, as we do swipe through ScrollEvents.
 692     */
 693     @Ignore
 694     @Test public void checkIfSwipeRightEventsChangeAnything() {
 695 
 696         scrolled = false;
 697 
 698         Rectangle rect = new Rectangle(200, 200, 200, 200);
 699 
 700         final ScrollPane scrollPaneInner = new ScrollPane();
 701         scrollPaneInner.setSkin(new ScrollPaneSkin(scrollPaneInner));
 702         scrollPaneInner.setPrefWidth(100);
 703         scrollPaneInner.setPrefHeight(100);
 704         scrollPaneInner.setPannable(true);
 705         scrollPaneInner.setContent(rect);
 706         scrollPaneInner.setOnSwipeUp(event -> {
 707             scrolled = true;
 708         });
 709         scrollPaneInner.setOnSwipeDown(event -> {
 710             scrolled = true;
 711         });
 712         scrollPaneInner.setOnSwipeLeft(event -> {
 713             scrolled = true;
 714         });
 715         scrollPaneInner.setOnSwipeRight(event -> {
 716             scrolled = true;
 717         });
 718         Pane pOuter = new Pane();
 719         pOuter.setPrefWidth(600);
 720         pOuter.setPrefHeight(600);
 721 
 722         Scene scene = new Scene(new Group(), 700, 700);
 723         ((Group) scene.getRoot()).getChildren().clear();
 724         ((Group) scene.getRoot()).getChildren().add(scrollPaneInner);
 725 
 726         Stage stage = new Stage();
 727         stage.setScene(scene);
 728         stage.show();
 729 
 730         Event.fireEvent(rect,
 731             new SwipeEvent(SwipeEvent.SWIPE_RIGHT,
 732             0.0, -50.0,
 733             0.0, -50.0,
 734             false,
 735             false,
 736             false,
 737             false,
 738             false,
 739             1,
 740             null
 741             ));
 742 
 743          /*
 744          ** did it work?
 745          */
 746         assertTrue(scrollPaneInner.getHvalue() > 0.0);
 747     }
 748 
 749 
 750 
 751     public static final class ScrollPaneSkinMock extends ScrollPaneSkin {
 752         boolean propertyChanged = false;
 753         int propertyChangeCount = 0;
 754         public ScrollPaneSkinMock(ScrollPane scrollPane) {
 755             super(scrollPane);
 756         }
 757 
 758         public void addWatchedProperty(ObservableValue<?> p) {
 759             p.addListener(o -> {
 760                 propertyChanged = true;
 761                 propertyChangeCount++;
 762             });
 763         }
 764 
 765         boolean isHSBarVisible() {
 766             return hsb.isVisible();
 767         }
 768 
 769         boolean isVSBarVisible() {
 770             return vsb.isVisible();
 771         }
 772         double getVsbX() {
 773             return vsb.getLayoutX();
 774         }
 775         double getVsbWidth() {
 776             return vsb.getWidth();
 777         }
 778         double getHsbY() {
 779             return hsb.getLayoutY();
 780         }
 781         double getHsbHeight() {
 782             return hsb.getHeight();
 783         }
 784     }
 785 
 786     private static class MouseEventGenerator {
 787         private boolean primaryButtonDown = false;
 788 
 789         public MouseEvent generateMouseEvent(EventType<MouseEvent> type,
 790                 double x, double y) {
 791 
 792             MouseButton button = MouseButton.NONE;
 793             if (type == MouseEvent.MOUSE_PRESSED ||
 794                     type == MouseEvent.MOUSE_RELEASED ||
 795                     type == MouseEvent.MOUSE_DRAGGED) {
 796                 button = MouseButton.PRIMARY;
 797             }
 798 
 799             if (type == MouseEvent.MOUSE_PRESSED ||
 800                     type == MouseEvent.MOUSE_DRAGGED) {
 801                 primaryButtonDown = true;
 802             }
 803 
 804             if (type == MouseEvent.MOUSE_RELEASED) {
 805                 primaryButtonDown = false;
 806             }
 807 
 808             MouseEvent event = new MouseEvent(type, x, y, x, y, button,
 809                     1, false, false, false, false, false, primaryButtonDown,
 810                     false, false, false, false, null);
 811 
 812             return event;
 813         }
 814     }
 815 }