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