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 test.javafx.scene.input; 27 28 import static org.junit.Assert.assertNull; 29 import static org.junit.Assert.fail; 30 31 import java.security.AccessControlContext; 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.HashSet; 35 import java.util.List; 36 import java.util.Set; 37 38 import com.sun.javafx.tk.TKScene; 39 import javafx.event.EventHandler; 40 import javafx.scene.Group; 41 import javafx.scene.Node; 42 import javafx.scene.Scene; 43 import javafx.scene.shape.Rectangle; 44 import javafx.stage.Stage; 45 import javafx.util.Pair; 46 47 import org.junit.After; 48 import org.junit.Assert; 49 import org.junit.Before; 50 import org.junit.Test; 51 52 import test.com.sun.javafx.pgstub.StubToolkit; 53 import com.sun.javafx.tk.TKClipboard; 54 import com.sun.javafx.tk.TKDragGestureListener; 55 import com.sun.javafx.tk.TKDragSourceListener; 56 import com.sun.javafx.tk.TKDropTargetListener; 57 import com.sun.javafx.tk.Toolkit; 58 import test.com.sun.javafx.test.MouseEventGenerator; 59 import javafx.event.Event; 60 import javafx.geometry.Point3D; 61 import javafx.scene.SubScene; 62 import javafx.scene.image.Image; 63 import javafx.scene.input.ClipboardContent; 64 import javafx.scene.input.ClipboardContent; 65 import javafx.scene.input.DataFormat; 66 import javafx.scene.input.DataFormat; 67 import javafx.scene.input.DragEvent; 68 import javafx.scene.input.DragEvent; 69 import javafx.scene.input.Dragboard; 70 import javafx.scene.input.Dragboard; 71 import javafx.scene.input.DragboardShim; 72 import javafx.scene.input.MouseEvent; 73 import javafx.scene.input.MouseEvent; 74 import javafx.scene.input.PickResult; 75 import javafx.scene.input.PickResult; 76 import javafx.scene.input.TransferMode; 77 import javafx.scene.input.TransferMode; 78 import static org.junit.Assert.assertEquals; 79 import static org.junit.Assert.assertFalse; 80 import static org.junit.Assert.assertNotNull; 81 import static org.junit.Assert.assertSame; 82 import static org.junit.Assert.assertTrue; 83 84 public class DragAndDropTest { 85 86 private DndToolkit toolkit = new DndToolkit(); 87 private int counter; 88 private boolean detected; 89 private Node dragSource; 90 91 @Before 92 public void setUp() { 93 counter = 0; 94 detected = false; 95 toolkit = new DndToolkit(); 96 ((StubToolkit) Toolkit.getToolkit()).setDndDelegate(toolkit); 97 } 98 99 @After 100 public void tearDown() { 101 ((StubToolkit) Toolkit.getToolkit()).setDndDelegate(null); 102 toolkit = null; 103 } 104 105 /************************************************************************/ 106 /* DRAG EVENT CONSTRUCTOR */ 107 /************************************************************************/ 108 109 @Test public void testShortConstructor() { 110 Rectangle node = new Rectangle(10, 10); 111 node.setTranslateX(3); 112 node.setTranslateY(2); 113 node.setTranslateZ(50); 114 Dragboard db = DragboardShim.getDragboard(new ClipboardImpl()); 115 Rectangle gsrc = new Rectangle(10, 10); 116 Rectangle gtrg = new Rectangle(10, 10); 117 118 PickResult pickRes = new PickResult(node, new Point3D(15, 25, 100), 33); 119 DragEvent e = new DragEvent(DragEvent.DRAG_ENTERED, db, 10, 20, 30, 40, 120 TransferMode.LINK, gsrc, gtrg, pickRes); 121 122 assertSame(DragEvent.DRAG_ENTERED, e.getEventType()); 123 assertEquals(18, e.getX(), 10e-20); 124 assertEquals(27, e.getY(), 10e-20); 125 assertEquals(150, e.getZ(), 10e-20); 126 assertEquals(10, e.getSceneX(), 10e-20); 127 assertEquals(20, e.getSceneY(), 10e-20); 128 assertEquals(30, e.getScreenX(), 10e-20); 129 assertEquals(40, e.getScreenY(), 10e-20); 130 assertSame(db, e.getDragboard()); 131 assertSame(gsrc, e.getGestureSource()); 132 assertSame(gtrg, e.getGestureTarget()); 133 assertSame(TransferMode.LINK, e.getTransferMode()); 134 assertSame(pickRes, e.getPickResult()); 135 assertSame(Event.NULL_SOURCE_TARGET, e.getSource()); 136 assertSame(Event.NULL_SOURCE_TARGET, e.getTarget()); 137 assertFalse(e.isAccepted()); 138 assertNull(e.getAcceptedTransferMode()); 139 assertFalse(e.isConsumed()); 140 } 141 142 @Test public void testShortConstructorWithoutPickResult() { 143 Dragboard db = DragboardShim.getDragboard(new ClipboardImpl()); 144 Rectangle gsrc = new Rectangle(10, 10); 145 Rectangle gtrg = new Rectangle(10, 10); 146 DragEvent e = new DragEvent(DragEvent.DRAG_ENTERED, db, 10, 20, 30, 40, 147 TransferMode.LINK, gsrc, gtrg, null); 148 149 assertEquals(10, e.getX(), 10e-20); 150 assertEquals(20, e.getY(), 10e-20); 151 assertEquals(0, e.getZ(), 10e-20); 152 assertEquals(10, e.getSceneX(), 10e-20); 153 assertEquals(20, e.getSceneY(), 10e-20); 154 assertEquals(30, e.getScreenX(), 10e-20); 155 assertEquals(40, e.getScreenY(), 10e-20); 156 assertNotNull(e.getPickResult()); 157 assertNotNull(e.getPickResult().getIntersectedPoint()); 158 assertEquals(10, e.getPickResult().getIntersectedPoint().getX(), 10e-20); 159 assertEquals(20, e.getPickResult().getIntersectedPoint().getY(), 10e-20); 160 assertEquals(0, e.getPickResult().getIntersectedPoint().getZ(), 10e-20); 161 assertSame(Event.NULL_SOURCE_TARGET, e.getSource()); 162 assertSame(Event.NULL_SOURCE_TARGET, e.getTarget()); 163 } 164 165 @Test public void testLongConstructor() { 166 Rectangle node = new Rectangle(10, 10); 167 node.setTranslateX(3); 168 node.setTranslateY(2); 169 node.setTranslateZ(50); 170 Rectangle n1 = new Rectangle(10, 10); 171 Rectangle n2 = new Rectangle(10, 10); 172 Dragboard db = DragboardShim.getDragboard(new ClipboardImpl()); 173 Rectangle gsrc = new Rectangle(10, 10); 174 Rectangle gtrg = new Rectangle(10, 10); 175 176 PickResult pickRes = new PickResult(node, new Point3D(15, 25, 100), 33); 177 DragEvent e = new DragEvent(n1, n2, DragEvent.DRAG_ENTERED, db, 178 10, 20, 30, 40, TransferMode.LINK, gsrc, gtrg, pickRes); 179 assertSame(n1, e.getSource()); 180 assertSame(n2, e.getTarget()); 181 assertSame(DragEvent.DRAG_ENTERED, e.getEventType()); 182 assertEquals(18, e.getX(), 10e-20); 183 assertEquals(27, e.getY(), 10e-20); 184 assertEquals(150, e.getZ(), 10e-20); 185 assertEquals(10, e.getSceneX(), 10e-20); 186 assertEquals(20, e.getSceneY(), 10e-20); 187 assertEquals(30, e.getScreenX(), 10e-20); 188 assertEquals(40, e.getScreenY(), 10e-20); 189 assertSame(TransferMode.LINK, e.getTransferMode()); 190 assertSame(db, e.getDragboard()); 191 assertSame(gsrc, e.getGestureSource()); 192 assertSame(gtrg, e.getGestureTarget()); 193 assertSame(pickRes, e.getPickResult()); 194 assertFalse(e.isConsumed()); 195 assertFalse(e.isAccepted()); 196 assertNull(e.getAcceptedTransferMode()); 197 } 198 199 @Test public void testLongConstructorWithoutPickResult() { 200 Rectangle n1 = new Rectangle(10, 10); 201 Rectangle n2 = new Rectangle(10, 10); 202 Dragboard db = DragboardShim.getDragboard(new ClipboardImpl()); 203 Rectangle gsrc = new Rectangle(10, 10); 204 Rectangle gtrg = new Rectangle(10, 10); 205 DragEvent e = new DragEvent(n1, n2, DragEvent.DRAG_ENTERED, db, 206 10, 20, 30, 40, TransferMode.LINK, gsrc, gtrg, null); 207 208 assertEquals(10, e.getX(), 10e-20); 209 assertEquals(20, e.getY(), 10e-20); 210 assertEquals(0, e.getZ(), 10e-20); 211 assertEquals(10, e.getSceneX(), 10e-20); 212 assertEquals(20, e.getSceneY(), 10e-20); 213 assertEquals(30, e.getScreenX(), 10e-20); 214 assertEquals(40, e.getScreenY(), 10e-20); 215 assertNotNull(e.getPickResult()); 216 assertNotNull(e.getPickResult().getIntersectedPoint()); 217 assertEquals(10, e.getPickResult().getIntersectedPoint().getX(), 10e-20); 218 assertEquals(20, e.getPickResult().getIntersectedPoint().getY(), 10e-20); 219 assertEquals(0, e.getPickResult().getIntersectedPoint().getZ(), 10e-20); 220 } 221 222 @Test public void shortConstructorMakesDropAccepted() { 223 DragEvent e = new DragEvent(DragEvent.DRAG_DROPPED, 224 DragboardShim.getDragboard( 225 new ClipboardImpl()), 10, 20, 30, 40, 226 TransferMode.LINK, new Rectangle(), new Rectangle(), null); 227 assertSame(DragEvent.DRAG_DROPPED, e.getEventType()); 228 assertTrue(e.isAccepted()); 229 assertSame(TransferMode.LINK, e.getAcceptedTransferMode()); 230 } 231 232 @Test 233 public void shortConstructorMakesDoneAccepted() { 234 DragEvent e = new DragEvent(DragEvent.DRAG_DONE, 235 DragboardShim.getDragboard( 236 new ClipboardImpl()), 10, 20, 30, 40, 237 TransferMode.LINK, new Rectangle(), new Rectangle(), null); 238 assertSame(DragEvent.DRAG_DONE, e.getEventType()); 239 assertTrue(e.isAccepted()); 240 assertSame(TransferMode.LINK, e.getAcceptedTransferMode()); 241 } 242 243 @Test public void longConstructorMakesDropAccepted() { 244 DragEvent e = new DragEvent(new Rectangle(), new Rectangle(), 245 DragEvent.DRAG_DROPPED, 246 DragboardShim.getDragboard( 247 new ClipboardImpl()), 10, 20, 30, 40, 248 TransferMode.LINK, new Rectangle(), new Rectangle(), null); 249 assertSame(DragEvent.DRAG_DROPPED, e.getEventType()); 250 assertTrue(e.isAccepted()); 251 assertSame(TransferMode.LINK, e.getAcceptedTransferMode()); 252 } 253 254 @Test public void longConstructorMakesDoneAccepted() { 255 DragEvent e = new DragEvent(new Rectangle(), new Rectangle(), 256 DragEvent.DRAG_DONE, 257 DragboardShim.getDragboard( 258 new ClipboardImpl()), 10, 20, 30, 40, 259 TransferMode.LINK, new Rectangle(), new Rectangle(), null); 260 assertSame(DragEvent.DRAG_DONE, e.getEventType()); 261 assertTrue(e.isAccepted()); 262 assertSame(TransferMode.LINK, e.getAcceptedTransferMode()); 263 } 264 265 /************************************************************************/ 266 /* DRAG INITIATION */ 267 /************************************************************************/ 268 269 270 @Test 271 public void dragDetectionShouldUseHysteresis() { 272 Node n = oneNode(); 273 MouseEventGenerator gen = new MouseEventGenerator(); 274 275 EventHandler<MouseEvent> thirdEventFailsHysteresis = 276 event -> { 277 counter++; 278 assertTrue((counter != 3 && !event.isDragDetect()) || 279 (counter == 3 && event.isDragDetect())); 280 }; 281 282 n.addEventHandler(MouseEvent.MOUSE_PRESSED, thirdEventFailsHysteresis); 283 n.addEventHandler(MouseEvent.MOUSE_DRAGGED, thirdEventFailsHysteresis); 284 n.addEventHandler(MouseEvent.MOUSE_RELEASED, thirdEventFailsHysteresis); 285 286 n.getScene().impl_processMouseEvent( 287 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 288 n.getScene().impl_processMouseEvent( 289 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 52, 48)); 290 n.getScene().impl_processMouseEvent( 291 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 70, 70)); 292 n.getScene().impl_processMouseEvent( 293 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 50, 50)); 294 n.getScene().impl_processMouseEvent( 295 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50)); 296 297 assertEquals(5, counter); 298 } 299 300 @Test 301 public void dragShouldNotBeDetectedBasedOnMoveOrRelase() { 302 Node n = oneNode(); 303 MouseEventGenerator gen = new MouseEventGenerator(); 304 305 n.setOnDragDetected(detector); 306 n.setOnMousePressed(dontDetect); 307 n.setOnMouseMoved(doDetect); 308 n.setOnMouseReleased(doDetect); 309 310 /* dontDetect prevents detection */ 311 n.getScene().impl_processMouseEvent( 312 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 313 assertFalse(detected); 314 315 n.getScene().impl_processMouseEvent( 316 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50)); 317 assertFalse(detected); 318 319 n.getScene().impl_processMouseEvent( 320 gen.generateMouseEvent(MouseEvent.MOUSE_MOVED, 60, 60)); 321 assertFalse(detected); 322 } 323 324 @Test 325 public void dragShouldBeDetectedBasedOnMouseEvent() { 326 Node n = oneNode(); 327 MouseEventGenerator gen = new MouseEventGenerator(); 328 329 n.setOnDragDetected(detector); 330 n.setOnMousePressed(dontDetect); 331 n.setOnMouseDragged(dontDetect); 332 n.setOnMouseReleased(doDetect); 333 334 /* dontDetect prevents detection */ 335 n.getScene().impl_processMouseEvent( 336 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 337 assertFalse(detected); 338 n.getScene().impl_processMouseEvent( 339 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 52, 48)); 340 assertFalse(detected); 341 n.getScene().impl_processMouseEvent( 342 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 70, 70)); 343 assertFalse(detected); 344 345 /* doDetect fires detection */ 346 n.setOnMouseDragged(doDetect); 347 348 n.getScene().impl_processMouseEvent( 349 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 50, 50)); 350 assertTrue(detected); 351 detected = false; 352 353 /* but fires it only once */ 354 n.getScene().impl_processMouseEvent( 355 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 70, 70)); 356 assertFalse(detected); 357 358 n.getScene().impl_processMouseEvent( 359 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50)); 360 assertFalse(detected); 361 } 362 363 @Test 364 public void dragDetectionShouldBeOverridable() { 365 Node n = oneNode(); 366 MouseEventGenerator gen = new MouseEventGenerator(); 367 368 n.setOnDragDetected(detector); 369 n.setOnMousePressed(doDetect); 370 n.setOnMouseDragged(dontDetect); 371 n.getParent().setOnMousePressed(dontDetect); 372 n.getParent().setOnMouseDragged(doDetect); 373 374 /* dontDetect prevents detection */ 375 n.getScene().impl_processMouseEvent( 376 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 377 assertFalse(detected); 378 379 n.getScene().impl_processMouseEvent( 380 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 50, 50)); 381 assertTrue(detected); 382 detected = false; 383 384 n.getScene().impl_processMouseEvent( 385 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50)); 386 assertFalse(detected); 387 } 388 389 @Test 390 public void startDragShouldNotBeCalledIfNothingPutOnDragboard() { 391 final Node n = oneNode(); 392 final MouseEventGenerator gen = new MouseEventGenerator(); 393 394 n.setOnMousePressed(doDetect); 395 n.setOnDragDetected(event -> { 396 n.startDragAndDrop(TransferMode.COPY); 397 }); 398 399 n.getScene().impl_processMouseEvent( 400 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 401 n.getScene().impl_processMouseEvent( 402 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 50, 50)); 403 n.getScene().impl_processMouseEvent( 404 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50)); 405 406 assertFalse(toolkit.dragging); 407 } 408 409 @Test 410 public void startDragShouldBeCalledIfStringPutOnDragboard() { 411 final Node n = oneNode(); 412 final MouseEventGenerator gen = new MouseEventGenerator(); 413 414 dragSource = n; 415 n.setOnMousePressed(doDetect); 416 n.setOnDragDetected(stringSource(TransferMode.ANY)); 417 418 n.getScene().impl_processMouseEvent( 419 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 420 assertTrue(toolkit.dragging); 421 } 422 423 /************************************************************************/ 424 /* SOURCE/TARGET */ 425 /************************************************************************/ 426 427 @Test 428 public void nodeThatCallsStartDndShouldBecomeGestureSource() { 429 final Node n = oneNode(); 430 final MouseEventGenerator gen = new MouseEventGenerator(); 431 432 dragSource = n.getParent(); 433 n.setOnMousePressed(doDetect); 434 n.setOnDragDetected(stringSource(TransferMode.ANY)); 435 n.setOnDragOver(event -> { 436 assertSame(dragSource, event.getGestureSource()); 437 counter++; 438 }); 439 440 n.getScene().impl_processMouseEvent( 441 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 442 toolkit.dragTo(52, 52, TransferMode.COPY); 443 444 assertEquals(1, counter); 445 } 446 447 @Test 448 public void parentThatCallsStartDndShouldBecomeGestureSource() { 449 final Node n = oneNode(); 450 final MouseEventGenerator gen = new MouseEventGenerator(); 451 452 dragSource = n.getParent(); 453 n.setOnMousePressed(doDetect); 454 n.getParent().setOnDragDetected(stringSource(TransferMode.ANY)); 455 n.setOnDragOver(event -> { 456 assertSame(dragSource, event.getGestureSource()); 457 counter++; 458 }); 459 460 n.getScene().impl_processMouseEvent( 461 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 462 toolkit.dragTo(52, 52, TransferMode.COPY); 463 464 assertEquals(1, counter); 465 } 466 467 @Test 468 public void nodeThatAcceptsDragShouldBecomeGestureTarget() { 469 final Node n = oneNode(); 470 final MouseEventGenerator gen = new MouseEventGenerator(); 471 472 dragSource = n; 473 n.setOnMousePressed(doDetect); 474 n.setOnDragDetected(stringSource(TransferMode.ANY)); 475 n.setOnDragOver(event -> { 476 event.acceptTransferModes(TransferMode.ANY); 477 if (counter == 0) { 478 assertNull(event.getGestureTarget()); 479 } else { 480 assertSame(n, event.getGestureTarget()); 481 } 482 counter++; 483 }); 484 n.setOnDragDropped(event -> { 485 assertSame(n, event.getGestureTarget()); 486 counter++; 487 }); 488 489 n.getScene().impl_processMouseEvent( 490 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 491 toolkit.dragTo(51, 51, TransferMode.COPY); 492 toolkit.dragTo(52, 52, TransferMode.COPY); 493 toolkit.drop(52, 52, TransferMode.COPY); 494 495 assertEquals(3, counter); 496 } 497 498 @Test 499 public void parentThatAcceptsDragShouldBecomeGestureTarget() { 500 final Node n = oneNode(); 501 final MouseEventGenerator gen = new MouseEventGenerator(); 502 503 dragSource = n; 504 n.setOnMousePressed(doDetect); 505 n.setOnDragDetected(stringSource(TransferMode.ANY)); 506 n.setOnDragOver(event -> { 507 event.acceptTransferModes(TransferMode.ANY); 508 if (counter == 0) { 509 assertNull(event.getGestureTarget()); 510 } else { 511 assertSame(n.getParent(), event.getGestureTarget()); 512 } 513 counter++; 514 }); 515 n.getParent().setOnDragOver(acceptAny); 516 n.setOnDragDropped(event -> { 517 assertSame(n.getParent(), event.getGestureTarget()); 518 counter++; 519 }); 520 521 n.getScene().impl_processMouseEvent( 522 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 523 toolkit.dragTo(51, 51, TransferMode.COPY); 524 toolkit.dragTo(52, 52, TransferMode.COPY); 525 toolkit.drop(52, 52, TransferMode.COPY); 526 527 assertEquals(3, counter); 528 } 529 530 @Test 531 public void sceneCanBecomeGestureSource() { 532 final Node n = oneNode(); 533 final MouseEventGenerator gen = new MouseEventGenerator(); 534 535 n.setOnMousePressed(doDetect); 536 n.getScene().setOnDragDetected(event -> { 537 Dragboard db = n.getScene().startDragAndDrop(TransferMode.ANY); 538 ClipboardContent cc = new ClipboardContent(); 539 cc.putString("Hello"); 540 db.setContent(cc); 541 }); 542 n.setOnDragOver(event -> { 543 assertSame(n.getScene(), event.getGestureSource()); 544 counter++; 545 }); 546 547 n.getScene().impl_processMouseEvent( 548 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 549 toolkit.dragTo(52, 52, TransferMode.COPY); 550 551 assertEquals(1, counter); 552 } 553 554 @Test 555 public void sceneCanBecomeGestureTarget() { 556 final Node n = oneNode(); 557 final MouseEventGenerator gen = new MouseEventGenerator(); 558 559 dragSource = n; 560 n.setOnMousePressed(doDetect); 561 n.setOnDragDetected(stringSource(TransferMode.ANY)); 562 n.getScene().setOnDragOver(event -> { 563 event.acceptTransferModes(TransferMode.ANY); 564 if (counter == 0) { 565 assertNull(event.getGestureTarget()); 566 } else { 567 assertSame(n.getScene(), event.getGestureTarget()); 568 } 569 counter++; 570 }); 571 n.setOnDragDropped(event -> { 572 assertSame(n.getScene(), event.getGestureTarget()); 573 counter++; 574 }); 575 576 n.getScene().impl_processMouseEvent( 577 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 578 toolkit.dragTo(51, 51, TransferMode.COPY); 579 toolkit.dragTo(52, 52, TransferMode.COPY); 580 toolkit.drop(52, 52, TransferMode.COPY); 581 582 assertEquals(3, counter); 583 } 584 585 /************************************************************************/ 586 /* TRANSFER MODES */ 587 /************************************************************************/ 588 589 @Test 590 public void defaultTransferModeShouldBeUsedIfSupported() { 591 final Node n = oneNode(); 592 final MouseEventGenerator gen = new MouseEventGenerator(); 593 594 dragSource = n; 595 n.setOnMousePressed(doDetect); 596 n.setOnDragDetected(stringSource(TransferMode.ANY)); 597 n.setOnDragOver(acceptAny); 598 599 /* start drag */ 600 n.getScene().impl_processMouseEvent( 601 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 602 603 /* drag */ 604 assertSame(TransferMode.LINK, toolkit.dragTo(52, 52, TransferMode.LINK)); 605 } 606 607 @Test 608 public void defaultTransferModeShouldNotBeUsedIfNotSupported() { 609 final Node n = oneNode(); 610 final MouseEventGenerator gen = new MouseEventGenerator(); 611 612 dragSource = n; 613 n.setOnMousePressed(doDetect); 614 n.setOnDragDetected(stringSource(TransferMode.COPY)); 615 n.setOnDragOver(acceptAny); 616 617 /* start drag */ 618 n.getScene().impl_processMouseEvent( 619 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 620 621 /* drag */ 622 assertSame(TransferMode.COPY, toolkit.dragTo(52, 52, TransferMode.LINK)); 623 } 624 625 @Test 626 public void mostCommonTransferModeShouldBeChosen() { 627 final Node n = oneNode(); 628 final MouseEventGenerator gen = new MouseEventGenerator(); 629 630 dragSource = n; 631 n.setOnMousePressed(doDetect); 632 n.setOnDragDetected(stringSource(TransferMode.COPY_OR_MOVE)); 633 n.setOnDragOver(acceptAny); 634 635 /* start drag */ 636 n.getScene().impl_processMouseEvent( 637 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 638 639 /* drag */ 640 assertSame(TransferMode.MOVE, toolkit.dragTo(52, 52, TransferMode.LINK)); 641 } 642 643 @Test 644 public void transferModeAcceptanceShouldBeOverridable_restriction() { 645 final Node n = oneNode(); 646 final MouseEventGenerator gen = new MouseEventGenerator(); 647 648 dragSource = n; 649 n.setOnMousePressed(doDetect); 650 n.setOnDragDetected(stringSource(TransferMode.COPY_OR_MOVE)); 651 n.setOnDragOver(acceptAny); 652 n.getParent().setOnDragOver(acceptCopy); 653 654 /* start drag */ 655 n.getScene().impl_processMouseEvent( 656 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 657 658 /* drag */ 659 assertSame(TransferMode.COPY, toolkit.dragTo(52, 52, TransferMode.MOVE)); 660 } 661 662 @Test 663 public void transferModeAcceptanceShouldBeOverridable_loosening() { 664 final Node n = oneNode(); 665 final MouseEventGenerator gen = new MouseEventGenerator(); 666 667 dragSource = n; 668 n.setOnMousePressed(doDetect); 669 n.setOnDragDetected(stringSource(TransferMode.COPY_OR_MOVE)); 670 n.setOnDragOver(acceptCopy); 671 n.getParent().setOnDragOver(acceptAny); 672 673 /* start drag */ 674 n.getScene().impl_processMouseEvent( 675 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 676 677 /* drag */ 678 assertSame(TransferMode.MOVE, toolkit.dragTo(52, 52, TransferMode.MOVE)); 679 } 680 681 @Test 682 public void noTransferShouldHappenWhenUnsupportedModeIsAccepted() { 683 final Node n = oneNode(); 684 final MouseEventGenerator gen = new MouseEventGenerator(); 685 686 dragSource = n; 687 n.setOnMousePressed(doDetect); 688 n.setOnDragDetected(stringSource(TransferMode.LINK)); 689 n.setOnDragOver(acceptCopyOrMove); 690 691 /* start drag */ 692 n.getScene().impl_processMouseEvent( 693 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 694 695 /* drag */ 696 assertNull(toolkit.dragTo(52, 52, TransferMode.MOVE)); 697 } 698 699 @Test 700 public void noTransferShouldHappenWhenNotAccepted() { 701 final Node n = oneNode(); 702 final MouseEventGenerator gen = new MouseEventGenerator(); 703 704 dragSource = n; 705 n.setOnMousePressed(doDetect); 706 n.setOnDragDetected(stringSource(TransferMode.ANY)); 707 708 /* start drag */ 709 n.getScene().impl_processMouseEvent( 710 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 711 712 /* drag */ 713 assertNull(toolkit.dragTo(52, 52, TransferMode.MOVE)); 714 } 715 716 @Test 717 public void dropShouldGetAcceptedTransferMode() { 718 final Node n = oneNode(); 719 final MouseEventGenerator gen = new MouseEventGenerator(); 720 721 dragSource = n; 722 n.setOnMousePressed(doDetect); 723 n.setOnDragDetected(stringSource(TransferMode.ANY)); 724 n.setOnDragOver(acceptCopy); 725 n.setOnDragDropped(event -> { 726 counter++; 727 assertSame(TransferMode.COPY, event.getTransferMode()); 728 assertSame(TransferMode.COPY, event.getAcceptedTransferMode()); 729 }); 730 731 /* start drag */ 732 n.getScene().impl_processMouseEvent( 733 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 734 735 /* drag and drop*/ 736 toolkit.dragTo(52, 52, TransferMode.MOVE); 737 toolkit.drop(52, 52, TransferMode.MOVE); 738 739 assertEquals(1, counter); 740 } 741 742 @Test 743 public void shouldBePossibleToAcceptInDrop() { 744 final Node n = oneNode(); 745 final MouseEventGenerator gen = new MouseEventGenerator(); 746 747 dragSource = n; 748 n.setOnMousePressed(doDetect); 749 n.setOnDragDetected(stringSource(TransferMode.ANY)); 750 n.setOnDragOver(acceptCopy); 751 n.setOnDragDropped(event -> { 752 assertSame(TransferMode.COPY, event.getTransferMode()); 753 assertSame(TransferMode.COPY, event.getAcceptedTransferMode()); 754 event.acceptTransferModes(TransferMode.MOVE); 755 event.setDropCompleted(true); 756 assertSame(TransferMode.COPY, event.getTransferMode()); 757 assertSame(TransferMode.MOVE, event.getAcceptedTransferMode()); 758 }); 759 760 /* start drag */ 761 n.getScene().impl_processMouseEvent( 762 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 763 764 /* drag and drop*/ 765 toolkit.dragTo(52, 52, TransferMode.MOVE); 766 assertEquals(TransferMode.MOVE, toolkit.drop(52, 52, TransferMode.LINK)); 767 } 768 769 @Test 770 public void acceptingNonSupportedTransferModeInDropShouldThrowException() { 771 final Node n = oneNode(); 772 final MouseEventGenerator gen = new MouseEventGenerator(); 773 774 dragSource = n; 775 n.setOnMousePressed(doDetect); 776 n.setOnDragDetected(stringSource(TransferMode.COPY_OR_MOVE)); 777 n.setOnDragOver(acceptCopy); 778 n.setOnDragDropped(event -> { 779 try { 780 event.acceptTransferModes(TransferMode.LINK); 781 fail("Exception was not thrown"); 782 } catch (IllegalStateException e) { 783 /* expceted */ 784 counter++; 785 } 786 }); 787 788 /* start drag */ 789 n.getScene().impl_processMouseEvent( 790 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 791 792 /* drag and drop*/ 793 toolkit.dragTo(52, 52, TransferMode.MOVE); 794 toolkit.drop(52, 52, TransferMode.LINK); 795 796 assertEquals(1, counter); 797 } 798 799 @Test 800 public void modifyingStaticArraysShouldNotInfluenceResult() { 801 TransferMode.ANY[0] = TransferMode.LINK; 802 TransferMode.ANY[1] = TransferMode.LINK; 803 TransferMode.ANY[2] = TransferMode.LINK; 804 805 TransferMode.COPY_OR_MOVE[0] = TransferMode.LINK; 806 TransferMode.COPY_OR_MOVE[1] = TransferMode.LINK; 807 808 final Node n = oneNode(); 809 final MouseEventGenerator gen = new MouseEventGenerator(); 810 811 dragSource = n; 812 n.setOnMousePressed(doDetect); 813 n.setOnDragDetected(stringSource(TransferMode.ANY)); 814 n.setOnDragOver(acceptCopyOrMove); 815 n.setOnDragDropped(event -> { 816 event.acceptTransferModes(TransferMode.ANY); 817 event.setDropCompleted(true); 818 }); 819 820 /* start drag */ 821 n.getScene().impl_processMouseEvent( 822 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 823 824 /* drag and drop*/ 825 assertSame(TransferMode.COPY, toolkit.dragTo(52, 52, TransferMode.COPY)); 826 assertSame(TransferMode.COPY, toolkit.drop(52, 52, TransferMode.COPY)); 827 828 TransferMode.ANY[0] = TransferMode.COPY; 829 TransferMode.ANY[1] = TransferMode.MOVE; 830 TransferMode.ANY[2] = TransferMode.LINK; 831 832 TransferMode.COPY_OR_MOVE[0] = TransferMode.COPY; 833 TransferMode.COPY_OR_MOVE[1] = TransferMode.MOVE; 834 } 835 836 /************************************************************************/ 837 /* GESTURE FINISH */ 838 /************************************************************************/ 839 840 @Test 841 public void dropShouldBeAcceptedByCompletion() { 842 final Node n = oneNode(); 843 final MouseEventGenerator gen = new MouseEventGenerator(); 844 845 dragSource = n; 846 n.setOnMousePressed(doDetect); 847 n.setOnDragDetected(stringSource(TransferMode.ANY)); 848 n.setOnDragOver(acceptCopy); 849 n.setOnDragDropped(event -> { 850 event.setDropCompleted(true); 851 }); 852 853 /* start drag */ 854 n.getScene().impl_processMouseEvent( 855 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 856 857 /* drag and drop*/ 858 toolkit.dragTo(52, 52, TransferMode.MOVE); 859 assertSame(TransferMode.COPY, toolkit.drop(52, 52, TransferMode.MOVE)); 860 } 861 862 @Test 863 public void dropShouldNotBeAcceptedWithUnsuccessfulCompletion() { 864 final Node n = oneNode(); 865 final MouseEventGenerator gen = new MouseEventGenerator(); 866 867 dragSource = n; 868 n.setOnMousePressed(doDetect); 869 n.setOnDragDetected(stringSource(TransferMode.ANY)); 870 n.setOnDragOver(acceptCopy); 871 n.setOnDragDropped(event -> { 872 event.setDropCompleted(false); 873 }); 874 875 /* start drag */ 876 n.getScene().impl_processMouseEvent( 877 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 878 879 /* drag and drop*/ 880 toolkit.dragTo(52, 52, TransferMode.MOVE); 881 assertNull(toolkit.drop(52, 52, TransferMode.MOVE)); 882 } 883 884 @Test 885 public void dropShouldNotBeAcceptedWithoutCompletion() { 886 final Node n = oneNode(); 887 final MouseEventGenerator gen = new MouseEventGenerator(); 888 889 dragSource = n; 890 n.setOnMousePressed(doDetect); 891 n.setOnDragDetected(stringSource(TransferMode.ANY)); 892 n.setOnDragOver(acceptCopy); 893 894 /* start drag */ 895 n.getScene().impl_processMouseEvent( 896 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 897 898 /* drag and drop*/ 899 toolkit.dragTo(52, 52, TransferMode.MOVE); 900 assertNull(toolkit.drop(52, 52, TransferMode.MOVE)); 901 } 902 903 @Test 904 public void dropCompletionShouldBeOverridable() { 905 final Node n = oneNode(); 906 final MouseEventGenerator gen = new MouseEventGenerator(); 907 908 dragSource = n; 909 n.setOnMousePressed(doDetect); 910 n.setOnDragDetected(stringSource(TransferMode.ANY)); 911 n.setOnDragOver(acceptCopyOrMove); 912 n.setOnDragDropped(event -> { 913 event.setDropCompleted(false); 914 }); 915 n.getParent().setOnDragDropped(event -> { 916 event.setDropCompleted(true); 917 }); 918 919 /* start drag */ 920 n.getScene().impl_processMouseEvent( 921 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 922 923 /* drag and drop*/ 924 toolkit.dragTo(52, 52, TransferMode.MOVE); 925 assertSame(TransferMode.MOVE, toolkit.drop(52, 52, TransferMode.MOVE)); 926 } 927 928 @Test 929 public void dropDoneShouldBeSentToGestureSource() { 930 final Node[] ns = twoNodes(); 931 Node src = ns[0]; 932 Node trgt = ns[1]; 933 934 final MouseEventGenerator gen = new MouseEventGenerator(); 935 936 dragSource = src; 937 src.setOnMousePressed(doDetect); 938 src.setOnDragDetected(stringSource(TransferMode.ANY)); 939 trgt.setOnDragOver(acceptCopyOrMove); 940 trgt.setOnDragDropped(event -> { 941 event.setDropCompleted(true); 942 }); 943 src.getParent().setOnDragDone(event -> { 944 Assert.assertEquals(TransferMode.MOVE, event.getTransferMode()); 945 Assert.assertEquals(TransferMode.MOVE, event.getAcceptedTransferMode()); 946 counter++; 947 }); 948 949 /* start drag */ 950 src.getScene().impl_processMouseEvent( 951 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 952 953 /* drag and drop*/ 954 toolkit.dragTo(52, 52, TransferMode.MOVE); 955 toolkit.dragTo(252, 52, TransferMode.MOVE); 956 toolkit.drop(252, 52, TransferMode.COPY); 957 toolkit.done(TransferMode.MOVE); 958 assertEquals(counter, 1); 959 } 960 961 /************************************************************************/ 962 /* ENTERED/EXITED */ 963 /************************************************************************/ 964 965 @Test 966 public void dragSourceShouldGetEnteredImmediately() { 967 final Node n = oneNode(); 968 final MouseEventGenerator gen = new MouseEventGenerator(); 969 970 dragSource = n; 971 n.setOnMousePressed(doDetect); 972 n.setOnDragDetected(stringSource(TransferMode.ANY)); 973 n.setOnDragOver(acceptAny); 974 n.setOnDragEntered(event -> { 975 counter++; 976 }); 977 978 /* start drag */ 979 n.getScene().impl_processMouseEvent( 980 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 981 assertEquals(0, counter); 982 983 /* drag */ 984 toolkit.dragTo(52, 52, TransferMode.MOVE); 985 assertEquals(1, counter); 986 } 987 988 @Test 989 public void dragSourcesParentShouldGetEnteredImmediately() { 990 final Node n = oneNode(); 991 final MouseEventGenerator gen = new MouseEventGenerator(); 992 993 dragSource = n; 994 n.setOnMousePressed(doDetect); 995 n.setOnDragDetected(stringSource(TransferMode.ANY)); 996 n.setOnDragOver(acceptAny); 997 n.getParent().setOnDragEntered(event -> { 998 counter++; 999 }); 1000 1001 /* start drag */ 1002 n.getScene().impl_processMouseEvent( 1003 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1004 assertEquals(0, counter); 1005 1006 /* drag */ 1007 toolkit.dragTo(52, 52, TransferMode.MOVE); 1008 assertEquals(1, counter); 1009 } 1010 1011 @Test 1012 public void dragSourcesSubScenesParentShouldGetEnteredImmediately() { 1013 final Node[] ns = oneNodeInSubScene(); 1014 final Node n = ns[0]; 1015 final Node subScene = ns[1]; 1016 1017 dragSource = n; 1018 n.setOnMousePressed(doDetect); 1019 n.setOnDragDetected(stringSource(TransferMode.ANY)); 1020 n.setOnDragOver(acceptAny); 1021 subScene.setOnDragEntered(event -> { 1022 counter++; 1023 }); 1024 subScene.getParent().setOnDragEntered(event -> { 1025 counter++; 1026 }); 1027 1028 /* start drag */ 1029 n.getScene().impl_processMouseEvent( 1030 MouseEventGenerator.generateMouseEvent( 1031 MouseEvent.MOUSE_PRESSED, 50, 50)); 1032 assertEquals(0, counter); 1033 1034 /* drag */ 1035 toolkit.dragTo(52, 52, TransferMode.MOVE); 1036 assertEquals(2, counter); 1037 } 1038 1039 @Test 1040 public void dragSourcesParentShouldGetEnteredTargetTwice() { 1041 final Node n = oneNode(); 1042 final MouseEventGenerator gen = new MouseEventGenerator(); 1043 1044 dragSource = n; 1045 n.setOnMousePressed(doDetect); 1046 n.setOnDragDetected(stringSource(TransferMode.ANY)); 1047 n.setOnDragOver(acceptAny); 1048 n.getParent().addEventHandler(DragEvent.DRAG_ENTERED_TARGET, 1049 event -> { 1050 counter++; 1051 } 1052 ); 1053 1054 /* start drag */ 1055 n.getScene().impl_processMouseEvent( 1056 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1057 assertEquals(0, counter); 1058 1059 /* drag */ 1060 toolkit.dragTo(52, 52, TransferMode.MOVE); 1061 assertEquals(2, counter); 1062 } 1063 1064 @Test 1065 public void dragSourceShouldGetExitedWhenLeft() { 1066 final Node n = oneNode(); 1067 final MouseEventGenerator gen = new MouseEventGenerator(); 1068 1069 dragSource = n; 1070 n.setOnMousePressed(doDetect); 1071 n.setOnDragDetected(stringSource(TransferMode.ANY)); 1072 n.setOnDragOver(acceptAny); 1073 n.setOnDragExited(event -> { 1074 counter++; 1075 }); 1076 1077 /* start drag */ 1078 n.getScene().impl_processMouseEvent( 1079 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1080 assertEquals(0, counter); 1081 1082 /* drag */ 1083 toolkit.dragTo(52, 52, TransferMode.MOVE); 1084 assertEquals(0, counter); 1085 1086 toolkit.dragTo(150, 52, TransferMode.MOVE); 1087 assertEquals(1, counter); 1088 } 1089 1090 @Test 1091 public void dragSourcesSubScenesParentShouldGetExitedWhenLeft() { 1092 final Node[] ns = oneNodeInSubScene(); 1093 final Node n = ns[0]; 1094 final Node subScene = ns[1]; 1095 1096 dragSource = n; 1097 n.setOnMousePressed(doDetect); 1098 n.setOnDragDetected(stringSource(TransferMode.ANY)); 1099 n.setOnDragOver(acceptAny); 1100 subScene.setOnDragExited(event -> { 1101 counter++; 1102 }); 1103 subScene.getParent().setOnDragExited(event -> { 1104 counter++; 1105 }); 1106 1107 /* start drag */ 1108 n.getScene().impl_processMouseEvent( 1109 MouseEventGenerator.generateMouseEvent( 1110 MouseEvent.MOUSE_PRESSED, 50, 50)); 1111 assertEquals(0, counter); 1112 1113 /* drag */ 1114 toolkit.dragTo(52, 52, TransferMode.MOVE); 1115 assertEquals(0, counter); 1116 1117 toolkit.dragTo(250, 52, TransferMode.MOVE); 1118 assertEquals(2, counter); 1119 } 1120 1121 @Test 1122 public void dragSourceShouldGetEnteredWhenReturned() { 1123 final Node n = oneNode(); 1124 final MouseEventGenerator gen = new MouseEventGenerator(); 1125 1126 dragSource = n; 1127 n.setOnMousePressed(doDetect); 1128 n.setOnDragDetected(stringSource(TransferMode.ANY)); 1129 n.setOnDragOver(acceptAny); 1130 n.setOnDragEntered(event -> { 1131 counter++; 1132 }); 1133 1134 /* start drag */ 1135 n.getScene().impl_processMouseEvent( 1136 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1137 assertEquals(0, counter); 1138 1139 /* drag */ 1140 toolkit.dragTo(52, 52, TransferMode.MOVE); 1141 assertEquals(1, counter); 1142 1143 toolkit.dragTo(150, 52, TransferMode.MOVE); 1144 assertEquals(1, counter); 1145 1146 toolkit.dragTo(60, 52, TransferMode.MOVE); 1147 assertEquals(2, counter); 1148 } 1149 1150 @Test 1151 public void anotherNodeShouldGetEntered() { 1152 final Node[] ns = twoNodes(); 1153 Node src = ns[0]; 1154 Node trgt = ns[1]; 1155 final MouseEventGenerator gen = new MouseEventGenerator(); 1156 1157 dragSource = src; 1158 src.setOnMousePressed(doDetect); 1159 src.setOnDragDetected(stringSource(TransferMode.ANY)); 1160 src.setOnDragOver(acceptAny); 1161 trgt.setOnDragEntered(event -> { 1162 counter++; 1163 }); 1164 1165 /* start drag */ 1166 src.getScene().impl_processMouseEvent( 1167 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1168 assertEquals(0, counter); 1169 1170 /* drag */ 1171 toolkit.dragTo(52, 52, TransferMode.MOVE); 1172 assertEquals(0, counter); 1173 1174 toolkit.dragTo(250, 52, TransferMode.MOVE); 1175 assertEquals(1, counter); 1176 } 1177 1178 @Test 1179 public void anotherNodeShouldGetExited() { 1180 final Node[] ns = twoNodes(); 1181 Node src = ns[0]; 1182 Node trgt = ns[1]; 1183 final MouseEventGenerator gen = new MouseEventGenerator(); 1184 1185 dragSource = src; 1186 src.setOnMousePressed(doDetect); 1187 src.setOnDragDetected(stringSource(TransferMode.ANY)); 1188 src.setOnDragOver(acceptAny); 1189 trgt.setOnDragExited(event -> { 1190 counter++; 1191 }); 1192 1193 /* start drag */ 1194 src.getScene().impl_processMouseEvent( 1195 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1196 assertEquals(0, counter); 1197 1198 /* drag */ 1199 toolkit.dragTo(52, 52, TransferMode.MOVE); 1200 assertEquals(0, counter); 1201 1202 toolkit.dragTo(250, 52, TransferMode.MOVE); 1203 assertEquals(0, counter); 1204 1205 toolkit.dragTo(150, 52, TransferMode.MOVE); 1206 assertEquals(1, counter); 1207 } 1208 1209 @Test 1210 public void parentShouldNotGetExitedWhenDraggingOverChildren() { 1211 final Node[] ns = twoNodes(); 1212 Node src = ns[0]; 1213 Node trgt = ns[1]; 1214 final MouseEventGenerator gen = new MouseEventGenerator(); 1215 1216 dragSource = src; 1217 src.setOnMousePressed(doDetect); 1218 src.setOnDragDetected(stringSource(TransferMode.ANY)); 1219 src.setOnDragOver(acceptAny); 1220 trgt.getParent().setOnDragExited(event -> { 1221 counter++; 1222 }); 1223 1224 /* start drag */ 1225 src.getScene().impl_processMouseEvent( 1226 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1227 assertEquals(0, counter); 1228 1229 /* drag */ 1230 toolkit.dragTo(52, 52, TransferMode.MOVE); 1231 assertEquals(0, counter); 1232 1233 toolkit.dragTo(250, 52, TransferMode.MOVE); 1234 assertEquals(0, counter); 1235 1236 toolkit.dragTo(50, 52, TransferMode.MOVE); 1237 assertEquals(0, counter); 1238 } 1239 1240 @Test 1241 public void parentShouldGetExitedTargetWhenDraggingOverChildren() { 1242 final Node[] ns = twoNodes(); 1243 Node src = ns[0]; 1244 Node trgt = ns[1]; 1245 final MouseEventGenerator gen = new MouseEventGenerator(); 1246 1247 dragSource = src; 1248 src.setOnMousePressed(doDetect); 1249 src.setOnDragDetected(stringSource(TransferMode.ANY)); 1250 src.setOnDragOver(acceptAny); 1251 trgt.getParent().addEventHandler(DragEvent.DRAG_EXITED_TARGET, 1252 event -> { 1253 counter++; 1254 } 1255 ); 1256 1257 /* start drag */ 1258 src.getScene().impl_processMouseEvent( 1259 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1260 assertEquals(0, counter); 1261 1262 /* drag */ 1263 toolkit.dragTo(52, 52, TransferMode.MOVE); 1264 assertEquals(0, counter); 1265 1266 toolkit.dragTo(250, 52, TransferMode.MOVE); 1267 assertEquals(1, counter); 1268 1269 toolkit.dragTo(50, 52, TransferMode.MOVE); 1270 assertEquals(2, counter); 1271 } 1272 1273 /************************************************************************/ 1274 /* DRAGVIEW */ 1275 /************************************************************************/ 1276 @Test 1277 public void startDragShouldNotBeCalledIfNothingPutOnDragboardWithDragView() { 1278 final Node n = oneNode(); 1279 final MouseEventGenerator gen = new MouseEventGenerator(); 1280 final Image img = new Image("file:testImg_" + 100 + "x" + 100 + ".png"); 1281 1282 n.setOnMousePressed(doDetect); 1283 n.setOnDragDetected(event -> { 1284 Dragboard db = n.startDragAndDrop(TransferMode.COPY); 1285 db.setDragView(img); 1286 db.setDragViewOffsetX(20); 1287 db.setDragViewOffsetX(15); 1288 }); 1289 1290 n.getScene().impl_processMouseEvent( 1291 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1292 n.getScene().impl_processMouseEvent( 1293 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 50, 50)); 1294 n.getScene().impl_processMouseEvent( 1295 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 50, 50)); 1296 1297 assertFalse(toolkit.dragging); 1298 } 1299 1300 @Test 1301 public void startDragShouldBeCalledIfStringPutOnDragboardsWithDragView() { 1302 final Node n = oneNode(); 1303 final MouseEventGenerator gen = new MouseEventGenerator(); 1304 final Image img = new Image("file:testImg_" + 100 + "x" + 100 + ".png"); 1305 1306 dragSource = n; 1307 n.setOnMousePressed(doDetect); 1308 n.setOnDragDetected(event -> { 1309 Dragboard db = dragSource.startDragAndDrop(TransferMode.ANY); 1310 ClipboardContent cc = new ClipboardContent(); 1311 cc.putString("Hello"); 1312 db.setContent(cc); 1313 db.setDragView(img); 1314 db.setDragViewOffsetX(20); 1315 db.setDragViewOffsetX(15); 1316 }); 1317 1318 n.getScene().impl_processMouseEvent( 1319 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1320 1321 assertTrue(toolkit.dragging); 1322 } 1323 1324 @Test 1325 public void changeDragViewInParentHandlerShouldBePossible() { 1326 final Node n = oneNode(); 1327 final Node parent = n.getParent(); 1328 final MouseEventGenerator gen = new MouseEventGenerator(); 1329 final Image img = new Image("file:testImg_" + 100 + "x" + 100 + ".png"); 1330 final Image imgParent = new Image("file:testImg_" + 200 + "x" + 200 + ".png"); 1331 1332 dragSource = n; 1333 n.setOnMousePressed(doDetect); 1334 n.setOnDragDetected(event -> { 1335 Dragboard db = dragSource.startDragAndDrop(TransferMode.ANY); 1336 ClipboardContent cc = new ClipboardContent(); 1337 cc.putString("Hello"); 1338 db.setContent(cc); 1339 db.setDragView(img); 1340 db.setDragViewOffsetX(20); 1341 db.setDragViewOffsetY(15); 1342 }); 1343 1344 parent.setOnDragDetected(event -> { 1345 Dragboard db = dragSource.startDragAndDrop(TransferMode.ANY); 1346 ClipboardContent cc = new ClipboardContent(); 1347 cc.putString("HelloParent"); 1348 db.setContent(cc); 1349 1350 assertEquals(img, db.getDragView()); 1351 assertEquals(20, db.getDragViewOffsetX(), 1e-10); 1352 assertEquals(15, db.getDragViewOffsetY(), 1e-10); 1353 1354 db.setDragView(imgParent); 1355 db.setDragViewOffsetX(40); 1356 db.setDragViewOffsetY(55); 1357 1358 assertEquals(imgParent, db.getDragView()); 1359 assertEquals(40, db.getDragViewOffsetX(), 1e-10); 1360 assertEquals(55, db.getDragViewOffsetY(), 1e-10); 1361 }); 1362 1363 n.getScene().impl_processMouseEvent( 1364 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1365 } 1366 1367 @Test 1368 public void settingDragViewAndCursorPositionShouldReturnSameResults() { 1369 final Node n = oneNode(); 1370 final Node parent = n.getParent(); 1371 final MouseEventGenerator gen = new MouseEventGenerator(); 1372 final Image img = new Image("file:testImg_" + 100 + "x" + 100 + ".png"); 1373 final Image imgParent = new Image("file:testImg_" + 200 + "x" + 200 + ".png"); 1374 1375 dragSource = n; 1376 n.setOnMousePressed(doDetect); 1377 n.setOnDragDetected(event -> { 1378 Dragboard db = dragSource.startDragAndDrop(TransferMode.ANY); 1379 ClipboardContent cc = new ClipboardContent(); 1380 cc.putString("Hello"); 1381 db.setContent(cc); 1382 db.setDragView(img, 20, 15); 1383 }); 1384 1385 parent.setOnDragDetected(event -> { 1386 Dragboard db = dragSource.startDragAndDrop(TransferMode.ANY); 1387 ClipboardContent cc = new ClipboardContent(); 1388 cc.putString("HelloParent"); 1389 db.setContent(cc); 1390 1391 assertEquals(img, db.getDragView()); 1392 assertEquals(20, db.getDragViewOffsetX(), 1e-10); 1393 assertEquals(15, db.getDragViewOffsetY(), 1e-10); 1394 1395 db.setDragView(imgParent); 1396 db.setDragViewOffsetX(40); 1397 db.setDragViewOffsetY(55); 1398 1399 assertEquals(imgParent, db.getDragView()); 1400 assertEquals(40, db.getDragViewOffsetX(), 1e-10); 1401 assertEquals(55, db.getDragViewOffsetY(), 1e-10); 1402 }); 1403 1404 n.getScene().impl_processMouseEvent( 1405 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1406 } 1407 1408 @Test 1409 public void dragViewShouldBeClearedInSubsequentDragDetectedCall() { 1410 final Node n = oneNode(); 1411 final MouseEventGenerator gen = new MouseEventGenerator(); 1412 final Image img = new Image("file:testImg_" + 100 + "x" + 100 + ".png"); 1413 1414 dragSource = n; 1415 n.setOnMousePressed(doDetect); 1416 n.setOnDragDetected(event -> { 1417 Dragboard db = dragSource.startDragAndDrop(TransferMode.ANY); 1418 1419 assertNull(db.getDragView()); 1420 assertEquals(0, db.getDragViewOffsetX(), 1e-10); 1421 assertEquals(0, db.getDragViewOffsetY(), 1e-10); 1422 1423 ClipboardContent cc = new ClipboardContent(); 1424 cc.putString("Hello"); 1425 db.setContent(cc); 1426 db.setDragView(img); 1427 db.setDragViewOffsetX(20); 1428 db.setDragViewOffsetX(15); 1429 }); 1430 1431 n.getScene().impl_processMouseEvent( 1432 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1433 n.getScene().impl_processMouseEvent( 1434 gen.generateMouseEvent(MouseEvent.MOUSE_DRAGGED, 40, 40)); 1435 n.getScene().impl_processMouseEvent( 1436 gen.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 55, 55)); 1437 n.getScene().impl_processMouseEvent( 1438 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 81, 81)); 1439 } 1440 1441 /************************************************************************/ 1442 /* PICK RESULT */ 1443 /************************************************************************/ 1444 1445 @Test 1446 public void shouldCompute3dCoordinates() { 1447 Node n = twoNodes()[0]; 1448 n.setTranslateZ(50); 1449 dragSource = n; 1450 1451 MouseEventGenerator gen = new MouseEventGenerator(); 1452 1453 counter = 0; 1454 n.setOnMousePressed(doDetect); 1455 n.setOnDragDetected(stringSource(TransferMode.ANY)); 1456 n.setOnDragOver(event -> { 1457 counter++; 1458 Assert.assertEquals(52, event.getX(), 0.00001); 1459 Assert.assertEquals(52, event.getY(), 0.00001); 1460 Assert.assertEquals(0, event.getZ(), 0.00001); 1461 }); 1462 1463 n.getScene().setOnDragOver(event -> { 1464 counter++; 1465 Assert.assertEquals(52, event.getX(), 0.00001); 1466 Assert.assertEquals(52, event.getY(), 0.00001); 1467 Assert.assertEquals(50, event.getZ(), 0.00001); 1468 }); 1469 1470 n.getScene().impl_processMouseEvent( 1471 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1472 toolkit.dragTo(52, 52, TransferMode.COPY); 1473 toolkit.drop(252, 52, TransferMode.COPY); 1474 toolkit.done(TransferMode.COPY); 1475 1476 assertEquals(2, counter); 1477 } 1478 1479 @Test 1480 public void dragEventsHavePickResult() { 1481 final Node[] nodes = twoNodes(); 1482 final Node n1 = nodes[0]; 1483 final Node n2 = nodes[1]; 1484 final MouseEventGenerator gen = new MouseEventGenerator(); 1485 1486 dragSource = n1; 1487 n1.setOnMousePressed(doDetect); 1488 n1.setOnDragDetected(stringSource(TransferMode.ANY)); 1489 n1.setOnDragOver(event -> { 1490 PickResult pickRes = event.getPickResult(); 1491 assertNotNull(pickRes); 1492 assertSame(n1, pickRes.getIntersectedNode()); 1493 assertEquals(52, pickRes.getIntersectedPoint().getX(), 0.00001); 1494 assertEquals(52, pickRes.getIntersectedPoint().getY(), 0.00001); 1495 assertEquals(0, pickRes.getIntersectedPoint().getZ(), 0.00001); 1496 counter++; 1497 }); 1498 EventHandler<DragEvent> switchNodeHandler = event -> { 1499 PickResult pickRes = event.getPickResult(); 1500 assertNotNull(pickRes); 1501 assertSame(n2, pickRes.getIntersectedNode()); 1502 assertEquals(252, pickRes.getIntersectedPoint().getX(), 0.00001); 1503 assertEquals(52, pickRes.getIntersectedPoint().getY(), 0.00001); 1504 assertEquals(0, pickRes.getIntersectedPoint().getZ(), 0.00001); 1505 event.acceptTransferModes(TransferMode.COPY); 1506 counter++; 1507 }; 1508 n1.setOnDragExited(switchNodeHandler); 1509 n2.setOnDragEntered(switchNodeHandler); 1510 n2.setOnDragOver(switchNodeHandler); 1511 n2.setOnDragDropped(switchNodeHandler); 1512 n1.setOnDragDone(event -> { 1513 PickResult pickRes = event.getPickResult(); 1514 assertNotNull(pickRes); 1515 assertNull(pickRes.getIntersectedNode()); 1516 assertEquals(0, pickRes.getIntersectedPoint().getX(), 0.00001); 1517 assertEquals(0, pickRes.getIntersectedPoint().getY(), 0.00001); 1518 assertEquals(0, pickRes.getIntersectedPoint().getZ(), 0.00001); 1519 counter++; 1520 }); 1521 1522 n1.getScene().impl_processMouseEvent( 1523 gen.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 50, 50)); 1524 toolkit.dragTo(52, 52, TransferMode.COPY); 1525 toolkit.dragTo(252, 52, TransferMode.COPY); 1526 toolkit.drop(252, 52, TransferMode.COPY); 1527 toolkit.done(TransferMode.COPY); 1528 1529 assertEquals(6, counter); 1530 } 1531 1532 1533 /************************************************************************/ 1534 /* HELPER CODE */ 1535 /************************************************************************/ 1536 1537 // Event handlers 1538 1539 private final EventHandler<MouseEvent> dontDetect = 1540 event -> event.setDragDetect(false); 1541 1542 private final EventHandler<MouseEvent> doDetect = 1543 event -> event.setDragDetect(true); 1544 1545 private final EventHandler<MouseEvent> detector = 1546 new EventHandler<MouseEvent>() { 1547 @Override public void handle(MouseEvent event) { 1548 detected = true; 1549 } 1550 }; 1551 1552 private EventHandler<MouseEvent> stringSource(final TransferMode... tms) { 1553 return event -> { 1554 Dragboard db = dragSource.startDragAndDrop(tms); 1555 ClipboardContent cc = new ClipboardContent(); 1556 cc.putString("Hello"); 1557 db.setContent(cc); 1558 }; 1559 } 1560 1561 private final EventHandler<DragEvent> acceptAny = 1562 event -> event.acceptTransferModes(TransferMode.ANY); 1563 1564 private final EventHandler<DragEvent> acceptCopyOrMove = 1565 event -> event.acceptTransferModes(TransferMode.COPY_OR_MOVE); 1566 1567 private final EventHandler<DragEvent> acceptCopy = 1568 event -> event.acceptTransferModes(TransferMode.COPY); 1569 1570 // Scenes 1571 1572 private static Node oneNode() { 1573 Group root = new Group(); 1574 getScene(root); 1575 1576 Rectangle r = new Rectangle(100, 100); 1577 root.getChildren().add(r); 1578 return r; 1579 } 1580 1581 private static Node[] twoNodes() { 1582 Group root = new Group(); 1583 getScene(root); 1584 1585 Rectangle r = new Rectangle(100, 100); 1586 root.getChildren().add(r); 1587 1588 Rectangle r2 = new Rectangle(200, 0, 100, 100); 1589 root.getChildren().add(r2); 1590 return new Node[] { r, r2 }; 1591 } 1592 1593 private static Node[] oneNodeInSubScene() { 1594 Group root = new Group(); 1595 getScene(root); 1596 1597 Rectangle r = new Rectangle(100, 100); 1598 SubScene subScene = new SubScene(new Group(r), 200, 200); 1599 root.getChildren().add(subScene); 1600 1601 return new Node[] { subScene, r }; 1602 } 1603 1604 1605 private static Scene getScene(Group root) { 1606 final Scene scene = new Scene(root, 400, 400); 1607 1608 Stage stage = new Stage(); 1609 stage.setScene(scene); 1610 stage.show(); 1611 1612 return scene; 1613 } 1614 1615 // Mock toolkit 1616 1617 private class ClipboardImpl implements TKClipboard { 1618 1619 private List<Pair<DataFormat, Object>> content; 1620 private Set<TransferMode> transferModes; 1621 private Image image; 1622 private double offsetX; 1623 private double offsetY; 1624 1625 @Override 1626 public void setSecurityContext(AccessControlContext ctx) { 1627 } 1628 1629 @Override 1630 public Object getContent(DataFormat df) { 1631 for (Pair<DataFormat, Object> pair : content) { 1632 if (pair.getKey() == df) { 1633 return pair.getValue(); 1634 } 1635 } 1636 return null; 1637 } 1638 1639 @Override 1640 public Set<DataFormat> getContentTypes() { 1641 Set<DataFormat> types = new HashSet<DataFormat>(); 1642 for (Pair<DataFormat, Object> pair : content) { 1643 types.add(pair.getKey()); 1644 } 1645 return types; 1646 } 1647 1648 @Override 1649 public Set<TransferMode> getTransferModes() { 1650 return transferModes; 1651 } 1652 1653 public void setTransferModes(Set<TransferMode> tms) { 1654 this.transferModes = tms; 1655 } 1656 1657 @Override 1658 public boolean hasContent(DataFormat df) { 1659 return content != null && !content.isEmpty(); 1660 } 1661 1662 @Override 1663 public boolean putContent(Pair<DataFormat, Object>... pairs) { 1664 content = new ArrayList<Pair<DataFormat, Object>>(); 1665 content.addAll(Arrays.asList(pairs)); 1666 return true; 1667 } 1668 1669 @Override 1670 public void setDragView(Image image) { 1671 this.image = image; 1672 } 1673 1674 @Override 1675 public void setDragViewOffsetX(double offsetX) { 1676 this.offsetX = offsetX; 1677 } 1678 1679 @Override 1680 public void setDragViewOffsetY(double offsetY) { 1681 this.offsetY = offsetY; 1682 } 1683 1684 @Override 1685 public Image getDragView() { 1686 return image; 1687 } 1688 1689 @Override 1690 public double getDragViewOffsetX() { 1691 return offsetX; 1692 } 1693 1694 @Override 1695 public double getDragViewOffsetY() { 1696 return offsetY; 1697 } 1698 1699 public void flush() { 1700 image = null; 1701 offsetX = offsetY = 0; 1702 } 1703 } 1704 1705 private class DndToolkit implements StubToolkit.DndDelegate { 1706 1707 boolean dragging = false; 1708 TKDragSourceListener srcListener; 1709 TKDragGestureListener gstrListener; 1710 TKDropTargetListener trgListener; 1711 TKClipboard db; 1712 1713 @Override 1714 public void registerListener(TKDragGestureListener l) { 1715 this.gstrListener = l; 1716 } 1717 1718 @Override 1719 public void enableDrop(TKDropTargetListener l) { 1720 this.trgListener = l; 1721 } 1722 1723 1724 @Override 1725 public TKClipboard createDragboard() { 1726 db = new ClipboardImpl(); 1727 return db; 1728 } 1729 1730 @Override 1731 public void startDrag(TKScene scene, Set<TransferMode> tm, 1732 TKDragSourceListener l, Dragboard dragboard) { 1733 ((ClipboardImpl)db).setTransferModes(tm); 1734 ((ClipboardImpl)db).flush(); 1735 dragging = true; 1736 srcListener = l; 1737 } 1738 1739 @Override 1740 public DragEvent convertDragEventToFx(Object event, Dragboard dragboard) { 1741 DragEvent de = (DragEvent) event; 1742 return new DragEvent(de.getSource(), de.getTarget(), de.getEventType(), 1743 dragboard, de.getSceneX(), de.getSceneY(), 1744 de.getScreenX(), de.getScreenY(), de.getTransferMode(), 1745 de.getGestureSource(), de.getGestureTarget(), de.getPickResult()); 1746 } 1747 1748 public TransferMode dragTo(double x, double y, TransferMode tm) { 1749 return trgListener.dragOver(x, y, x, y, tm); 1750 } 1751 1752 public TransferMode drop(double x, double y, TransferMode tm) { 1753 return trgListener.drop(x, y, x, y, tm); 1754 } 1755 1756 public void done(TransferMode tm) { 1757 srcListener.dragDropEnd(0, 0, 0, 0, tm); 1758 } 1759 1760 public void stopDrag() { 1761 dragging = false; 1762 } 1763 1764 } 1765 }