1 /*
   2  * Copyright (c) 2000, 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;
  27 
  28 import com.sun.javafx.test.MouseEventGenerator;
  29 import static org.junit.Assert.*;
  30 import javafx.event.EventHandler;
  31 import javafx.scene.input.MouseEvent;
  32 import javafx.scene.shape.Rectangle;
  33 import javafx.stage.Stage;
  34 
  35 import org.junit.Assert;
  36 import org.junit.Test;
  37 
  38 import com.sun.javafx.pgstub.StubScene;
  39 import com.sun.javafx.pgstub.StubToolkit;
  40 import com.sun.javafx.tk.Toolkit;
  41 import javafx.event.EventTarget;
  42 import javafx.event.EventType;
  43 import javafx.scene.input.MouseDragEvent;
  44 import javafx.scene.input.PickResult;
  45 import javafx.scene.paint.Color;
  46 import javafx.scene.transform.Rotate;
  47 
  48 public class MouseTest {
  49 
  50     private static final double DONT_TEST = 0.0;
  51 
  52     @Test
  53     public void moveShouldBubbleToParent() {
  54         SimpleTestScene scene = new SimpleTestScene();
  55         MouseEventGenerator generator = new MouseEventGenerator();
  56 
  57         scene.processEvent(generator.generateMouseEvent(
  58                 MouseEvent.MOUSE_MOVED, 250, 250));
  59 
  60         assertTrue(scene.smallSquareTracker.wasMoved());
  61         assertFalse(scene.bigSquareTracker.wasMoved());
  62         assertTrue(scene.groupTracker.wasMoved());
  63     }
  64 
  65     @Test
  66     public void moveOutsideNodesShouldntBeNoticed() {
  67         SimpleTestScene scene = new SimpleTestScene();
  68         MouseEventGenerator generator = new MouseEventGenerator();
  69 
  70         scene.processEvent(generator.generateMouseEvent(
  71                 MouseEvent.MOUSE_MOVED, 350, 350));
  72 
  73         assertFalse(scene.smallSquareTracker.wasMoved());
  74         assertFalse(scene.bigSquareTracker.wasMoved());
  75         assertFalse(scene.groupTracker.wasMoved());
  76     }
  77 
  78     @Test
  79     public void moveOutsideNodesShouldGoToScene() {
  80         SimpleTestScene scene = new SimpleTestScene();
  81         MouseEventGenerator generator = new MouseEventGenerator();
  82 
  83         scene.processEvent(generator.generateMouseEvent(
  84                 MouseEvent.MOUSE_MOVED, 350, 350));
  85 
  86         assertTrue(scene.wasMoused());
  87     }
  88 
  89     @Test
  90     public void ImpossibleToComputeCoordsShouldResultInNaNs() {
  91         final SimpleTestScene scene = new SimpleTestScene();
  92 
  93         scene.smallSquareTracker.node.setOnMouseMoved(event -> scene.smallSquareTracker.node.setScaleX(0));
  94 
  95         scene.smallSquareTracker.node.setOnMouseExited(event -> {
  96             assertTrue(Double.isNaN(event.getX()));
  97             assertTrue(Double.isNaN(event.getY()));
  98             assertTrue(Double.isNaN(event.getZ()));
  99         });
 100 
 101         scene.processEvent(MouseEventGenerator.generateMouseEvent(
 102                 MouseEvent.MOUSE_MOVED, 250, 250));
 103         scene.processEvent(MouseEventGenerator.generateMouseEvent(
 104                 MouseEvent.MOUSE_MOVED, 260, 260));
 105         assertTrue(scene.smallSquareTracker.enteredMe);
 106     }
 107 
 108     @Test
 109     public void PdrGestureShouldGoToOneNode() {
 110         SimpleTestScene scene = new SimpleTestScene();
 111         MouseEventGenerator generator = new MouseEventGenerator();
 112 
 113         /* gesture */
 114         scene.processEvent(generator.generateMouseEvent(
 115                 MouseEvent.MOUSE_PRESSED, 250, 250));
 116 
 117         scene.processEvent(generator.generateMouseEvent(
 118                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 119 
 120         scene.processEvent(generator.generateMouseEvent(
 121                 MouseEvent.MOUSE_RELEASED, 150, 150));
 122 
 123         assertTrue(scene.smallSquareTracker.wasPressed());
 124         assertTrue(scene.smallSquareTracker.wasDragged());
 125         assertTrue(scene.smallSquareTracker.wasReleased());
 126         assertFalse(scene.bigSquareTracker.wasPressed());
 127         assertFalse(scene.bigSquareTracker.wasDragged());
 128         assertFalse(scene.bigSquareTracker.wasReleased());
 129         assertFalse(scene.bigSquareTracker.wasMoved());
 130 
 131         /* gesture ended */
 132         scene.processEvent(generator.generateMouseEvent(
 133                 MouseEvent.MOUSE_MOVED, 140, 140));
 134 
 135         assertTrue(scene.bigSquareTracker.wasMoved());
 136     }
 137 
 138     @Test
 139     public void PdrGestureOnSceneShouldGoOnlyToScene() {
 140         SimpleTestScene scene = new SimpleTestScene();
 141         MouseEventGenerator generator = new MouseEventGenerator();
 142 
 143         /* gesture */
 144         scene.processEvent(generator.generateMouseEvent(
 145                 MouseEvent.MOUSE_PRESSED, 50, 50));
 146 
 147         assertTrue(scene.wasMoused());
 148         assertFalse(scene.smallSquareTracker.wasPressed());
 149         assertFalse(scene.smallSquareTracker.wasDragged());
 150         assertFalse(scene.smallSquareTracker.wasReleased());
 151         assertFalse(scene.bigSquareTracker.wasPressed());
 152         assertFalse(scene.bigSquareTracker.wasDragged());
 153         assertFalse(scene.bigSquareTracker.wasReleased());
 154         assertFalse(scene.bigSquareTracker.wasMoved());
 155         scene.clear();
 156 
 157         scene.processEvent(generator.generateMouseEvent(
 158                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 159 
 160         assertTrue(scene.wasMoused());
 161         assertFalse(scene.smallSquareTracker.wasPressed());
 162         assertFalse(scene.smallSquareTracker.wasDragged());
 163         assertFalse(scene.smallSquareTracker.wasReleased());
 164         assertFalse(scene.bigSquareTracker.wasPressed());
 165         assertFalse(scene.bigSquareTracker.wasDragged());
 166         assertFalse(scene.bigSquareTracker.wasReleased());
 167         assertFalse(scene.bigSquareTracker.wasMoved());
 168         scene.clear();
 169 
 170         scene.processEvent(generator.generateMouseEvent(
 171                 MouseEvent.MOUSE_RELEASED, 150, 150));
 172 
 173         assertTrue(scene.wasMoused());
 174         assertFalse(scene.smallSquareTracker.wasPressed());
 175         assertFalse(scene.smallSquareTracker.wasDragged());
 176         assertFalse(scene.smallSquareTracker.wasReleased());
 177         assertFalse(scene.bigSquareTracker.wasPressed());
 178         assertFalse(scene.bigSquareTracker.wasDragged());
 179         assertFalse(scene.bigSquareTracker.wasReleased());
 180         assertFalse(scene.bigSquareTracker.wasMoved());
 181 
 182         /* gesture ended */
 183         scene.processEvent(generator.generateMouseEvent(
 184                 MouseEvent.MOUSE_MOVED, 140, 140));
 185 
 186         assertTrue(scene.bigSquareTracker.wasMoved());
 187     }
 188 
 189     @Test
 190     public void testEnteredExitedGeneration() {
 191         SimpleTestScene scene = new SimpleTestScene();
 192         MouseEventGenerator generator = new MouseEventGenerator();
 193 
 194         scene.processEvent(generator.generateMouseEvent(
 195                 MouseEvent.MOUSE_MOVED, 350, 350));
 196 
 197         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 198         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 199         assertFalse(scene.groupTracker.wasEnteredMe());
 200         assertFalse(scene.smallSquareTracker.wasExitedMe());
 201         assertFalse(scene.bigSquareTracker.wasExitedMe());
 202         assertFalse(scene.groupTracker.wasExitedMe());
 203         assertTrue(scene.sceneTracker.wasEnteredMe());
 204         assertFalse(scene.sceneTracker.wasExitedMe());
 205         scene.clear();
 206 
 207         scene.processEvent(generator.generateMouseEvent(
 208                 MouseEvent.MOUSE_MOVED, 250, 250));
 209 
 210         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 211         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 212         assertTrue(scene.groupTracker.wasEnteredMe());
 213         assertFalse(scene.smallSquareTracker.wasExitedMe());
 214         assertFalse(scene.bigSquareTracker.wasExitedMe());
 215         assertFalse(scene.groupTracker.wasExitedMe());
 216         assertFalse(scene.sceneTracker.wasEnteredMe());
 217         assertFalse(scene.sceneTracker.wasExitedMe());
 218         scene.clear();
 219 
 220         scene.processEvent(generator.generateMouseEvent(
 221                 MouseEvent.MOUSE_MOVED, 150, 150));
 222 
 223         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 224         assertTrue(scene.bigSquareTracker.wasEnteredMe());
 225         assertFalse(scene.groupTracker.wasEnteredMe());
 226         assertTrue(scene.smallSquareTracker.wasExitedMe());
 227         assertFalse(scene.bigSquareTracker.wasExitedMe());
 228         assertFalse(scene.groupTracker.wasExitedMe());
 229         assertFalse(scene.sceneTracker.wasEnteredMe());
 230         assertFalse(scene.sceneTracker.wasExitedMe());
 231         scene.clear();
 232 
 233         scene.processEvent(generator.generateMouseEvent(
 234                 MouseEvent.MOUSE_MOVED, 50, 50));
 235 
 236         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 237         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 238         assertFalse(scene.groupTracker.wasEnteredMe());
 239         assertFalse(scene.smallSquareTracker.wasExitedMe());
 240         assertTrue(scene.bigSquareTracker.wasExitedMe());
 241         assertTrue(scene.groupTracker.wasExitedMe());
 242         assertFalse(scene.sceneTracker.wasEnteredMe());
 243         assertFalse(scene.sceneTracker.wasExitedMe());
 244         scene.clear();
 245 
 246         scene.processEvent(generator.generateMouseEvent(
 247                 MouseEvent.MOUSE_MOVED, -1, 50));
 248         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 249         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 250         assertFalse(scene.groupTracker.wasEnteredMe());
 251         assertFalse(scene.smallSquareTracker.wasExitedMe());
 252         assertFalse(scene.bigSquareTracker.wasExitedMe());
 253         assertFalse(scene.groupTracker.wasExitedMe());
 254         assertFalse(scene.sceneTracker.wasEnteredMe());
 255         assertTrue(scene.sceneTracker.wasExitedMe());
 256         scene.clear();
 257     }
 258 
 259     @Test
 260     public void testEnteredExitedGenerationDuringPdr() {
 261         SimpleTestScene scene = new SimpleTestScene();
 262         MouseEventGenerator generator = new MouseEventGenerator();
 263 
 264         scene.processEvent(generator.generateMouseEvent(
 265                 MouseEvent.MOUSE_PRESSED, 255, 255));
 266 
 267         scene.processEvent(generator.generateMouseEvent(
 268                 MouseEvent.MOUSE_DRAGGED, 250, 250));
 269 
 270         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 271         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 272         assertTrue(scene.groupTracker.wasEnteredMe());
 273         assertFalse(scene.smallSquareTracker.wasExitedMe());
 274         assertFalse(scene.bigSquareTracker.wasExitedMe());
 275         assertFalse(scene.groupTracker.wasExitedMe());
 276         assertTrue(scene.sceneTracker.wasEnteredMe());
 277         assertFalse(scene.sceneTracker.wasExitedMe());
 278         scene.clear();
 279 
 280         scene.processEvent(generator.generateMouseEvent(
 281                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 282 
 283         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 284         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 285         assertFalse(scene.groupTracker.wasEnteredMe());
 286         assertTrue(scene.smallSquareTracker.wasExitedMe());
 287         assertFalse(scene.bigSquareTracker.wasExitedMe());
 288         assertFalse(scene.groupTracker.wasExitedMe());
 289         assertFalse(scene.sceneTracker.wasEnteredMe());
 290         assertFalse(scene.sceneTracker.wasExitedMe());
 291         scene.clear();
 292 
 293         scene.processEvent(generator.generateMouseEvent(
 294                 MouseEvent.MOUSE_DRAGGED, 50, 50));
 295 
 296         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 297         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 298         assertFalse(scene.groupTracker.wasEnteredMe());
 299         assertFalse(scene.smallSquareTracker.wasExitedMe());
 300         assertFalse(scene.bigSquareTracker.wasExitedMe());
 301         assertTrue(scene.groupTracker.wasExitedMe());
 302         assertFalse(scene.sceneTracker.wasEnteredMe());
 303         assertFalse(scene.sceneTracker.wasExitedMe());
 304         scene.clear();
 305 
 306         scene.processEvent(generator.generateMouseEvent(
 307                 MouseEvent.MOUSE_DRAGGED, -1, 50));
 308 
 309         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 310         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 311         assertFalse(scene.groupTracker.wasEnteredMe());
 312         assertFalse(scene.smallSquareTracker.wasExitedMe());
 313         assertFalse(scene.bigSquareTracker.wasExitedMe());
 314         assertFalse(scene.groupTracker.wasExitedMe());
 315         assertFalse(scene.sceneTracker.wasEnteredMe());
 316         assertTrue(scene.sceneTracker.wasExitedMe());
 317         scene.clear();
 318 
 319         scene.processEvent(generator.generateMouseEvent(
 320                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 321 
 322         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 323         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 324         assertTrue(scene.groupTracker.wasEnteredMe());
 325         assertFalse(scene.smallSquareTracker.wasExitedMe());
 326         assertFalse(scene.bigSquareTracker.wasExitedMe());
 327         assertFalse(scene.groupTracker.wasExitedMe());
 328         assertTrue(scene.sceneTracker.wasEnteredMe());
 329         assertFalse(scene.sceneTracker.wasExitedMe());
 330         scene.clear();
 331 
 332         scene.processEvent(generator.generateMouseEvent(
 333                 MouseEvent.MOUSE_RELEASED, 350, 350));
 334 
 335         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 336         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 337         assertFalse(scene.groupTracker.wasEnteredMe());
 338         assertFalse(scene.smallSquareTracker.wasExitedMe());
 339         assertFalse(scene.bigSquareTracker.wasExitedMe());
 340         assertTrue(scene.groupTracker.wasExitedMe());
 341         assertFalse(scene.sceneTracker.wasEnteredMe());
 342         assertFalse(scene.sceneTracker.wasExitedMe());
 343     }
 344 
 345     @Test
 346     public void testEnteredExitedGenerationAfterPdr() {
 347         SimpleTestScene scene = new SimpleTestScene();
 348         MouseEventGenerator generator = new MouseEventGenerator();
 349 
 350         scene.processEvent(generator.generateMouseEvent(
 351                 MouseEvent.MOUSE_PRESSED, 155, 155));
 352 
 353         scene.processEvent(generator.generateMouseEvent(
 354                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 355 
 356         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 357         assertTrue(scene.bigSquareTracker.wasEnteredMe());
 358         assertTrue(scene.groupTracker.wasEnteredMe());
 359         assertFalse(scene.smallSquareTracker.wasExitedMe());
 360         assertFalse(scene.bigSquareTracker.wasExitedMe());
 361         assertFalse(scene.groupTracker.wasExitedMe());
 362         scene.clear();
 363 
 364         scene.processEvent(generator.generateMouseEvent(
 365                 MouseEvent.MOUSE_DRAGGED, 250, 250));
 366 
 367         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 368         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 369         assertFalse(scene.groupTracker.wasEnteredMe());
 370         assertFalse(scene.smallSquareTracker.wasExitedMe());
 371         assertTrue(scene.bigSquareTracker.wasExitedMe());
 372         assertFalse(scene.groupTracker.wasExitedMe());
 373         scene.clear();
 374 
 375         scene.processEvent(generator.generateMouseEvent(
 376                 MouseEvent.MOUSE_RELEASED, 250, 250));
 377 
 378         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 379         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 380         assertFalse(scene.groupTracker.wasEnteredMe());
 381         assertFalse(scene.smallSquareTracker.wasExitedMe());
 382         assertFalse(scene.bigSquareTracker.wasExitedMe());
 383         assertFalse(scene.groupTracker.wasExitedMe());
 384         scene.clear();
 385 
 386         scene.processEvent(generator.generateMouseEvent(
 387                 MouseEvent.MOUSE_MOVED, 250, 250));
 388 
 389         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 390         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 391         assertFalse(scene.groupTracker.wasEnteredMe());
 392         assertFalse(scene.smallSquareTracker.wasExitedMe());
 393         assertFalse(scene.bigSquareTracker.wasExitedMe());
 394         assertFalse(scene.groupTracker.wasExitedMe());
 395     }
 396 
 397     @Test
 398     public void testEnteredExitedGenerationDuringDndOnScene() {
 399         SimpleTestScene scene = new SimpleTestScene();
 400         MouseEventGenerator generator = new MouseEventGenerator();
 401 
 402         scene.processEvent(generator.generateMouseEvent(
 403                 MouseEvent.MOUSE_PRESSED, 50, 50));
 404 
 405         scene.processEvent(generator.generateMouseEvent(
 406                 MouseEvent.MOUSE_DRAGGED, 250, 250));
 407 
 408         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 409         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 410         assertFalse(scene.groupTracker.wasEnteredMe());
 411         assertFalse(scene.smallSquareTracker.wasExitedMe());
 412         assertFalse(scene.bigSquareTracker.wasExitedMe());
 413         assertFalse(scene.groupTracker.wasExitedMe());
 414         scene.clear();
 415 
 416         scene.processEvent(generator.generateMouseEvent(
 417                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 418 
 419         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 420         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 421         assertFalse(scene.groupTracker.wasEnteredMe());
 422         assertFalse(scene.smallSquareTracker.wasExitedMe());
 423         assertFalse(scene.bigSquareTracker.wasExitedMe());
 424         assertFalse(scene.groupTracker.wasExitedMe());
 425         scene.clear();
 426 
 427         scene.processEvent(generator.generateMouseEvent(
 428                 MouseEvent.MOUSE_DRAGGED, 50, 50));
 429 
 430         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 431         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 432         assertFalse(scene.groupTracker.wasEnteredMe());
 433         assertFalse(scene.smallSquareTracker.wasExitedMe());
 434         assertFalse(scene.bigSquareTracker.wasExitedMe());
 435         assertFalse(scene.groupTracker.wasExitedMe());
 436         scene.clear();
 437 
 438         scene.processEvent(generator.generateMouseEvent(
 439                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 440 
 441         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 442         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 443         assertFalse(scene.groupTracker.wasEnteredMe());
 444         assertFalse(scene.smallSquareTracker.wasExitedMe());
 445         assertFalse(scene.bigSquareTracker.wasExitedMe());
 446         assertFalse(scene.groupTracker.wasExitedMe());
 447         scene.clear();
 448 
 449         scene.processEvent(generator.generateMouseEvent(
 450                 MouseEvent.MOUSE_RELEASED, 350, 350));
 451 
 452         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 453         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 454         assertFalse(scene.groupTracker.wasEnteredMe());
 455         assertFalse(scene.smallSquareTracker.wasExitedMe());
 456         assertFalse(scene.bigSquareTracker.wasExitedMe());
 457         assertFalse(scene.groupTracker.wasExitedMe());
 458     }
 459 
 460     @Test
 461     public void testEnteredExitedMeChildSwitching() {
 462         SimpleTestScene scene = new SimpleTestScene();
 463         MouseEventGenerator generator = new MouseEventGenerator();
 464 
 465         scene.processEvent(generator.generateMouseEvent(
 466                 MouseEvent.MOUSE_MOVED, 150, 150));
 467 
 468         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 469         assertTrue(scene.bigSquareTracker.wasEnteredMe());
 470         assertTrue(scene.groupTracker.wasEnteredMe());
 471         assertFalse(scene.smallSquareTracker.wasExitedMe());
 472         assertFalse(scene.bigSquareTracker.wasExitedMe());
 473         assertFalse(scene.groupTracker.wasExitedMe());
 474         assertFalse(scene.smallSquareTracker.wasEnteredChild());
 475         assertFalse(scene.bigSquareTracker.wasEnteredChild());
 476         assertTrue(scene.groupTracker.wasEnteredChild());
 477         assertFalse(scene.smallSquareTracker.wasExitedChild());
 478         assertFalse(scene.bigSquareTracker.wasExitedChild());
 479         assertFalse(scene.groupTracker.wasExitedChild());
 480         scene.clear();
 481 
 482         scene.processEvent(generator.generateMouseEvent(
 483                 MouseEvent.MOUSE_MOVED, 250, 250));
 484 
 485         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 486         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 487         assertFalse(scene.groupTracker.wasEnteredMe());
 488         assertFalse(scene.smallSquareTracker.wasExitedMe());
 489         assertTrue(scene.bigSquareTracker.wasExitedMe());
 490         assertFalse(scene.groupTracker.wasExitedMe());
 491         assertFalse(scene.smallSquareTracker.wasEnteredChild());
 492         assertFalse(scene.bigSquareTracker.wasEnteredChild());
 493         assertTrue(scene.groupTracker.wasEnteredChild());
 494         assertFalse(scene.smallSquareTracker.wasExitedChild());
 495         assertFalse(scene.bigSquareTracker.wasExitedChild());
 496         assertTrue(scene.groupTracker.wasExitedChild());
 497         scene.clear();
 498 
 499         scene.processEvent(generator.generateMouseEvent(
 500                 MouseEvent.MOUSE_MOVED, 350, 350));
 501 
 502         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 503         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 504         assertFalse(scene.groupTracker.wasEnteredMe());
 505         assertTrue(scene.smallSquareTracker.wasExitedMe());
 506         assertFalse(scene.bigSquareTracker.wasExitedMe());
 507         assertTrue(scene.groupTracker.wasExitedMe());
 508         assertFalse(scene.smallSquareTracker.wasEnteredChild());
 509         assertFalse(scene.bigSquareTracker.wasEnteredChild());
 510         assertFalse(scene.groupTracker.wasEnteredChild());
 511         assertFalse(scene.smallSquareTracker.wasExitedChild());
 512         assertFalse(scene.bigSquareTracker.wasExitedChild());
 513         assertTrue(scene.groupTracker.wasExitedChild());
 514     }
 515 
 516     @Test
 517     public void platformCursorShouldBeUpdated() {
 518         SimpleTestScene scene = new SimpleTestScene();
 519         MouseEventGenerator generator = new MouseEventGenerator();
 520 
 521         scene.processEvent(generator.generateMouseEvent(
 522                 MouseEvent.MOUSE_MOVED, 250, 250));
 523 
 524         assertSame(Cursor.HAND.getCurrentFrame(), scene.getCursorFrame());
 525 
 526         scene.processEvent(generator.generateMouseEvent(
 527                 MouseEvent.MOUSE_MOVED, 150, 150));
 528 
 529         assertSame(Cursor.TEXT.getCurrentFrame(), scene.getCursorFrame());
 530 
 531         scene.processEvent(generator.generateMouseEvent(
 532                 MouseEvent.MOUSE_MOVED, 50, 50));
 533 
 534         assertSame(Cursor.DEFAULT.getCurrentFrame(),
 535                    scene.getCursorFrame());
 536     }
 537     
 538     @Test
 539     public void platformCursorShouldBeUpdatedOnPulse() {
 540         
 541         final StubToolkit toolkit = (StubToolkit) Toolkit.getToolkit();
 542         SimpleTestScene scene = new SimpleTestScene();
 543         MouseEventGenerator generator = new MouseEventGenerator();
 544 
 545         scene.processEvent(generator.generateMouseEvent(
 546                 MouseEvent.MOUSE_MOVED, 250, 250));
 547 
 548         assertSame(Cursor.HAND.getCurrentFrame(), scene.getCursorFrame());
 549 
 550         scene.scene.setCursor(Cursor.TEXT);
 551         toolkit.firePulse();
 552         assertSame(Cursor.TEXT.getCurrentFrame(), scene.getCursorFrame());
 553         
 554     }
 555 
 556     @Test
 557     public void testHover() {
 558         SimpleTestScene scene = new SimpleTestScene();
 559         MouseEventGenerator generator = new MouseEventGenerator();
 560 
 561         scene.processEvent(generator.generateMouseEvent(
 562                 MouseEvent.MOUSE_MOVED, 250, 250));
 563 
 564         assertTrue(scene.smallSquareTracker.isHover());
 565         assertFalse(scene.bigSquareTracker.isHover());
 566         assertTrue(scene.groupTracker.isHover());
 567 
 568         scene.processEvent(generator.generateMouseEvent(
 569                 MouseEvent.MOUSE_MOVED, 150, 150));
 570 
 571         assertFalse(scene.smallSquareTracker.isHover());
 572         assertTrue(scene.bigSquareTracker.isHover());
 573         assertTrue(scene.groupTracker.isHover());
 574 
 575         scene.processEvent(generator.generateMouseEvent(
 576                 MouseEvent.MOUSE_MOVED, 50, 50));
 577 
 578         assertFalse(scene.smallSquareTracker.isHover());
 579         assertFalse(scene.bigSquareTracker.isHover());
 580         assertFalse(scene.groupTracker.isHover());
 581     }
 582 
 583     @Test
 584     public void clickShouldBeGeneratedFromPressRelease() {
 585         SimpleTestScene scene = new SimpleTestScene();
 586         MouseEventGenerator generator = new MouseEventGenerator();
 587 
 588         scene.processEvent(generator.generateMouseEvent(
 589                 MouseEvent.MOUSE_PRESSED, 250, 250));
 590         scene.processEvent(generator.generateMouseEvent(
 591                 MouseEvent.MOUSE_RELEASED, 250, 250));
 592 
 593         assertTrue(scene.smallSquareTracker.wasClicked());
 594         assertFalse(scene.bigSquareTracker.wasClicked());
 595         assertTrue(scene.groupTracker.wasClicked());
 596     }
 597     
 598     @Test
 599     public void clickShouldBeGeneratedWhenReleasedOnTheSameNode() {
 600         SimpleTestScene scene = new SimpleTestScene();
 601         MouseEventGenerator generator = new MouseEventGenerator();
 602 
 603         scene.processEvent(generator.generateMouseEvent(
 604                 MouseEvent.MOUSE_PRESSED, 250, 250));
 605         scene.processEvent(generator.generateMouseEvent(
 606                 MouseEvent.MOUSE_DRAGGED, 50, 50));
 607         scene.processEvent(generator.generateMouseEvent(
 608                 MouseEvent.MOUSE_DRAGGED, 270, 270));
 609         scene.processEvent(generator.generateMouseEvent(
 610                 MouseEvent.MOUSE_RELEASED, 270, 270));
 611 
 612         assertTrue(scene.smallSquareTracker.wasClicked());
 613         assertFalse(scene.bigSquareTracker.wasClicked());
 614         assertTrue(scene.groupTracker.wasClicked());
 615     }
 616     
 617     @Test
 618     public void clickShouldBeGeneratedWhenReleasedOnParent() {
 619         SimpleTestScene scene = new SimpleTestScene();
 620         MouseEventGenerator generator = new MouseEventGenerator();
 621 
 622         scene.processEvent(generator.generateMouseEvent(
 623                 MouseEvent.MOUSE_PRESSED, 250, 250));
 624         scene.processEvent(generator.generateMouseEvent(
 625                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 626         scene.processEvent(generator.generateMouseEvent(
 627                 MouseEvent.MOUSE_RELEASED, 150, 150));
 628 
 629         assertFalse(scene.smallSquareTracker.wasClicked());
 630         assertFalse(scene.bigSquareTracker.wasClicked());
 631         assertTrue(scene.groupTracker.wasClicked());
 632     }
 633     
 634     @Test
 635     public void doubleClickShouldBeGeneratedFromPressedReleasedTwoTimes() {
 636         SimpleTestScene scene = new SimpleTestScene();
 637         MouseEventGenerator generator = new MouseEventGenerator();
 638 
 639         scene.processEvent(generator.generateMouseEvent(
 640                 MouseEvent.MOUSE_PRESSED, 250, 250));
 641         scene.processEvent(generator.generateMouseEvent(
 642                 MouseEvent.MOUSE_RELEASED, 250, 250));
 643         scene.processEvent(generator.generateMouseEvent(
 644                 MouseEvent.MOUSE_PRESSED, 250, 250));
 645         scene.processEvent(generator.generateMouseEvent(
 646                 MouseEvent.MOUSE_RELEASED, 250, 250));
 647 
 648         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 649         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 650         assertTrue(scene.groupTracker.wasDoubleClicked());
 651     }
 652 
 653     @Test
 654     public void doubleClickShouldBeGeneratedEvenIfNodeChangesInBetween() {
 655         SimpleTestScene scene = new SimpleTestScene();
 656         MouseEventGenerator generator = new MouseEventGenerator();
 657 
 658         scene.processEvent(generator.generateMouseEvent(
 659                 MouseEvent.MOUSE_PRESSED, 199, 250));
 660         scene.processEvent(generator.generateMouseEvent(
 661                 MouseEvent.MOUSE_RELEASED, 199, 250));
 662         scene.processEvent(generator.generateMouseEvent(
 663                 MouseEvent.MOUSE_PRESSED, 201, 250));
 664         scene.processEvent(generator.generateMouseEvent(
 665                 MouseEvent.MOUSE_RELEASED, 201, 250));
 666 
 667         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 668         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 669         assertTrue(scene.bigSquareTracker.wasClicked());
 670     }
 671 
 672     @Test
 673     public void doubleClickShouldBeGeneratedFromPressedReleasedTwoTimesWithHysteresis() {
 674         SimpleTestScene scene = new SimpleTestScene();
 675         MouseEventGenerator generator = new MouseEventGenerator();
 676 
 677         scene.processEvent(generator.generateMouseEvent(
 678                 MouseEvent.MOUSE_PRESSED, 250, 250));
 679         scene.processEvent(generator.generateMouseEvent(
 680                 MouseEvent.MOUSE_DRAGGED, 251, 251));
 681         scene.processEvent(generator.generateMouseEvent(
 682                 MouseEvent.MOUSE_RELEASED, 251, 251));
 683         scene.processEvent(generator.generateMouseEvent(
 684                 MouseEvent.MOUSE_DRAGGED, 252, 252));
 685         scene.processEvent(generator.generateMouseEvent(
 686                 MouseEvent.MOUSE_PRESSED, 252, 252));
 687         scene.processEvent(generator.generateMouseEvent(
 688                 MouseEvent.MOUSE_DRAGGED, 253, 253));
 689         scene.processEvent(generator.generateMouseEvent(
 690                 MouseEvent.MOUSE_RELEASED, 253, 253));
 691 
 692         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 693         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 694         assertTrue(scene.groupTracker.wasDoubleClicked());
 695     }
 696     
 697     @Test
 698     public void doubleClickShouldNotBeGeneratedWhenMovedFarAwayBetweenClick() {
 699         SimpleTestScene scene = new SimpleTestScene();
 700         MouseEventGenerator generator = new MouseEventGenerator();
 701 
 702         scene.processEvent(generator.generateMouseEvent(
 703                 MouseEvent.MOUSE_PRESSED, 250, 250));
 704         scene.processEvent(generator.generateMouseEvent(
 705                 MouseEvent.MOUSE_RELEASED, 250, 250));
 706         scene.processEvent(generator.generateMouseEvent(
 707                 MouseEvent.MOUSE_DRAGGED, 258, 258));
 708         scene.processEvent(generator.generateMouseEvent(
 709                 MouseEvent.MOUSE_PRESSED, 258, 258));
 710         scene.processEvent(generator.generateMouseEvent(
 711                 MouseEvent.MOUSE_RELEASED, 258, 258));
 712 
 713         assertTrue(scene.smallSquareTracker.wasClicked());
 714         assertFalse(scene.bigSquareTracker.wasClicked());
 715         assertTrue(scene.groupTracker.wasClicked());
 716         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 717         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 718         assertFalse(scene.groupTracker.wasDoubleClicked());
 719     }
 720     
 721     @Test
 722     public void doubleClickShouldNotBeGeneratedWhenMovedFarAwayInFirstClick() {
 723         SimpleTestScene scene = new SimpleTestScene();
 724         MouseEventGenerator generator = new MouseEventGenerator();
 725 
 726         scene.processEvent(generator.generateMouseEvent(
 727                 MouseEvent.MOUSE_PRESSED, 250, 250));
 728         scene.processEvent(generator.generateMouseEvent(
 729                 MouseEvent.MOUSE_DRAGGED, 258, 258));
 730         scene.processEvent(generator.generateMouseEvent(
 731                 MouseEvent.MOUSE_RELEASED, 258, 258));
 732         scene.processEvent(generator.generateMouseEvent(
 733                 MouseEvent.MOUSE_PRESSED, 258, 258));
 734         scene.processEvent(generator.generateMouseEvent(
 735                 MouseEvent.MOUSE_RELEASED, 258, 258));
 736 
 737         assertTrue(scene.smallSquareTracker.wasClicked());
 738         assertFalse(scene.bigSquareTracker.wasClicked());
 739         assertTrue(scene.groupTracker.wasClicked());
 740         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 741         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 742         assertFalse(scene.groupTracker.wasDoubleClicked());
 743     }
 744     
 745     @Test
 746     public void doubleClickShouldBeGeneratedWhenMovedFarAwayInSecondClick() {
 747         SimpleTestScene scene = new SimpleTestScene();
 748         MouseEventGenerator generator = new MouseEventGenerator();
 749 
 750         scene.processEvent(generator.generateMouseEvent(
 751                 MouseEvent.MOUSE_PRESSED, 250, 250));
 752         scene.processEvent(generator.generateMouseEvent(
 753                 MouseEvent.MOUSE_RELEASED, 250, 250));
 754         scene.processEvent(generator.generateMouseEvent(
 755                 MouseEvent.MOUSE_PRESSED, 250, 250));
 756         scene.processEvent(generator.generateMouseEvent(
 757                 MouseEvent.MOUSE_DRAGGED, 258, 258));
 758         scene.processEvent(generator.generateMouseEvent(
 759                 MouseEvent.MOUSE_RELEASED, 258, 258));
 760 
 761         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 762         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 763         assertTrue(scene.groupTracker.wasDoubleClicked());
 764     }
 765     
 766     @Test
 767     public void doubleClickShouldNotBeGeneratedWithLongTimeBetweenClicks() {
 768         SimpleTestScene scene = new SimpleTestScene();
 769         MouseEventGenerator generator = new MouseEventGenerator();
 770 
 771         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(0);
 772         
 773         scene.processEvent(generator.generateMouseEvent(
 774                 MouseEvent.MOUSE_PRESSED, 250, 250));
 775         scene.processEvent(generator.generateMouseEvent(
 776                 MouseEvent.MOUSE_RELEASED, 250, 250));
 777         
 778         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(2000);
 779 
 780         scene.processEvent(generator.generateMouseEvent(
 781                 MouseEvent.MOUSE_PRESSED, 250, 250));
 782         scene.processEvent(generator.generateMouseEvent(
 783                 MouseEvent.MOUSE_RELEASED, 250, 250));
 784 
 785         assertTrue(scene.smallSquareTracker.wasClicked());
 786         assertFalse(scene.bigSquareTracker.wasClicked());
 787         assertTrue(scene.groupTracker.wasClicked());
 788         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 789         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 790         assertFalse(scene.groupTracker.wasDoubleClicked());
 791     }
 792     
 793     @Test
 794     public void doubleClickShouldNotBeGeneratedWithLongTimeInFirstClick() {
 795         SimpleTestScene scene = new SimpleTestScene();
 796         MouseEventGenerator generator = new MouseEventGenerator();
 797 
 798         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(0);
 799         
 800         scene.processEvent(generator.generateMouseEvent(
 801                 MouseEvent.MOUSE_PRESSED, 250, 250));
 802         
 803         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(2000);
 804 
 805         scene.processEvent(generator.generateMouseEvent(
 806                 MouseEvent.MOUSE_RELEASED, 250, 250));
 807         scene.processEvent(generator.generateMouseEvent(
 808                 MouseEvent.MOUSE_PRESSED, 250, 250));
 809         scene.processEvent(generator.generateMouseEvent(
 810                 MouseEvent.MOUSE_RELEASED, 250, 250));
 811 
 812         assertTrue(scene.smallSquareTracker.wasClicked());
 813         assertFalse(scene.bigSquareTracker.wasClicked());
 814         assertTrue(scene.groupTracker.wasClicked());
 815         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 816         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 817         assertFalse(scene.groupTracker.wasDoubleClicked());
 818     }
 819     
 820     @Test
 821     public void doubleClickShouldBeGeneratedWithLongTimeInSecondClick() {
 822         SimpleTestScene scene = new SimpleTestScene();
 823         MouseEventGenerator generator = new MouseEventGenerator();
 824 
 825         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(0);
 826         
 827         scene.processEvent(generator.generateMouseEvent(
 828                 MouseEvent.MOUSE_PRESSED, 250, 250));
 829         scene.processEvent(generator.generateMouseEvent(
 830                 MouseEvent.MOUSE_RELEASED, 250, 250));
 831         scene.processEvent(generator.generateMouseEvent(
 832                 MouseEvent.MOUSE_PRESSED, 250, 250));
 833         
 834         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(2000);
 835 
 836         scene.processEvent(generator.generateMouseEvent(
 837                 MouseEvent.MOUSE_RELEASED, 250, 250));
 838 
 839         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 840         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 841         assertTrue(scene.groupTracker.wasDoubleClicked());
 842     }
 843     
 844     @Test
 845     public void testClickCountOfMouseEvents() {
 846         SimpleTestScene scene = new SimpleTestScene();
 847         MouseEventGenerator generator = new MouseEventGenerator();
 848         
 849         scene.processEvent(generator.generateMouseEvent(
 850                 MouseEvent.MOUSE_MOVED, 250, 250));
 851         assertEquals(0, scene.smallSquareTracker.getLastClickCount());
 852         scene.smallSquareTracker.clear();
 853         
 854         scene.processEvent(generator.generateMouseEvent(
 855                 MouseEvent.MOUSE_PRESSED, 250, 250));
 856         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 857         scene.smallSquareTracker.clear();
 858 
 859         scene.processEvent(generator.generateMouseEvent(
 860                 MouseEvent.MOUSE_DRAGGED, 251, 251));
 861         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 862         scene.smallSquareTracker.clear();
 863         
 864         scene.processEvent(generator.generateMouseEvent(
 865                 MouseEvent.MOUSE_RELEASED, 251, 251));
 866         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 867         scene.smallSquareTracker.clear();
 868         
 869         scene.processEvent(generator.generateMouseEvent(
 870                 MouseEvent.MOUSE_MOVED, 252, 252));
 871         assertEquals(0, scene.smallSquareTracker.getLastClickCount());
 872         scene.smallSquareTracker.clear();
 873         
 874         scene.processEvent(generator.generateMouseEvent(
 875                 MouseEvent.MOUSE_PRESSED, 252, 252));
 876         assertEquals(2, scene.smallSquareTracker.getLastClickCount());
 877         scene.smallSquareTracker.clear();
 878 
 879         scene.processEvent(generator.generateMouseEvent(
 880                 MouseEvent.MOUSE_DRAGGED, 280, 280));
 881         assertEquals(2, scene.smallSquareTracker.getLastClickCount());
 882         scene.smallSquareTracker.clear();
 883         
 884         scene.processEvent(generator.generateMouseEvent(
 885                 MouseEvent.MOUSE_RELEASED, 280, 280));
 886         assertEquals(2, scene.smallSquareTracker.getLastClickCount());
 887         scene.smallSquareTracker.clear();
 888         
 889         scene.processEvent(generator.generateMouseEvent(
 890                 MouseEvent.MOUSE_MOVED, 280, 280));
 891         assertEquals(0, scene.smallSquareTracker.getLastClickCount());
 892         scene.smallSquareTracker.clear();
 893         
 894         scene.processEvent(generator.generateMouseEvent(
 895                 MouseEvent.MOUSE_PRESSED, 280, 280));
 896         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 897         scene.smallSquareTracker.clear();
 898 
 899         scene.processEvent(generator.generateMouseEvent(
 900                 MouseEvent.MOUSE_RELEASED, 280, 280));
 901         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 902         scene.smallSquareTracker.clear();        
 903     }
 904     
 905     @Test
 906     public void testIsStillOfMouseEvents() {
 907         SimpleTestScene scene = new SimpleTestScene();
 908         MouseEventGenerator generator = new MouseEventGenerator();
 909         
 910         scene.processEvent(generator.generateMouseEvent(
 911                 MouseEvent.MOUSE_MOVED, 250, 250));
 912         assertFalse(scene.smallSquareTracker.wasLastStill());
 913     
 914         scene.processEvent(generator.generateMouseEvent(
 915                 MouseEvent.MOUSE_PRESSED, 250, 250));
 916         assertFalse(scene.smallSquareTracker.wasLastStill());
 917         
 918         scene.processEvent(generator.generateMouseEvent(
 919                 MouseEvent.MOUSE_DRAGGED, 252, 252));
 920         assertTrue(scene.smallSquareTracker.wasLastStill());
 921         
 922         scene.processEvent(generator.generateMouseEvent(
 923                 MouseEvent.MOUSE_RELEASED, 252, 252));
 924         assertTrue(scene.smallSquareTracker.wasLastStill());
 925 
 926         scene.processEvent(generator.generateMouseEvent(
 927                 MouseEvent.MOUSE_MOVED, 254, 254));
 928         assertTrue(scene.smallSquareTracker.wasLastStill());
 929 
 930         scene.processEvent(generator.generateMouseEvent(
 931                 MouseEvent.MOUSE_PRESSED, 254, 254));
 932         assertTrue(scene.smallSquareTracker.wasLastStill());
 933 
 934         scene.processEvent(generator.generateMouseEvent(
 935                 MouseEvent.MOUSE_DRAGGED, 257, 257));
 936         assertTrue(scene.smallSquareTracker.wasLastStill());
 937 
 938         scene.processEvent(generator.generateMouseEvent(
 939                 MouseEvent.MOUSE_DRAGGED, 265, 265));
 940         assertFalse(scene.smallSquareTracker.wasLastStill());
 941 
 942         scene.processEvent(generator.generateMouseEvent(
 943                 MouseEvent.MOUSE_RELEASED, 265, 265));
 944         assertFalse(scene.smallSquareTracker.wasLastStill());
 945 
 946         scene.processEvent(generator.generateMouseEvent(
 947                 MouseEvent.MOUSE_MOVED, 266, 266));
 948         assertFalse(scene.smallSquareTracker.wasLastStill());
 949 
 950         scene.processEvent(generator.generateMouseEvent(
 951                 MouseEvent.MOUSE_PRESSED, 266, 266));
 952         assertFalse(scene.smallSquareTracker.wasLastStill());
 953         
 954         scene.processEvent(generator.generateMouseEvent(
 955                 MouseEvent.MOUSE_RELEASED, 266, 266));
 956         assertTrue(scene.smallSquareTracker.wasLastStill());        
 957     }
 958 
 959     @Test
 960     public void nodeMovementsWithStillMouseShouldFireEnteredExited() {
 961         SimpleTestScene scene = new SimpleTestScene();
 962         MouseEventGenerator generator = new MouseEventGenerator();
 963 
 964         scene.processEvent(generator.generateMouseEvent(
 965                 MouseEvent.MOUSE_ENTERED, 250, 250));
 966         scene.processEvent(generator.generateMouseEvent(
 967                 MouseEvent.MOUSE_MOVED, 250, 250));
 968         scene.smallSquareTracker.clear();
 969 
 970         assertFalse(scene.smallSquareTracker.exitedMe);
 971         ((Rectangle) scene.smallSquareTracker.node).setX(400);
 972         ((StubToolkit) Toolkit.getToolkit()).firePulse();
 973         assertTrue(scene.smallSquareTracker.exitedMe);
 974 
 975         scene.smallSquareTracker.clear();
 976 
 977         assertFalse(scene.smallSquareTracker.enteredMe);
 978         ((Rectangle) scene.smallSquareTracker.node).setX(200);
 979         ((StubToolkit) Toolkit.getToolkit()).firePulse();
 980         assertTrue(scene.smallSquareTracker.enteredMe);
 981     }
 982 
 983     @Test
 984     public void nodeWithNoninvertibleTransformShouldGetNanCoords() {
 985         SimpleTestScene scene = new SimpleTestScene();
 986         MouseEventGenerator generator = new MouseEventGenerator();
 987 
 988         scene.processEvent(generator.generateMouseEvent(
 989                 MouseEvent.MOUSE_PRESSED, 250, 250));
 990         scene.smallSquareTracker.clear();
 991 
 992         scene.smallSquareTracker.node.addEventHandler(MouseEvent.MOUSE_RELEASED,
 993                 event -> {
 994                     Assert.assertEquals(Double.NaN, event.getX(), 0.0001);
 995                     Assert.assertEquals(Double.NaN, event.getY(), 0.0001);
 996                     Assert.assertEquals(251.0, event.getSceneX(), 0.0001);
 997                     Assert.assertEquals(251.0, event.getSceneY(), 0.0001);
 998                 }
 999         );
1000 
1001         ((Rectangle) scene.smallSquareTracker.node).setScaleX(0);
1002 
1003         scene.processEvent(generator.generateMouseEvent(
1004                 MouseEvent.MOUSE_RELEASED, 251, 251));
1005 
1006         assertTrue(scene.smallSquareTracker.released);
1007     }
1008 
1009     @Test
1010     public void topMostNodeShouldBePickedWithDepthBufferByPerspectiveCamera() {
1011         SimpleTestScene scene = new SimpleTestScene(true, true);
1012         MouseEventGenerator generator = new MouseEventGenerator();
1013 
1014         scene.processEvent(generator.generateMouseEvent(
1015                 MouseEvent.MOUSE_MOVED, 250, 250));
1016 
1017         assertFalse(scene.smallSquareTracker.wasMoved());
1018         assertTrue(scene.bigSquareTracker.wasMoved());
1019         assertTrue(scene.groupTracker.wasMoved());
1020     }
1021 
1022     @Test
1023     public void topMostNodeShouldBePickedWithDepthBufferByParallelCamera() {
1024         SimpleTestScene scene = new SimpleTestScene(true, false);
1025         MouseEventGenerator generator = new MouseEventGenerator();
1026 
1027         scene.processEvent(generator.generateMouseEvent(
1028                 MouseEvent.MOUSE_MOVED, 250, 250));
1029 
1030         assertFalse(scene.smallSquareTracker.wasMoved());
1031         assertTrue(scene.bigSquareTracker.wasMoved());
1032         assertTrue(scene.groupTracker.wasMoved());
1033     }
1034 
1035     @Test
1036     public void subSceneShouldBePickedOnFill() {
1037         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1038 
1039         s.subScene1.setFill(Color.BLACK);
1040 
1041         s.scene.addEventFilter(MouseEvent.MOUSE_MOVED,
1042                 s.handler(s.subScene1, DONT_TEST, DONT_TEST));
1043 
1044         s.processEvent(MouseEvent.MOUSE_MOVED, 22, 12);
1045         s.assertCalled();
1046     }
1047 
1048     @Test
1049     public void subSceneShouldNotBePickedWithoutFill() {
1050         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1051 
1052         s.scene.addEventFilter(MouseEvent.MOUSE_MOVED,
1053                 s.handler(s.scene, DONT_TEST, DONT_TEST));
1054 
1055         s.processEvent(MouseEvent.MOUSE_MOVED, 22, 12);
1056         s.assertCalled();
1057     }
1058 
1059     @Test
1060     public void eventShouldBubbleOutOfSubScene() {
1061         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1062 
1063         s.parent1.setOnMouseMoved(s.handler(s.innerRect1, 120, 20));
1064 
1065         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1066         s.assertCalled();
1067     }
1068 
1069     @Test
1070     public void enteredEventShouldBeGeneratedInsideSubScene() {
1071         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1072 
1073         s.innerRect1.setOnMouseEntered(s.handler(s.innerRect1, 10, 10));
1074 
1075         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1076         s.assertCalled();
1077     }
1078 
1079     @Test
1080     public void enteredEventShouldBubbleOutOfSubScene() {
1081         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1082 
1083         s.parent1.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET,
1084                 event -> {
1085                     if (event.getTarget() == s.innerRect1) {
1086                         s.called = true;
1087                     }
1088                 }
1089         );
1090 
1091         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1092         s.assertCalled();
1093     }
1094 
1095     @Test
1096     public void enteredEventShouldBeGeneratedOutsideSubScene() {
1097         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1098 
1099         s.parent1.setOnMouseEntered(s.handler(s.parent1, 120, 20));
1100 
1101         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1102         s.assertCalled();
1103     }
1104 
1105     @Test
1106     public void exitedEventShouldBeGeneratedInsideSubScene() {
1107         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1108 
1109         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 60, 10));
1110 
1111         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1112         s.processEvent(MouseEvent.MOUSE_MOVED, 180, 30);
1113         s.assertCalled();
1114     }
1115 
1116     @Test
1117     public void exitedEventShouldBeGeneratedInsideSubSceneWhenMovedOut() {
1118         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1119 
1120         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 60, -15));
1121 
1122         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1123         s.processEvent(MouseEvent.MOUSE_MOVED, 180, 5);
1124         s.assertCalled();
1125     }
1126 
1127     @Test
1128     public void exitedEventShouldBeGeneratedInsideSubSceneWhenMovedToOtherSubScene() {
1129         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1130 
1131         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 240, 10));
1132 
1133         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1134         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1135         s.assertCalled();
1136     }
1137 
1138     @Test
1139     public void cursorShouldBePropagatedFromSubScene() {
1140         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1141 
1142         s.innerRect1.setCursor(Cursor.HAND);
1143         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1144         assertSame(Cursor.HAND.getCurrentFrame(), s.getCursorFrame());
1145     }
1146 
1147     @Test
1148     public void cursorShouldBeTakenFromOutsideOfSubScene() {
1149         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1150 
1151         s.parent1.setCursor(Cursor.HAND);
1152         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1153         assertSame(Cursor.HAND.getCurrentFrame(), s.getCursorFrame());
1154     }
1155 
1156     @Test
1157     public void coordinatesShouldBeFineWhenDraggedOutOfSubSecne() {
1158         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1159 
1160         s.innerRect1.setOnMouseDragged(s.handler(s.innerRect1, 60, -15));
1161 
1162         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1163         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1164         s.processEvent(MouseEvent.MOUSE_DRAGGED, 180, 5);
1165         s.processEvent(MouseEvent.MOUSE_RELEASED, 180, 5);
1166 
1167         s.assertCalled();
1168         assertNotNull(s.lastPickResult);
1169         assertNull(s.lastPickResult.getIntersectedNode());
1170     }
1171 
1172     @Test
1173     public void coordinatesShouldBeFineWhenDraggedToOtherSubSecne() {
1174         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1175 
1176         s.innerRect1.setOnMouseDragged(s.handler(s.innerRect1, 240, 10));
1177 
1178         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1179         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1180         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1181         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1182 
1183         s.assertCalled();
1184         assertNotNull(s.lastPickResult);
1185         assertSame(s.innerRect2, s.lastPickResult.getIntersectedNode());
1186     }
1187 
1188     @Test
1189     public void fullDragShouldDeliverToOtherSubScene() {
1190         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1191 
1192         s.innerRect1.setOnDragDetected(event -> s.innerRect1.startFullDrag());
1193         s.innerRect2.setOnMouseDragOver(s.handler(s.innerRect2, 10, 10));
1194 
1195         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1196         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1197         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 29);
1198         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1199         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1200 
1201         s.assertCalled();
1202     }
1203 
1204     @Test
1205     public void fullDragEnterShouldDeliverToOtherSubScene() {
1206         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1207 
1208         s.innerRect1.setOnDragDetected(event -> s.innerRect1.startFullDrag());
1209         s.innerRect2.setOnMouseDragEntered(s.handler(s.innerRect2, 10, 10));
1210 
1211         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1212         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1213         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1214         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1215 
1216         s.assertCalled();
1217     }
1218 
1219     @Test
1220     public void fullDragEnterShouldDeliverToOtherSubScenesParent() {
1221         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1222 
1223         s.innerRect1.setOnDragDetected(event -> s.innerRect1.startFullDrag());
1224         s.parent2.setOnMouseDragEntered(s.handler(s.parent2, 130, 20));
1225 
1226         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1227         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1228         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1229         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1230 
1231         s.assertCalled();
1232     }
1233 
1234     @Test
1235     public void depthBufferShouldWorkInsideSubScene() {
1236         final TestSceneWithSubScenes s = new TestSceneWithSubScenes(false, true);
1237 
1238         Rectangle r = new Rectangle(50, 50);
1239         r.setTranslateX(100);
1240         r.setTranslateY(10);
1241         r.setTranslateZ(1);
1242         s.subScene1.getRoot().getChildren().add(r);
1243 
1244         s.innerRect1.addEventFilter(MouseEvent.MOUSE_MOVED,
1245                 s.handler(s.innerRect1, DONT_TEST, DONT_TEST));
1246 
1247         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1248         s.assertCalled();
1249     }
1250 
1251     @Test
1252     public void sceneDepthBufferShouldNotInfluenceSubSceneDepthBuffer() {
1253         final TestSceneWithSubScenes s = new TestSceneWithSubScenes(true, false);
1254 
1255         Rectangle r = new Rectangle(50, 50);
1256         r.setTranslateX(100);
1257         r.setTranslateY(10);
1258         r.setTranslateZ(1);
1259         s.subScene1.getRoot().getChildren().add(r);
1260 
1261         r.addEventFilter(MouseEvent.MOUSE_MOVED,
1262                 s.handler(r, DONT_TEST, DONT_TEST));
1263 
1264         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1265         s.assertCalled();
1266     }
1267 
1268     @Test
1269     public void sceneShouldConsiderSubScenesFlat() {
1270         final TestSceneWithSubScenes s = new TestSceneWithSubScenes(false, true);
1271 
1272         s.parent2.setTranslateX(10);
1273         s.innerRect2.setTranslateZ(-10);
1274         s.parent2.setTranslateZ(1);
1275 
1276         s.innerRect2.addEventFilter(MouseEvent.MOUSE_MOVED,
1277                 s.handler(s.innerRect2, DONT_TEST, DONT_TEST));
1278 
1279         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1280         s.assertCalled();
1281     }
1282 
1283     @Test
1284     public void coordinatesShouldBeFlattenedWhenBubblingOutOfSubScene() {
1285         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1286 
1287         s.subScene1.setTranslateZ(5);
1288         s.innerRect1.setTranslateZ(10);
1289 
1290         s.parent1.setOnMouseMoved(event -> {
1291             Assert.assertEquals(5, event.getZ(), 0.00001);
1292             assertSame(s.innerRect1, event.getTarget());
1293             s.called = true;
1294         });
1295 
1296         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1297         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1298         s.assertCalled();
1299     }
1300     
1301     @Test
1302     public void coordinatesShouldBeReComputedToSubScenePlane() {
1303         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1304 
1305         s.parent2.setTranslateZ(10);
1306         s.innerRect2.setTranslateZ(10);
1307 
1308         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 240, 10));
1309 
1310         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1311         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1312         s.assertCalled();
1313     }
1314 
1315     @Test
1316     public void coordinatesShouldBeRecomputedToSubSceneProjectionPlane() {
1317         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1318 
1319         s.scene.setCamera(new PerspectiveCamera());
1320         s.subScene1.setCamera(new PerspectiveCamera());
1321         s.subScene2.setCamera(new PerspectiveCamera());
1322 
1323         s.subScene1.setRotationAxis(Rotate.Y_AXIS);
1324         s.subScene1.setRotate(45);
1325         s.subScene2.setRotationAxis(Rotate.Y_AXIS);
1326         s.subScene2.setRotate(-45);
1327         ((Group) s.subScene1.getRoot()).getChildren().add(s.subScene1.getCamera());
1328         s.subScene1.getCamera().setTranslateZ(-3.0);
1329 
1330         s.innerRect1.setOnMouseExited(event -> {
1331             assertSame(s.innerRect2, event.getPickResult().getIntersectedNode());
1332             assertSame(s.innerRect1, event.getTarget());
1333             Assert.assertEquals(16.58, event.getPickResult().getIntersectedPoint().getX(), 0.1);
1334             Assert.assertEquals(7.33, event.getPickResult().getIntersectedPoint().getY(), 0.1);
1335             Assert.assertEquals(0.0, event.getPickResult().getIntersectedPoint().getZ(), 0.0001);
1336             Assert.assertEquals(295.81, event.getX(), 0.1);
1337             Assert.assertEquals(57.64, event.getY(), 0.1);
1338             Assert.assertEquals(-3.0, event.getZ(), 0.1);
1339 
1340             s.called = true;
1341         });
1342 
1343         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1344         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1345         s.assertCalled();
1346     }
1347 
1348     @Test
1349     public void coordinatesShouldBeRecomputedToNodeLocalCoordsOfSubSceneProjectionPlane() {
1350         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1351 
1352         s.scene.setCamera(new PerspectiveCamera());
1353         s.subScene1.setCamera(new PerspectiveCamera());
1354         s.subScene2.setCamera(new PerspectiveCamera());
1355 
1356         s.subScene1.setRotationAxis(Rotate.Y_AXIS);
1357         s.subScene1.setRotate(45);
1358         s.innerRect1.setRotationAxis(Rotate.Y_AXIS);
1359         s.innerRect1.setRotate(-45);
1360         s.subScene2.setRotationAxis(Rotate.Y_AXIS);
1361         s.subScene2.setRotate(-45);
1362         s.innerRect2.setRotationAxis(Rotate.Y_AXIS);
1363         s.innerRect2.setRotate(45);
1364 
1365         s.innerRect1.setOnMouseExited(event -> {
1366             assertSame(s.innerRect2, event.getPickResult().getIntersectedNode());
1367             assertSame(s.innerRect1, event.getTarget());
1368             Assert.assertEquals(14.07, event.getPickResult().getIntersectedPoint().getX(), 0.1);
1369             Assert.assertEquals(5.97, event.getPickResult().getIntersectedPoint().getY(), 0.1);
1370             Assert.assertEquals(0.0, event.getPickResult().getIntersectedPoint().getZ(), 0.0001);
1371             Assert.assertEquals(216.49, event.getX(), 0.1);
1372             Assert.assertEquals(57.64, event.getY(), 0.1);
1373             Assert.assertEquals(-191.49, event.getZ(), 0.1);
1374 
1375             s.called = true;
1376         });
1377 
1378         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1379         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1380         s.assertCalled();
1381     }
1382 
1383     @Test
1384     public void ImpossibleToComputeSubSceneInnerNodeCoordsShouldResultInNaNs() {
1385         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1386 
1387         s.parent2.setTranslateZ(10);
1388         s.innerRect2.setTranslateZ(10);
1389 
1390         s.innerRect1.setOnMouseMoved(event -> s.innerRect1.setScaleX(0.0));
1391 
1392         s.innerRect1.setOnMouseExited(event -> {
1393             assertSame(s.innerRect1, event.getTarget());
1394             assertTrue(Double.isNaN(event.getX()));
1395             assertTrue(Double.isNaN(event.getY()));
1396             assertTrue(Double.isNaN(event.getZ()));
1397             s.called = true;
1398         });
1399 
1400         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1401         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1402         s.assertCalled();
1403     }
1404 
1405     @Test
1406     public void ImpossibleToComputeSubSceneCoordsShouldResultInNaNs() {
1407         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1408 
1409         s.parent2.setTranslateZ(10);
1410         s.innerRect2.setTranslateZ(10);
1411 
1412         s.innerRect1.setOnMouseMoved(event -> {
1413             s.subScene1.setRotationAxis(Rotate.Y_AXIS);
1414             s.subScene1.setRotate(90);
1415         });
1416 
1417         s.innerRect1.setOnMouseExited(event -> {
1418             assertSame(s.innerRect1, event.getTarget());
1419             assertTrue(Double.isNaN(event.getX()));
1420             assertTrue(Double.isNaN(event.getY()));
1421             assertTrue(Double.isNaN(event.getZ()));
1422             s.called = true;
1423         });
1424 
1425         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1426         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1427         s.assertCalled();
1428     }
1429 
1430     @Test
1431     public void mouseExitedShouldBeGeneratedBeforeNodeRemoval() {
1432         final SimpleTestScene s = new SimpleTestScene();
1433         s.smallSquareTracker.node.addEventHandler(MouseEvent.MOUSE_EXITED,
1434                 event -> assertNotNull(s.smallSquareTracker.node.getScene())
1435         );
1436 
1437         s.processEvent(MouseEventGenerator.generateMouseEvent(
1438                 MouseEvent.MOUSE_MOVED, 250, 250));
1439         assertTrue(s.smallSquareTracker.enteredMe);
1440         assertFalse(s.smallSquareTracker.exitedMe);
1441 
1442         s.scene.getRoot().getChildren().clear();
1443 
1444         assertTrue(s.smallSquareTracker.exitedMe);
1445     }
1446 
1447     @Test
1448     public void pdrGestureShouldHandleDraggedNodeRemoval() {
1449         final SimpleTestScene s = new SimpleTestScene();
1450 
1451         s.processEvent(MouseEventGenerator.generateMouseEvent(
1452                 MouseEvent.MOUSE_MOVED, 250, 250));
1453         assertTrue(s.smallSquareTracker.node.isHover());
1454         assertFalse(s.smallSquareTracker.node.isPressed());
1455 
1456         s.processEvent(MouseEventGenerator.generateMouseEvent(
1457                 MouseEvent.MOUSE_PRESSED, 250, 250));
1458         assertTrue(s.smallSquareTracker.node.isHover());
1459         assertTrue(s.smallSquareTracker.node.isPressed());
1460         assertTrue(s.smallSquareTracker.wasPressed());
1461         assertTrue(s.groupTracker.wasPressed());
1462 
1463         s.processEvent(MouseEventGenerator.generateMouseEvent(
1464                 MouseEvent.MOUSE_DRAGGED, 255, 255));
1465         assertTrue(s.smallSquareTracker.node.isHover());
1466         assertTrue(s.smallSquareTracker.node.isPressed());
1467         assertTrue(s.smallSquareTracker.wasDragged());
1468         assertTrue(s.groupTracker.wasDragged());
1469 
1470         s.smallSquareTracker.clear();
1471         s.groupTracker.clear();
1472         s.rootTracker.clear();
1473 
1474         s.scene.getRoot().getChildren().clear();
1475         assertFalse(s.smallSquareTracker.node.isHover());
1476         assertFalse(s.smallSquareTracker.node.isPressed());
1477         assertFalse(s.groupTracker.node.isHover());
1478         assertFalse(s.groupTracker.node.isPressed());
1479         assertTrue(s.rootTracker.node.isHover());
1480         assertTrue(s.rootTracker.node.isPressed());
1481         assertTrue(s.smallSquareTracker.wasExitedMe());
1482         assertTrue(s.groupTracker.wasExitedMe());
1483         assertFalse(s.rootTracker.wasExitedMe());
1484 
1485         s.processEvent(MouseEventGenerator.generateMouseEvent(
1486                 MouseEvent.MOUSE_DRAGGED, 260, 260));
1487         assertFalse(s.smallSquareTracker.wasDragged());
1488         assertFalse(s.groupTracker.wasDragged());
1489         assertTrue(s.rootTracker.wasDragged());
1490 
1491         s.processEvent(MouseEventGenerator.generateMouseEvent(
1492                 MouseEvent.MOUSE_RELEASED, 270, 270));
1493         assertFalse(s.smallSquareTracker.wasReleased());
1494         assertFalse(s.groupTracker.wasReleased());
1495         assertTrue(s.rootTracker.wasReleased());
1496     }
1497     
1498     @Test
1499     public void testMouseEventCanEditCursor() {
1500         final SimpleTestScene s = new SimpleTestScene();
1501         
1502         s.smallSquare.setOnMousePressed(event -> s.smallSquare.setCursor(Cursor.CROSSHAIR));
1503         
1504         s.smallSquare.setOnMouseReleased(event -> s.smallSquare.setCursor(Cursor.WAIT));
1505         
1506         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_MOVED, 250, 250));
1507         assertSame(Cursor.HAND.getCurrentFrame(), s.getCursorFrame());
1508         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 250, 250));
1509         assertSame(Cursor.CROSSHAIR.getCurrentFrame(), s.getCursorFrame());
1510         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 250, 250));
1511         assertSame(Cursor.WAIT.getCurrentFrame(), s.getCursorFrame());
1512         
1513         s.smallSquare.setOnMouseClicked(event -> s.smallSquare.setCursor(Cursor.TEXT));
1514         
1515         s.smallSquare.setCursor(Cursor.HAND);
1516         
1517         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_MOVED, 250, 250));
1518         assertSame(Cursor.HAND.getCurrentFrame(), s.getCursorFrame());
1519         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 250, 250));
1520         assertSame(Cursor.CROSSHAIR.getCurrentFrame(), s.getCursorFrame());
1521         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 250, 250));
1522         assertSame(Cursor.TEXT.getCurrentFrame(), s.getCursorFrame());
1523     }
1524     
1525     private static class SimpleTestScene {
1526 
1527         MouseEventTracker sceneTracker;
1528         MouseEventTracker rootTracker;
1529         MouseEventTracker groupTracker;
1530         MouseEventTracker bigSquareTracker;
1531         MouseEventTracker smallSquareTracker;
1532         
1533         Rectangle smallSquare;
1534         private boolean moused = false;
1535         private Scene scene;
1536 
1537         public SimpleTestScene() {
1538             this(false, false);
1539         }
1540 
1541         public SimpleTestScene(boolean depthBuffer, boolean perspective) {
1542             final Group root = new Group();
1543             scene = new Scene(root, 400, 400, depthBuffer);
1544             if (perspective) {
1545                 scene.setCamera(new PerspectiveCamera());
1546             }
1547 
1548             Group group = new Group();
1549             Rectangle bigSquare = new Rectangle(100, 100, 200, 200);
1550             smallSquare = new Rectangle(200, 200, 100, 100);
1551             bigSquare.setTranslateZ(-1);
1552 
1553             smallSquare.setCursor(Cursor.HAND);
1554             group.setCursor(Cursor.TEXT);
1555 
1556             group.getChildren().add(bigSquare);
1557             group.getChildren().add(smallSquare);
1558 
1559             root.getChildren().add(group);
1560 
1561             sceneTracker = new MouseEventTracker(scene);
1562             rootTracker = new MouseEventTracker(root);
1563             groupTracker = new MouseEventTracker(group);
1564             bigSquareTracker = new MouseEventTracker(bigSquare);
1565             smallSquareTracker = new MouseEventTracker(smallSquare);
1566 
1567             scene.addEventHandler(MouseEvent.ANY, event -> {
1568                 moused = true;
1569             });
1570 
1571             Stage stage = new Stage();
1572             stage.setScene(scene);
1573             stage.show();
1574         }
1575 
1576         public void processEvent(MouseEvent e) {
1577             scene.impl_processMouseEvent(e);
1578         }
1579 
1580         public Object getCursorFrame() {
1581             return ((StubScene) scene.impl_getPeer()).getCursor();
1582         }
1583 
1584         public boolean wasMoused() {
1585             return moused;
1586         }
1587 
1588         public void clear() {
1589             moused = false;
1590             sceneTracker.clear();
1591             groupTracker.clear();
1592             bigSquareTracker.clear();
1593             smallSquareTracker.clear();
1594         }
1595     }
1596 
1597     private static class MouseEventTracker {
1598 
1599         private Node node;
1600         private boolean pressed = false;
1601         private boolean released = false;
1602         private boolean clicked = false;
1603         private boolean doubleClicked = false;
1604         private boolean moved = false;
1605         private boolean dragged = false;
1606         private boolean enteredMe = false;
1607         private boolean exitedMe = false;
1608         private boolean enteredChild = false;
1609         private boolean exitedChild = false;
1610         private int lastClickCount = 0;
1611         private boolean lastIsStill = false;
1612 
1613         public MouseEventTracker(Node node) {
1614             this.node = node;
1615 
1616             node.setOnMousePressed(event -> {
1617                 pressed = true;
1618             });
1619 
1620             node.setOnMouseReleased(event -> {
1621                 released = true;
1622             });
1623 
1624             node.setOnMouseClicked(event -> {
1625                 if (event.getClickCount() == 1) {
1626                     clicked = true;
1627                 } else if (event.getClickCount() == 2) {
1628                     doubleClicked = true;
1629                 }
1630             });
1631 
1632             node.setOnMouseMoved(event -> {
1633                 moved = true;
1634             });
1635 
1636             node.setOnMouseDragged(event -> {
1637                 dragged = true;
1638             });
1639 
1640             node.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, event -> {
1641                 if (event.getTarget() == MouseEventTracker.this.node) {
1642                     enteredMe = true;
1643                 } else {
1644                     enteredChild = true;
1645                 }
1646             });
1647 
1648             node.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, event -> {
1649                 if (event.getTarget() == MouseEventTracker.this.node) {
1650                     exitedMe = true;
1651                 } else {
1652                     exitedChild = true;
1653                 }
1654             });
1655             
1656             node.addEventHandler(MouseEvent.ANY, event -> {
1657                 if (event.getEventType() != MouseEvent.MOUSE_CLICKED) {
1658                     lastClickCount = event.getClickCount();
1659                     lastIsStill = event.isStillSincePress();
1660                 }
1661             });
1662         }
1663 
1664         public MouseEventTracker(Scene scene) {
1665             scene.setOnMouseEntered(event -> {
1666                 enteredMe = true;
1667             });
1668 
1669             scene.setOnMouseExited(event -> {
1670                 exitedMe = true;
1671             });
1672         }
1673 
1674         public boolean wasClicked() {
1675             return clicked;
1676         }
1677 
1678         public boolean wasDoubleClicked() {
1679             return doubleClicked;
1680         }
1681 
1682         public boolean wasDragged() {
1683             return dragged;
1684         }
1685 
1686         public boolean wasEnteredMe() {
1687             return enteredMe;
1688         }
1689 
1690         public boolean wasExitedMe() {
1691             return exitedMe;
1692         }
1693 
1694         public boolean wasMoved() {
1695             return moved;
1696         }
1697 
1698         public boolean wasPressed() {
1699             return pressed;
1700         }
1701 
1702         public boolean wasReleased() {
1703             return released;
1704         }
1705 
1706         public boolean wasEnteredChild() {
1707             return enteredChild;
1708         }
1709 
1710         public boolean wasExitedChild() {
1711             return exitedChild;
1712         }
1713 
1714         public boolean isHover() {
1715             return node.isHover();
1716         }
1717         
1718         public int getLastClickCount() {
1719             return lastClickCount;
1720         }
1721         
1722         public boolean wasLastStill() {
1723             return lastIsStill;
1724         }
1725 
1726         public void clear() {
1727             pressed = false;
1728             released = false;
1729             clicked = false;
1730             doubleClicked = false;
1731             moved = false;
1732             dragged = false;
1733             enteredMe = false;
1734             exitedMe = false;
1735             enteredChild = false;
1736             exitedChild = false;
1737             lastClickCount = 0;
1738         }
1739     }
1740 
1741     private static class TestSceneWithSubScenes {
1742         private SubScene subScene1, subScene2;
1743         private Rectangle innerRect1, innerRect2;
1744         private Group root, parent1, parent2;
1745         private Scene scene;
1746         private boolean called = false;
1747         private PickResult lastPickResult = null;
1748 
1749         public TestSceneWithSubScenes() {
1750             this(false, false);
1751         }
1752 
1753         public TestSceneWithSubScenes(boolean depthBuffer, boolean subDepthBuffer) {
1754             root = new Group();
1755             scene = new Scene(root, 500, 400, depthBuffer);
1756 
1757             innerRect1 = new Rectangle(50, 50);
1758             innerRect1.setTranslateX(100);
1759             innerRect1.setTranslateY(10);
1760             subScene1 = new SubScene(new Group(innerRect1), 200, 100,
1761                     subDepthBuffer, null);
1762             subScene1.setTranslateX(10);
1763             parent1 = new Group(subScene1);
1764             parent1.setTranslateX(10);
1765             parent1.setTranslateY(10);
1766 
1767             innerRect2 = new Rectangle(50, 50);
1768             innerRect2.setTranslateX(100);
1769             innerRect2.setTranslateY(10);
1770             subScene2 = new SubScene(new Group(innerRect2), 200, 100);
1771             subScene2.setTranslateX(20);
1772 
1773             parent2 = new Group(subScene2);
1774             parent2.setTranslateX(230);
1775             parent2.setTranslateY(10);
1776 
1777 
1778             root.getChildren().addAll(parent1, parent2);
1779 
1780             Stage stage = new Stage();
1781             stage.setScene(scene);
1782             stage.show();
1783         }
1784 
1785         public void processEvent(EventType<MouseEvent> type, double x, double y) {
1786             scene.impl_processMouseEvent(
1787                     MouseEventGenerator.generateMouseEvent(type, x, y));
1788         }
1789 
1790         public Object getCursorFrame() {
1791             return ((StubScene) scene.impl_getPeer()).getCursor();
1792         }
1793 
1794         public EventHandler<MouseEvent> handler(final EventTarget target,
1795                 final double x, final double y) {
1796 
1797             return event -> {
1798                 if (target != null) assertSame(target, event.getTarget());
1799                 if (x != DONT_TEST) assertEquals(x, event.getX(), 0.00001);
1800                 if (y != DONT_TEST) assertEquals(y, event.getY(), 0.00001);
1801                 assertEquals(0.0, event.getZ(), 0.00001);
1802                 lastPickResult = event.getPickResult();
1803                 called = true;
1804             };
1805         }
1806 
1807         public void assertCalled() {
1808             assertTrue(called);
1809         }
1810     }
1811 
1812 }