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