1 /*
   2  * Copyright (c) 2010, 2013, 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.stage;
  27 
  28 import com.sun.javafx.FXUnit;
  29 import com.sun.javafx.pgstub.StubToolkit.ScreenConfiguration;
  30 import com.sun.javafx.test.MouseEventGenerator;
  31 import javafx.geometry.BoundingBox;
  32 import javafx.geometry.Point2D;
  33 import javafx.scene.input.KeyCode;
  34 import javafx.scene.input.KeyEvent;
  35 import javafx.scene.input.MouseEvent;
  36 import static org.junit.Assert.assertFalse;
  37 import static org.junit.Assert.assertTrue;
  38 import javafx.event.Event;
  39 import javafx.event.EventHandler;
  40 import javafx.scene.Group;
  41 import javafx.scene.Scene;
  42 import javafx.scene.shape.Rectangle;
  43 
  44 import org.junit.After;
  45 import org.junit.Before;
  46 import org.junit.Ignore;
  47 import org.junit.Rule;
  48 import org.junit.Test;
  49 
  50 import com.sun.javafx.pgstub.StubPopupStage;
  51 import com.sun.javafx.pgstub.StubStage;
  52 import com.sun.javafx.pgstub.StubToolkit;
  53 import com.sun.javafx.tk.Toolkit;
  54 import javafx.geometry.Bounds;
  55 import javafx.scene.Cursor;
  56 import javafx.scene.Parent;
  57 import junit.framework.Assert;
  58 import static org.junit.Assert.assertEquals;
  59 
  60 public class PopupTest {
  61 
  62     @Rule
  63     public FXUnit fx = new FXUnit();
  64 
  65     private StubToolkit toolkit;
  66     private Stage stage;
  67     private Scene scene;
  68     private boolean done = false;
  69 
  70     @Before
  71     public void setUp() {
  72         stage = new Stage();
  73         scene = new Scene(new Group(), 500, 500);
  74         stage.setScene(scene);
  75         stage.show();
  76         done = false;
  77         toolkit = (StubToolkit) Toolkit.getToolkit();
  78     }
  79 
  80     @After
  81     public void tearDown() {
  82         stage.hide();
  83         toolkit.resetScreens();
  84     }
  85 
  86     private void pulse() {
  87         toolkit.fireTestPulse();
  88     }    
  89 
  90     @Test
  91     public void testShow() {
  92         // test showing popup with visible parent
  93         Popup p1 = new Popup();
  94         p1.show(stage);
  95         assertTrue(p1.isShowing());
  96         
  97         // test showing popup with invisible parent
  98         stage.hide();
  99         Popup p2 = new Popup();
 100         p2.show(stage);
 101         assertFalse(p2.isShowing());
 102         
 103         // test showing popup without parent
 104         // TODO should result in an exception
 105 //        Popup p3 = new Popup();
 106 //        p3.show(null);
 107 //        assertFalse(p3.isVisible());
 108     }
 109         
 110     @Test
 111     public void testShowNoAutofix() {
 112         Popup p1 = new Popup();
 113         p1.setAutoFix(false);
 114         p1.show(stage);
 115         assertTrue(p1.isShowing());
 116     }
 117             
 118     @Test
 119     public void testShowLocation() {
 120         Popup p1 = new Popup();
 121         p1.show(stage, 10, 20);
 122         assertTrue(p1.isShowing());
 123         assertEquals(10, p1.getX(), 1e-100);
 124         assertEquals(20, p1.getY(), 1e-100);
 125         pulse();
 126         StubPopupStage peer = (StubPopupStage) p1.impl_getPeer();
 127         assertEquals(10, peer.x, 1e-100);
 128         assertEquals(20, peer.y, 1e-100);
 129     }
 130 
 131     private static final class PopupRoot extends Parent {
 132         private final Rectangle geomBoundsRect;
 133 
 134         private double layoutBoundsX;
 135         private double layoutBoundsY;
 136         private double layoutBoundsWidth;
 137         private double layoutBoundsHeight;
 138 
 139         public PopupRoot() {
 140             geomBoundsRect = new Rectangle(0, 0, 100, 100);
 141             layoutBoundsWidth = 100;
 142             layoutBoundsHeight = 100;
 143 
 144             getChildren().add(geomBoundsRect);
 145         }
 146 
 147         public void setGeomBounds(final double x, final double y,
 148                                   final double width,
 149                                   final double height) {
 150             geomBoundsRect.setX(x);
 151             geomBoundsRect.setY(y);
 152             geomBoundsRect.setWidth(width);
 153             geomBoundsRect.setHeight(height);
 154         }
 155 
 156         public void setLayoutBounds(final double x, final double y,
 157                                     final double width,
 158                                     final double height) {
 159             layoutBoundsX = x;
 160             layoutBoundsY = y;
 161             layoutBoundsWidth = width;
 162             layoutBoundsHeight = height;
 163 
 164             impl_layoutBoundsChanged();
 165         }
 166 
 167         @Override
 168         protected Bounds impl_computeLayoutBounds() {
 169             return new BoundingBox(layoutBoundsX, layoutBoundsY,
 170                                    layoutBoundsWidth, layoutBoundsHeight);
 171         }
 172     }
 173 
 174     @Test
 175     public void testAnchorPositioning() {
 176         final Popup popup = new Popup();
 177         final PopupRoot root = new PopupRoot();
 178 
 179         root.setGeomBounds(-10, 20, 120, 100);
 180         root.setLayoutBounds(0, 0, 100, 140);
 181 
 182         popup.getScene().setRoot(root);
 183 
 184         popup.setAnchorLocation(PopupWindow.AnchorLocation.WINDOW_BOTTOM_RIGHT);
 185         popup.show(stage, 400, 400);
 186 
 187         final StubPopupStage peer = (StubPopupStage) popup.impl_getPeer();
 188 
 189         pulse();
 190         assertEquals(280.0, peer.x, 1e-100);
 191         assertEquals(260.0, peer.y, 1e-100);
 192 
 193         popup.setAnchorLocation(PopupWindow.AnchorLocation.CONTENT_TOP_LEFT);
 194         assertEquals(290.0, popup.getAnchorX(), 1e-100);
 195         assertEquals(260.0, popup.getAnchorY(), 1e-100);
 196 
 197         pulse();
 198         assertEquals(280.0, peer.x, 1e-100);
 199         assertEquals(260.0, peer.y, 1e-100);
 200 
 201         popup.setAnchorX(200);
 202         popup.setAnchorY(100);
 203 
 204         pulse();
 205         assertEquals(190.0, peer.x, 1e-100);
 206         assertEquals(100.0, peer.y, 1e-100);
 207     }
 208 
 209     @Test
 210     public void testAnchorKeepsPositionOnContentChange() {
 211         final Popup popup = new Popup();
 212         final PopupRoot root = new PopupRoot();
 213 
 214         root.setGeomBounds(0, 0, 100, 140);
 215         root.setLayoutBounds(-10, 20, 120, 100);
 216 
 217         popup.getScene().setRoot(root);
 218 
 219         popup.setAnchorLocation(
 220                 PopupWindow.AnchorLocation.CONTENT_BOTTOM_RIGHT);
 221         popup.show(stage, 400, 300);
 222 
 223         final StubPopupStage peer = (StubPopupStage) popup.impl_getPeer();
 224 
 225         assertEquals(280.0, peer.x, 1e-100);
 226         assertEquals(180.0, peer.y, 1e-100);
 227 
 228         root.setLayoutBounds(10, -10, 80, 160);
 229 
 230         pulse();
 231 
 232         assertEquals(400.0, popup.getAnchorX(), 1e-100);
 233         assertEquals(300.0, popup.getAnchorY(), 1e-100);
 234         assertEquals(310.0, peer.x, 1e-100);
 235         assertEquals(140.0, peer.y, 1e-100);
 236     }
 237 
 238     @Test
 239     public void testHide() {
 240         Popup p1 = new Popup();
 241         p1.show(stage);
 242         assertTrue(p1.isShowing());
 243         p1.hide();
 244         assertFalse(p1.isShowing());
 245     }
 246     
 247     @Test
 248     public void testHideAll() {
 249         Popup p1 = new Popup();
 250         p1.show(stage);
 251         Popup p2 = new Popup();
 252         p2.show(p1);
 253         assertTrue(p1.isShowing());
 254         assertTrue(p2.isShowing());
 255         p1.hide();
 256         assertFalse(p1.isShowing());
 257         assertFalse(p2.isShowing());
 258         p1.show(stage);
 259         assertTrue(p1.isShowing());
 260         assertFalse(p2.isShowing());
 261         p1.hide();
 262         assertFalse(p1.isShowing());
 263         assertFalse(p2.isShowing());
 264     }
 265     
 266     @Test
 267     public void testAutoHiding() {
 268         Popup p1 = new Popup();
 269         p1.setAutoHide(true);
 270         p1.show(stage);
 271         
 272         Rectangle rect = new Rectangle();
 273         p1.getContent().add(rect);
 274         rect.requestFocus();
 275         assertTrue(p1.isShowing());
 276       
 277         // hiding popup stage removes the focus (in stubbed environment)
 278         p1.hide();
 279         assertFalse(p1.isShowing());
 280     }
 281 
 282     @Test
 283     public void testAutoHidingWithFocusedChild() {
 284         Popup p1 = new Popup();
 285         p1.setAutoHide(true);
 286         p1.show(stage);
 287         // setting initial focus
 288         Rectangle rect = new Rectangle();
 289         p1.getContent().add(rect);
 290         rect.requestFocus();
 291         assertTrue(p1.isShowing());
 292 
 293         Popup p2 = new Popup();
 294         p2.setAutoHide(true);
 295         p2.show(p1);
 296         Rectangle rect2 = new Rectangle();
 297         p2.getContent().add(rect2);
 298         rect2.requestFocus();
 299         assertTrue(p1.isShowing());
 300         assertTrue(p2.isShowing());
 301 
 302         p1.hide();
 303         // child has focus, popup should stay visible
 304         // Again this should be handled by PopupEventRedirector
 305         // all the AutoHide features are not implemented yet.
 306         //assertTrue(p1.isVisible());
 307     }
 308     
 309     @Test
 310     public void testAutoHidingTree() {
 311         Popup p0 = new Popup();
 312         p0.setAutoHide(true);
 313         p0.show(stage);
 314         // setting initial focus
 315         Rectangle rect = new Rectangle();
 316         p0.getContent().add(rect);
 317         rect.requestFocus();
 318         
 319         Popup p1 = new Popup();
 320         p1.setAutoHide(true);
 321         p1.show(p0);
 322 
 323         Popup p2 = new Popup();
 324         p2.setAutoHide(true);
 325         p2.show(p1);
 326         Rectangle rect2 = new Rectangle();
 327         p2.getContent().add(rect2);
 328         rect2.requestFocus();
 329     
 330         assertTrue(p1.isShowing());
 331         assertTrue(p2.isShowing());
 332         assertTrue(p0.isShowing());
 333 
 334         // after autohide the whole popup tree should be hidden
 335         // up to the parent popup with focus
 336         p2.hide();
 337         // Commenting this assersion for now : need to decide if
 338         // doAutoHide on popup should hide just itself or its parent popup as well.
 339         // PopupEventRedirector should probably take care of it.
 340         //assertFalse(p1.isVisible());
 341         assertFalse(p2.isShowing());
 342         assertTrue(p0.isShowing());
 343     }
 344     
 345     @Test
 346     public void testOnAutohide() {
 347         Popup p1 = new Popup();
 348         p1.setAutoHide(true);
 349         p1.show(stage);
 350         p1.setOnAutoHide(new EventHandler<Event>() {
 351             @Override public void handle(Event e) {
 352                 done = true;
 353             }
 354         });
 355         Rectangle rect = new Rectangle(20, 20, 50, 50);
 356         p1.getContent().add(rect);
 357         assertFalse(done);
 358 
 359         final MouseEventGenerator generator = new MouseEventGenerator();
 360         scene.impl_processMouseEvent(
 361                 generator.generateMouseEvent(
 362                         MouseEvent.MOUSE_PRESSED, 0, 0));
 363 
 364         // test whether runnable ran
 365         assertTrue(done);
 366     }
 367  
 368     
 369     @Ignore ("Not sure how this ever worked, or what the point is")
 370     @Test
 371     public void testPeerListener() {
 372         Popup p = new Popup();
 373         p.setAutoHide(true);
 374         p.show(stage);
 375         
 376         StubPopupStage peer = (StubPopupStage) p.impl_getPeer();
 377         p.sizeToScene();        
 378 
 379         double width = p.getWidth();
 380         double height = p.getHeight();
 381         
 382         // test changing dimensions to same values
 383         p.sizeToScene();        
 384         assertEquals(width, p.getWidth(), 1e-100);
 385         assertEquals(height, p.getHeight(), 1e-100);
 386         
 387         // these methods shouldn't do anything for popups,
 388         // width and height should stay the same
 389         peer.close();
 390         assertEquals(width, p.getWidth(), 1e-100);
 391         assertEquals(height, p.getHeight(), 1e-100);
 392         
 393         peer.setFullScreen(true);
 394         assertEquals(width, p.getWidth(), 1e-100);
 395         assertEquals(height, p.getHeight(), 1e-100);
 396         
 397         peer.setIconified(true);
 398         assertEquals(width, p.getWidth(), 1e-100);
 399         assertEquals(height, p.getHeight(), 1e-100);
 400         
 401         peer.setResizable(true);
 402         assertEquals(width, p.getWidth(), 1e-100);
 403         assertEquals(height, p.getHeight(), 1e-100);
 404         
 405         peer.setLocation(0, 0);
 406         assertEquals(0, p.getX(), 1e-100);
 407         assertEquals(0, p.getY(), 1e-100);
 408         peer.setSize(100, 100);
 409         assertEquals(100, p.getWidth(), 1e-100);
 410         assertEquals(100, p.getHeight(), 1e-100);
 411     }
 412 
 413     @Test
 414     public void testDefautValueOfAutofix() {
 415         Popup p = new Popup();
 416         assertTrue(p.isAutoFix());
 417         assertTrue(p.autoFixProperty().get());
 418     }
 419 
 420     @Test
 421     public void testBasicAutofix() {
 422         toolkit.setScreens(
 423                 new ScreenConfiguration(0, 0, 1920, 1200,
 424                                         0, 200, 1920, 1000,
 425                                         96));
 426 
 427         final Popup popup = new Popup();
 428         popup.getContent().add(new Rectangle(0, 0, 50, 50));
 429         popup.show(stage, 1900, 100);
 430         assertEquals(1920, popup.getX() + popup.getWidth(), 1e-100);
 431         assertEquals(200, popup.getY(), 1e-100);
 432     }
 433 
 434     @Test
 435     public void testDoubleShowAutofix() {
 436         toolkit.setScreens(
 437                 new ScreenConfiguration(0, 0, 1920, 1200,
 438                                         0, 200, 1920, 1000,
 439                                         96));
 440 
 441         final Popup popup = new Popup();
 442         popup.getContent().add(new Rectangle(0, 0, 50, 50));
 443 
 444         popup.show(stage, 1900, 100);
 445         assertEquals(1920, popup.getX() + popup.getWidth(), 1e-100);
 446         assertEquals(200, popup.getY(), 1e-100);
 447 
 448         popup.show(stage, 1900, 100);
 449         assertEquals(1920, popup.getX() + popup.getWidth(), 1e-100);
 450         assertEquals(200, popup.getY(), 1e-100);
 451     }
 452 
 453     @Test
 454     public void testAutofixActivationAfterShow() {
 455         toolkit.setScreens(
 456                 new ScreenConfiguration(0, 0, 1920, 1200,
 457                                         0, 200, 1920, 1000,
 458                                         96));
 459 
 460         final Popup popup = new Popup();
 461         popup.setAutoFix(false);
 462         popup.getContent().add(new Rectangle(0, 0, 50, 50));
 463         popup.show(stage, 1900, 100);
 464 
 465         assertEquals(1900, popup.getX(), 1e-100);
 466         assertEquals(100, popup.getY(), 1e-100);
 467 
 468         popup.setAutoFix(true);
 469         assertEquals(1920, popup.getX() + popup.getWidth(), 1e-100);
 470         assertEquals(200, popup.getY(), 1e-100);
 471     }
 472 
 473     @Test
 474     public void testAutofixOnContentChange() {
 475         toolkit.setScreens(
 476                 new ScreenConfiguration(0, 0, 1920, 1200,
 477                                         0, 0, 1920, 1172,
 478                                         96));
 479 
 480         final Popup popup = new Popup();
 481         popup.getContent().add(new Rectangle(0, 0, 50, 50));
 482         popup.show(stage, 100, 1120);
 483         assertEquals(100, popup.getX(), 1e-100);
 484         assertEquals(1120, popup.getY(), 1e-100);
 485 
 486         popup.getContent().add(new Rectangle(0, 0, 50, 100));
 487         assertEquals(100, popup.getX(), 1e-100);
 488         assertEquals(1172, popup.getY() + popup.getHeight(), 1e-100);
 489     }
 490 
 491     @Test
 492     public void testAutofixOnScreenChange() {
 493         toolkit.setScreens(
 494                 new ScreenConfiguration(0, 0, 1920, 1200,
 495                                         0, 0, 1920, 1172,
 496                                         96));
 497 
 498         final Popup popup = new Popup();
 499         popup.getContent().add(new Rectangle(0, 0, 50, 50));
 500         popup.show(stage, 100, 1120);
 501         assertEquals(100, popup.getX(), 1e-100);
 502         assertEquals(1120, popup.getY(), 1e-100);
 503 
 504         toolkit.setScreens(
 505                 new ScreenConfiguration(0, 0, 1920, 1200,
 506                                         120, 0, 1800, 1172,
 507                                         96));
 508 
 509         assertEquals(120, popup.getX(), 1e-100);
 510         assertEquals(1120, popup.getY(), 1e-100);
 511     }
 512 
 513     @Test
 514     public void testAutofixWithFullScreen() {
 515         toolkit.setScreens(
 516                 new ScreenConfiguration(0, 0, 1920, 1200,
 517                                         0, 0, 1920, 1172,
 518                                         96));
 519 
 520         final Popup popup = new Popup();
 521         popup.getContent().add(new Rectangle(0, 0, 50, 50));
 522 
 523         stage.setFullScreen(true);
 524         popup.show(stage, 100, 1160);
 525 
 526         assertEquals(100, popup.getX(), 1e-100);
 527         assertEquals(1150, popup.getY(), 1e-100);
 528     }
 529 
 530     @Test
 531     public void testSetPopupContentByChangingRootNode() {
 532         final Popup popup = new Popup();
 533 
 534         popup.getScene().setRoot(new Group(new Rectangle(0, 0, 300, 200)));
 535         assertEquals(300, popup.getWidth(), 1e-100);
 536         assertEquals(200, popup.getHeight(), 1e-100);
 537 
 538         popup.getScene().setRoot(new Group(new Rectangle(0, 0, 200, 300)));
 539         assertEquals(200, popup.getWidth(), 1e-100);
 540         assertEquals(300, popup.getHeight(), 1e-100);
 541     }
 542 
 543     @Test
 544     public void testConsumeAutoHidingEventsProperty() {
 545         final EventCounter mouseEventCounter = new EventCounter();
 546         final EventCounter keyEventCounter = new EventCounter();
 547 
 548         stage.addEventHandler(MouseEvent.MOUSE_PRESSED, mouseEventCounter);
 549         stage.addEventHandler(KeyEvent.KEY_PRESSED, keyEventCounter);
 550         try {
 551             final MouseEventGenerator mouseEventGenerator =
 552                     new MouseEventGenerator();
 553 
 554             final Popup popup = new Popup();
 555             popup.setAutoHide(true);
 556 
 557             assertTrue(popup.getConsumeAutoHidingEvents());
 558 
 559             popup.show(stage);
 560             Event.fireEvent(stage,
 561                             mouseEventGenerator.generateMouseEvent(
 562                                 MouseEvent.MOUSE_PRESSED, 0, 0));
 563             assertEquals(0, mouseEventCounter.getValue());
 564 
 565             popup.show(stage);
 566             Event.fireEvent(stage,
 567                             new KeyEvent(null, stage,
 568                                 KeyEvent.KEY_PRESSED, KeyEvent.CHAR_UNDEFINED,
 569                                 KeyCode.ESCAPE.getName(),
 570                                 KeyCode.ESCAPE,
 571                                 false, false, false, false));
 572             assertEquals(0, keyEventCounter.getValue());
 573 
 574             popup.setConsumeAutoHidingEvents(false);
 575 
 576             popup.show(stage);
 577             Event.fireEvent(stage,
 578                             mouseEventGenerator.generateMouseEvent(
 579                                 MouseEvent.MOUSE_PRESSED, 0, 0));
 580             assertEquals(1, mouseEventCounter.getValue());
 581 
 582             popup.show(stage);
 583             Event.fireEvent(stage,
 584                             new KeyEvent(null, stage,
 585                                 KeyEvent.KEY_PRESSED,
 586                                 KeyEvent.CHAR_UNDEFINED,
 587                                 KeyCode.ESCAPE.getName(),
 588                                 KeyCode.ESCAPE,
 589                                 false, false, false, false));
 590             assertEquals(1, keyEventCounter.getValue());
 591             
 592         } finally {
 593             stage.removeEventHandler(MouseEvent.MOUSE_PRESSED,
 594                                      mouseEventCounter);
 595             stage.removeEventHandler(KeyEvent.KEY_PRESSED, keyEventCounter);
 596         }
 597     }
 598 
 599     @Test(expected=NullPointerException.class)
 600     public void testShowWithNullOwner() {
 601         final Popup popup = new Popup();
 602         popup.show(null);
 603     }
 604 
 605     @Test(expected=NullPointerException.class)
 606     public void testShowXYWithNullOwner() {
 607         final Popup popup = new Popup();
 608         popup.show((Window) null, 10, 10);
 609     }
 610 
 611     @Test(expected=IllegalArgumentException.class)
 612     public void testShowWithOwnerThatWouldCreateCycle1() {
 613         final Popup popup = new Popup();
 614         popup.show(popup);                
 615     }
 616 
 617     @Test(expected=IllegalArgumentException.class)
 618     public void testShowWithOwnerThatWouldCreateCycle2() {
 619         final Popup popup1 = new Popup();
 620         final Popup popup2 = new Popup();
 621 
 622         popup1.show(stage);
 623         popup2.show(popup1);
 624         popup1.hide();
 625         popup1.show(popup2);
 626     }
 627 
 628     @Test(expected=IllegalArgumentException.class)
 629     public void testShowXYWithOwnerThatWouldCreateCycle1() {
 630         final Popup popup = new Popup();
 631         popup.show(popup, 10, 20);
 632     }
 633 
 634     @Test(expected=IllegalArgumentException.class)
 635     public void testShowXYWithOwnerThatWouldCreateCycle2() {
 636         final Popup popup1 = new Popup();
 637         final Popup popup2 = new Popup();
 638 
 639         popup1.show(stage);
 640         popup2.show(popup1);
 641         popup1.hide();
 642         popup1.show(popup2, 10, 20);
 643     }
 644 
 645     @Test
 646     public void testFocusGrabbedWhenNecessary() {
 647         final Popup popup = new Popup();
 648 
 649         popup.show(stage);
 650         stage.requestFocus();
 651 
 652         final StubStage peer = (StubStage) stage.impl_getPeer();
 653         assertFalse(peer.isFocusGrabbed());
 654 
 655         popup.setAutoHide(true);
 656         assertTrue(peer.isFocusGrabbed());
 657 
 658         popup.hide();
 659         assertFalse(peer.isFocusGrabbed());
 660     }
 661 
 662     @Test
 663     public void testPopupRootStyle() {
 664         final Popup popup = new Popup();
 665 
 666         final Parent oldRoot = popup.getScene().getRoot();
 667         Assert.assertTrue(oldRoot.getStyleClass().contains("popup"));
 668 
 669         final Group newRoot = new Group(new Rectangle(0, 0, 200, 300));
 670         popup.getScene().setRoot(newRoot);
 671 
 672         Assert.assertTrue(newRoot.getStyleClass().contains("popup"));
 673         Assert.assertFalse(oldRoot.getStyleClass().contains("popup"));
 674 
 675         System.out.println(javafx.scene.shape.Sphere.class.getResource("Sphere.class"));
 676     }
 677     
 678     @Test
 679     public void testCursorInheritance() {
 680         stage.getScene().setCursor(Cursor.CLOSED_HAND);
 681         
 682         final Popup popup = new Popup();
 683 
 684         popup.show(stage);
 685         assertEquals(Cursor.CLOSED_HAND, popup.getScene().getCursor());
 686 
 687     }
 688 
 689     private static final class EventCounter implements EventHandler<Event> {
 690         private int counter;
 691 
 692         public int getValue() {
 693             return counter;
 694         }
 695 
 696         public void handle(final Event event) {
 697             ++counter;
 698         }
 699     }
 700 }