1 /* 2 * Copyright (c) 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 package javafx.draganddrop; 26 27 import java.io.File; 28 import java.io.Serializable; 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.EnumSet; 32 import java.util.HashMap; 33 import java.util.HashSet; 34 import java.util.LinkedList; 35 import java.util.List; 36 import java.util.Map; 37 import java.util.Set; 38 import java.util.concurrent.Callable; 39 import java.util.concurrent.ConcurrentHashMap; 40 import javafx.beans.value.ChangeListener; 41 import javafx.beans.value.ObservableValue; 42 import javafx.event.ActionEvent; 43 import javafx.event.EventHandler; 44 import javafx.factory.ControlsFactory; 45 import javafx.factory.NodeFactory; 46 import javafx.factory.Panes; 47 import javafx.factory.Shapes; 48 import javafx.geometry.Orientation; 49 import javafx.scene.Node; 50 import javafx.scene.Parent; 51 import javafx.scene.Scene; 52 import javafx.scene.control.Button; 53 import javafx.scene.control.CheckBox; 54 import javafx.scene.control.ChoiceBox; 55 import javafx.scene.control.Label; 56 import javafx.scene.control.Separator; 57 import javafx.scene.control.TextField; 58 import javafx.scene.image.Image; 59 import javafx.scene.image.ImageView; 60 import javafx.scene.input.Clipboard; 61 import javafx.scene.input.ClipboardContent; 62 import javafx.scene.input.DataFormat; 63 import javafx.scene.input.DragEvent; 64 import javafx.scene.input.Dragboard; 65 import javafx.scene.input.MouseEvent; 66 import javafx.scene.input.TransferMode; 67 import javafx.scene.layout.HBox; 68 import javafx.scene.layout.Pane; 69 import javafx.scene.layout.StackPane; 70 import javafx.scene.layout.VBox; 71 import javafx.scene.text.Text; 72 import javafx.stage.Stage; 73 import javafx.util.Pair; 74 import static org.junit.Assert.*; 75 import test.javaclient.shared.InteroperabilityApp; 76 import static test.javaclient.shared.TestUtil.isEmbedded; 77 import test.javaclient.shared.Utils; 78 79 public class DragDropWithControls extends InteroperabilityApp { 80 81 final public static String PARAMETER_ONLY_SOURCE_STAGE = "onlySource"; 82 final public static String PARAMETER_ONLY_TARGET_STAGE = "onlyTarget"; 83 final static String TITLE_TARGET_STAGE = "Target"; 84 final static String TITLE_SOURCE_STAGE = "Source"; 85 final static String ID_NODE_CHOOSER = "nodeChooser"; 86 final static String ID_DRAG_SOURCE = "from"; 87 final static String ID_DRAG_TARGET = "to"; 88 final static String ID_TO_CLIPBOARD_BUTTON = "toClipboardButton"; 89 final static String ID_FROM_CLIPBOARD_BUTTON = "fromClipboardButton"; 90 final static String ID_PLAIN_TEXT = "PLAIN_TEXT"; 91 final static String ID_HTML = "HTML"; 92 final static String ID_IMAGE = "IMAGE"; 93 final static String ID_RTF = "RTF"; 94 final static String ID_URL = "URL"; 95 final static String ID_FILES = "Files"; 96 final static String ID_CUSTOM_BYTES = "Custom (bytes)"; 97 final static String ID_CUSTOM_STRING = "Custom (string)"; 98 final static String ID_CUSTOM_CLASS = "Custom (class)"; 99 final static String ID_RECEIVED_IMAGE = "ReceivedImage"; 100 final static String ID_SRC_IMAGE = "SrcImage"; 101 public final static DataFormat DF_CUSTOM_BYTES = new DataFormat("dndwithcontrols.custom.bytes"); 102 public final static DataFormat DF_CUSTOM_STRING = new DataFormat("dndwithcontrols.custom.string"); 103 public final static DataFormat DF_CUSTOM_CLASS = new DataFormat("dndwithcontrols.custom.class"); 104 final static String CONTENT_PLAIN_TEXT = "Hello!!!"; 105 final static String CONTENT_URL = "http://www.oracle.com"; 106 private static Image CONTENT_IMAGE; 107 final static String CONTENT_HTML = 108 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" 109 + "<html xmlns=\"http://www.w3.org/1999/xhtml\">" 110 + "<head></head>" 111 + "<body><i><b>Hello!</b></i></body>" 112 + "</html>"; 113 final static String CONTENT_RTF = "{\\rtf1 This is some {\\b bold} text.\\par}"; 114 final static String CONTENT_CUSTOM_STRING = "Hello Custom String!"; 115 final static List<File> CONTENT_FILES = new LinkedList<File>(); 116 private Scene leftScene; 117 private Scene rightScene; 118 119 static { 120 CONTENT_FILES.add(new File("./content/index.html")); 121 System.setProperty("prism.lcdtext", "false"); 122 } 123 final static byte[] CONTENT_CUSTOM_BYTES = 124 new byte[]{1, 2, 3, 4}; 125 final static SerializableClass CONTENT_CUSTOM_CLASS = new SerializableClass(new SerializableClass(100, 100.9), 10, 10.9); 126 final static Map<DataFormat, Object> receivedContent = new ConcurrentHashMap<DataFormat, Object>(); 127 public final static Map<DataFormat, Pair<String, Object>> dataFormatToCheckBoxID = new HashMap<DataFormat, Pair<String, Object>>(10); 128 129 static { 130 131 dataFormatToCheckBoxID.put(DataFormat.PLAIN_TEXT, new Pair<String, Object>(ID_PLAIN_TEXT, CONTENT_PLAIN_TEXT)); 132 dataFormatToCheckBoxID.put(DataFormat.HTML, new Pair<String, Object>(ID_HTML, CONTENT_HTML)); 133 dataFormatToCheckBoxID.put(DataFormat.RTF, new Pair<String, Object>(ID_RTF, CONTENT_RTF)); 134 dataFormatToCheckBoxID.put(DataFormat.URL, new Pair<String, Object>(ID_URL, CONTENT_URL)); 135 dataFormatToCheckBoxID.put(DataFormat.FILES, new Pair<String, Object>(ID_FILES, CONTENT_FILES)); 136 dataFormatToCheckBoxID.put(DF_CUSTOM_BYTES, new Pair<String, Object>(ID_CUSTOM_BYTES, CONTENT_CUSTOM_BYTES)); 137 dataFormatToCheckBoxID.put(DF_CUSTOM_STRING, new Pair<String, Object>(ID_CUSTOM_STRING, CONTENT_CUSTOM_STRING)); 138 dataFormatToCheckBoxID.put(DF_CUSTOM_CLASS, new Pair<String, Object>(ID_CUSTOM_CLASS, CONTENT_CUSTOM_CLASS)); 139 InteroperabilityApp.isEmbeddedFullScreenMode = false; 140 } 141 142 @Override 143 protected Scene getScene() { 144 if (null == CONTENT_IMAGE) { 145 CONTENT_IMAGE = new Image(DragDropWithControls.class.getResource("JavaFX.png").toExternalForm()); 146 dataFormatToCheckBoxID.put(DataFormat.IMAGE, new Pair<String, Object>(ID_IMAGE, CONTENT_IMAGE)); 147 } 148 149 Parameters params = getParameters(); 150 parameters = params == null ? Collections.<String>emptyList() : params.getRaw(); 151 152 if (parameters.size() > 1 && parameters.get(1).equals(PARAMETER_ONLY_SOURCE_STAGE)) { 153 leftScene = prepareSourceStage(stage); 154 return leftScene; 155 } else if (parameters.size() > 1 && parameters.get(1).equals(PARAMETER_ONLY_TARGET_STAGE)) { 156 rightScene = prepareTargetStage(secondaryStage); 157 return rightScene; 158 } else { 159 leftScene = prepareSourceStage(stage); 160 secondaryStage = new Stage(); 161 rightScene = prepareTargetStage(secondaryStage); 162 return leftScene; 163 } 164 } 165 166 @Override 167 protected String getFirstStageName() { 168 return TITLE_SOURCE_STAGE; 169 } 170 171 @Override 172 protected StageInfo getSecondaryScene() { 173 return new StageInfo(new Callable<Scene>() { 174 public Scene call() throws Exception { 175 return rightScene; 176 } 177 }, isEmbedded() ? 510 : 670 + (Utils.isLinux() ? 70 : 0), 30, TITLE_TARGET_STAGE); 178 } 179 180 @Override 181 protected boolean hasSecondaryScene() { 182 return leftScene != null && rightScene != null; 183 } 184 185 private static class SerializableClass implements Serializable { 186 187 public SerializableClass() { 188 } 189 190 public SerializableClass(SerializableClass clazz, int i, double d) { 191 this(i, d); 192 this.clazz = clazz; 193 } 194 195 public SerializableClass(int i, double d) { 196 this.i = i; 197 this.d = d; 198 } 199 SerializableClass clazz; 200 int i; 201 double d; 202 203 @Override 204 public String toString() { 205 return "Class{" + " clazz=" + clazz + ", i=" + i + ", d=" + d + "}"; 206 } 207 208 @Override 209 public boolean equals(Object obj) { 210 if (obj == null) { 211 return false; 212 } 213 if (getClass() != obj.getClass()) { 214 return false; 215 } 216 final SerializableClass other = (SerializableClass) obj; 217 if (this.clazz != other.clazz && (this.clazz == null || !this.clazz.equals(other.clazz))) { 218 return false; 219 } 220 if (this.i != other.i) { 221 return false; 222 } 223 if (Double.doubleToLongBits(this.d) != Double.doubleToLongBits(other.d)) { 224 return false; 225 } 226 return true; 227 } 228 229 @Override 230 public int hashCode() { 231 int hash = 5; 232 hash = 17 * hash + (this.clazz != null ? this.clazz.hashCode() : 0); 233 hash = 17 * hash + this.i; 234 hash = 17 * hash + (int) (Double.doubleToLongBits(this.d) ^ (Double.doubleToLongBits(this.d) >>> 32)); 235 return hash; 236 } 237 } 238 Pane sourceControlPane = new StackPane() { 239 { 240 setStyle("-fx-border-color:green;-fx-border-width: 2px;"); 241 } 242 }; 243 Pane targetControlPane = new StackPane() { 244 { 245 setStyle("-fx-border-color:red;-fx-border-width: 2px;"); 246 } 247 }; 248 Pane transferedContentPane = new VBox(); 249 public Set<TransferMode> sourceModes = EnumSet.noneOf(TransferMode.class); 250 public Set<TransferMode> targetModes = EnumSet.noneOf(TransferMode.class); 251 Set<DataFormat> sourceFormats = new HashSet<DataFormat>(); 252 Set<DataFormat> targetFormats = new HashSet<DataFormat>(); 253 static List<DragEvents> eventList = new ArrayList<DragEvents>(); 254 Text log = new Text(); 255 CheckBox useCustomViewCB; 256 List<String> messages = new LinkedList<String>(); 257 List<String> parameters; 258 259 private Scene prepareTargetStage(Stage stageTarget) { 260 final Scene localScene = new Scene(createRightPane(), isEmbedded() ? 420 : 630, 700); 261 localScene.getRoot().setId(TITLE_TARGET_STAGE); 262 263 if (stageTarget != null) { 264 stageTarget.setTitle(TITLE_TARGET_STAGE); 265 stageTarget.setScene(localScene); 266 stageTarget.setX(680); 267 stageTarget.setY(30); 268 } 269 return localScene; 270 } 271 272 private Scene prepareSourceStage(final Stage stageSource) { 273 final Scene localScene = new Scene(createLeftPane(), isEmbedded() ? 420 : 580, 700); 274 localScene.getRoot().setId(TITLE_SOURCE_STAGE); 275 276 if (stageSource != null) { 277 stageSource.setTitle(TITLE_SOURCE_STAGE); 278 stageSource.setScene(localScene); 279 stageSource.setX(0); 280 stageSource.setY(30); 281 } 282 283 return localScene; 284 } 285 286 private Parent createLeftPane() { 287 VBox lbox = new VBox(10); 288 lbox.getChildren().addAll(sourceControlPane, new Separator(), 289 new Text("Source control type:"), 290 createControlCombo(sourceControlPane, true), 291 new Text("Source transfer modes:"), 292 createTMSelect(sourceModes)); 293 294 VBox rbox = new VBox(10); 295 Button b = new Button("Put to clipboard"); 296 b.setId(ID_TO_CLIPBOARD_BUTTON); 297 b.setOnAction(new EventHandler<ActionEvent>() { 298 public void handle(ActionEvent t) { 299 Clipboard.getSystemClipboard().setContent(prepareClipboardContent()); 300 } 301 }); 302 rbox.getChildren().addAll(new Text("Data formats:"), 303 createFormatSelect(sourceFormats), 304 b); 305 306 HBox hbox = new HBox(10); 307 hbox.getChildren().addAll(lbox, new Separator(Orientation.VERTICAL), rbox); 308 309 final Text fileHdr = new Text("Files to drag (1):"); 310 final Text fileNames = new Text(); 311 showFileNames(fileNames); 312 final TextField tb = new TextField("Put full path here"); 313 final Button add = new Button("Add"); 314 add.setOnAction(new EventHandler<ActionEvent>() { 315 @Override 316 public void handle(ActionEvent event) { 317 File f = new File(tb.getText()); 318 if (f.exists()) { 319 CONTENT_FILES.add(f); 320 tb.setText(""); 321 fileHdr.setText("Files to drag (" + CONTENT_FILES.size() + ")"); 322 showFileNames(fileNames); 323 log("Added file " + f.getPath()); 324 } else { 325 log("File doesn't exist: " + f.getPath()); 326 } 327 } 328 }); 329 final Button clear = new Button("Clear"); 330 clear.setOnAction(new EventHandler<ActionEvent>() { 331 @Override 332 public void handle(ActionEvent event) { 333 CONTENT_FILES.clear(); 334 fileHdr.setText("Files to drag (0)"); 335 log("File list cleared"); 336 } 337 }); 338 339 HBox btns = new HBox(); 340 btns.getChildren().addAll(add, clear); 341 342 useCustomViewCB = new CheckBox("Use custom drag view."); 343 344 VBox box = new VBox(10); 345 ImageView i = new ImageView(); 346 i.setImage(CONTENT_IMAGE); 347 i.setId(ID_SRC_IMAGE); 348 box.getChildren().addAll(hbox, new Separator(), fileHdr, 349 fileNames, tb, btns, 350 useCustomViewCB, new Text("Image: "), 351 i, 352 log); 353 if (parameters.size() > 0) { 354 box.setStyle("-fx-background-color: " + parameters.get(0) + ";"); 355 } 356 return box; 357 } 358 359 private void showFileNames(Text text) { 360 StringBuilder sb = new StringBuilder(); 361 for (int i = 0; i < CONTENT_FILES.size(); i++) { 362 File file = CONTENT_FILES.get(i); 363 sb.append(i + 1).append(": ").append(file.toURI()).append("\n"); 364 } 365 text.setText(sb.toString()); 366 } 367 368 private Parent createRightPane() { 369 HBox hbox = new HBox(10); 370 371 VBox lbox = new VBox(10); 372 lbox.getChildren().addAll(targetControlPane, new Separator(), new Text("Target control type:"), 373 createControlCombo(targetControlPane, false), new Text("Target transfer modes:"), createTMSelect(targetModes)); 374 375 VBox rbox = new VBox(10); 376 Button b = new Button("paste from clipboard"); 377 b.setId(ID_FROM_CLIPBOARD_BUTTON); 378 b.setOnAction(new EventHandler<ActionEvent>() { 379 public void handle(ActionEvent t) { 380 getDataFromClipboard(Clipboard.getSystemClipboard()); 381 } 382 }); 383 rbox.getChildren().addAll(new Text("Data formats:"), createFormatSelect(targetFormats), b); 384 385 VBox content = new VBox(10); 386 content.getChildren().addAll(new Text("Transfered content:"), transferedContentPane); 387 388 hbox.getChildren().addAll(lbox, new Separator(Orientation.VERTICAL), rbox, 389 new Separator(Orientation.VERTICAL), content); 390 if (parameters.size() > 0) { 391 hbox.setStyle("-fx-background-color: " + parameters.get(0) + ";"); 392 } 393 return hbox; 394 } 395 396 private Node createControlCombo(final Pane sourceControlPane, final boolean source) { 397 ChoiceBox<NodeFactory> cb = new ChoiceBox<NodeFactory>(); 398 cb.setId(ID_NODE_CHOOSER); 399 cb.getItems().addAll(ControlsFactory.filteredValues()); 400 cb.getItems().addAll(Shapes.values()); 401 cb.getItems().addAll(Panes.values()); 402 403 cb.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<NodeFactory>() { 404 @Override 405 public void changed(ObservableValue<? extends NodeFactory> ov, NodeFactory t, NodeFactory t1) { 406 Node ctrl = null; 407 ctrl = t1.createNode(); 408 if (ctrl instanceof ImageView) { 409 ctrl.setPickOnBounds(true); 410 } 411 if (source) { 412 ctrl.setId(ID_DRAG_SOURCE); 413 } else { 414 ctrl.setId(ID_DRAG_TARGET); 415 } 416 eventList.clear(); 417 sourceControlPane.getChildren().clear(); 418 sourceControlPane.getChildren().add(ctrl); 419 420 final Node control = ctrl; 421 422 if (source) { 423 System.out.println("Source control : " + control); 424 control.setOnDragDetected(new EventHandler<MouseEvent>() { 425 @Override 426 public void handle(MouseEvent event) { 427 eventList.add(DragEvents.DRAG_DETECTED); 428 System.out.println("DragDetected"); 429 Dragboard db = control.startDragAndDrop(sourceModes.toArray(new TransferMode[sourceModes.size()])); 430 if (db == null) { 431 log("Cannot start drag and drop."); 432 return; 433 } 434 System.out.println("db " + db); 435 final ClipboardContent prepareClipboardContent = prepareClipboardContent(); 436 System.out.println("prepareClipboardContent " + prepareClipboardContent); 437 db.setContent(prepareClipboardContent); 438 439 if (useCustomViewCB.isSelected()) { 440 final int const1 = 100; 441 final int const2 = 100; 442 db.setDragView(CONTENT_IMAGE, const1, const2); 443 444 //Assertions here normally prevent DnD, and don't crash the app. 445 assertEquals("OffsetX equals", db.getDragViewOffsetX(), const1, 0); 446 assertEquals("OffsetY equals", db.getDragViewOffsetY(), const2, 0); 447 assertEquals("Image correct get", db.getDragView(), CONTENT_IMAGE); 448 } 449 450 event.consume(); 451 } 452 }); 453 454 control.setOnDragDone(new EventHandler<DragEvent>() { 455 @Override 456 public void handle(DragEvent event) { 457 System.out.println("DragDone"); 458 if (event.getTransferMode() == null) { 459 eventList.add(DragEvents.EMPTY_DRAG_DONE); 460 } 461 462 eventList.add(DragEvents.DRAG_DONE); 463 log("Transfer done: " + event.getTransferMode()); 464 log(""); 465 } 466 }); 467 } else { 468 System.out.println("Target Control : " + control); 469 control.setOnDragEntered(new EventHandler<DragEvent>() { 470 public void handle(DragEvent t) { 471 System.out.println("DragEntered"); 472 eventList.add(DragEvents.DRAG_ENTER); 473 } 474 }); 475 control.setOnDragOver(new EventHandler<DragEvent>() { 476 @Override 477 public void handle(DragEvent event) { 478 System.out.println("DragOver"); 479 eventList.add(DragEvents.DRAG_OVER); 480 Dragboard db = event.getDragboard(); 481 for (DataFormat df : targetFormats) { 482 if (db.hasContent(df)) { 483 event.acceptTransferModes( 484 targetModes.toArray(new TransferMode[targetModes.size()])); 485 return; 486 } 487 } 488 } 489 }); 490 491 control.setOnDragDropped(new EventHandler<DragEvent>() { 492 @Override 493 public void handle(DragEvent event) { 494 System.out.println("DragDropped"); 495 eventList.add(DragEvents.DRAG_DROPPED); 496 Dragboard db = event.getDragboard(); 497 boolean gotData = getDataFromClipboard(db); 498 event.setDropCompleted(gotData); 499 } 500 }); 501 } 502 } 503 }); 504 505 cb.getSelectionModel().select(0); 506 return cb; 507 } 508 509 private ClipboardContent prepareClipboardContent() { 510 ClipboardContent content = new ClipboardContent(); 511 if (sourceFormats.contains(DataFormat.PLAIN_TEXT)) { 512 log("Source is putting string on dragboard"); 513 content.putString(CONTENT_PLAIN_TEXT); 514 } 515 if (sourceFormats.contains(DataFormat.URL)) { 516 log("Source is putting URL on dragboard"); 517 content.putUrl(CONTENT_URL); 518 } 519 if (sourceFormats.contains(DataFormat.IMAGE)) { 520 log("Source is putting image on dragboard"); 521 content.putImage(CONTENT_IMAGE); 522 } 523 if (sourceFormats.contains(DataFormat.HTML)) { 524 log("Source is putting HTML on dragboard"); 525 content.putHtml(CONTENT_HTML); 526 } 527 if (sourceFormats.contains(DataFormat.RTF)) { 528 log("Source is putting RTF on dragboard"); 529 content.putRtf(CONTENT_RTF); 530 } 531 if (sourceFormats.contains(DF_CUSTOM_BYTES)) { 532 log("Source is putting custom four bytes on dragboard"); 533 content.put(DF_CUSTOM_BYTES, CONTENT_CUSTOM_BYTES); 534 } 535 if (sourceFormats.contains(DF_CUSTOM_STRING)) { 536 log("Source is putting custom four bytes on dragboard"); 537 content.put(DF_CUSTOM_STRING, CONTENT_CUSTOM_STRING); 538 } 539 if (sourceFormats.contains(DF_CUSTOM_CLASS)) { 540 log("Source is putting custom class on dragboard"); 541 content.put(DF_CUSTOM_CLASS, CONTENT_CUSTOM_CLASS); 542 } 543 if (sourceFormats.contains(DataFormat.FILES)) { 544 log("Source is putting two files on dragboard"); 545 content.putFiles(CONTENT_FILES); 546 } 547 return content; 548 } 549 550 private boolean getDataFromClipboard(Clipboard cb) { 551 boolean gotData = false; 552 receivedContent.clear(); 553 transferedContentPane.getChildren().clear(); 554 if (targetFormats.contains(DataFormat.PLAIN_TEXT) && cb.hasString()) { 555 receivedContent.put(DataFormat.PLAIN_TEXT, cb.getString()); 556 transferedContentPane.getChildren().addAll(new WrappedLabel("String: " + cb.getString())); 557 log("Dropped string: " + cb.getString()); 558 gotData = true; 559 } 560 if (targetFormats.contains(DataFormat.HTML) && cb.hasHtml()) { 561 receivedContent.put(DataFormat.HTML, cb.getHtml()); 562 transferedContentPane.getChildren().addAll(new WrappedLabel("Html: " + cb.getHtml())); 563 log("Dropped HTML: " + cb.getHtml()); 564 gotData = true; 565 } 566 if (targetFormats.contains(DataFormat.RTF) && cb.hasRtf()) { 567 receivedContent.put(DataFormat.RTF, cb.getRtf()); 568 transferedContentPane.getChildren().addAll(new WrappedLabel("Rtf: " + cb.getRtf())); 569 log("Dropped RTF: " + cb.getRtf()); 570 gotData = true; 571 } 572 if (targetFormats.contains(DataFormat.URL) && cb.hasUrl()) { 573 receivedContent.put(DataFormat.URL, cb.getUrl()); 574 transferedContentPane.getChildren().addAll(new WrappedLabel("Url: " + cb.getUrl())); 575 log("Dropped URL: " + cb.getUrl()); 576 gotData = true; 577 } 578 if (targetFormats.contains(DataFormat.IMAGE) && cb.hasImage()) { 579 receivedContent.put(DataFormat.IMAGE, cb.getImage()); 580 ImageView i = new ImageView(cb.getImage()); 581 i.setId(ID_RECEIVED_IMAGE); 582 transferedContentPane.getChildren().addAll(new Text("Image: "), i); 583 log("Dropped image: " + cb.getImage()); 584 gotData = true; 585 } 586 if (targetFormats.contains(DataFormat.FILES) && cb.hasFiles()) { 587 log("Dropped files:"); 588 receivedContent.put(DataFormat.FILES, cb.getFiles()); 589 transferedContentPane.getChildren().addAll(new WrappedLabel("Files: ")); 590 for (File f : cb.getFiles()) { 591 transferedContentPane.getChildren().addAll(new Label("File: " + f) { 592 { 593 setWrapText(true); 594 } 595 }); 596 log(" " + f.getPath()); 597 } 598 transferedContentPane.getChildren().addAll(new Separator()); 599 gotData = true; 600 } 601 if (targetFormats.contains(DF_CUSTOM_BYTES) && cb.hasContent(DF_CUSTOM_BYTES)) { 602 byte[] b = (byte[]) cb.getContent(DF_CUSTOM_BYTES); 603 receivedContent.put(DF_CUSTOM_BYTES, b); 604 transferedContentPane.getChildren().addAll(new WrappedLabel("bytes: " + b[0] + ", " + b[1] + ", " + b[2] + ", " + b[3])); 605 log("Dropped custom bytes: " + b[0] + ", " + b[1] + ", " + b[2] + ", " + b[3]); 606 gotData = true; 607 } 608 if (targetFormats.contains(DF_CUSTOM_STRING) && cb.hasContent(DF_CUSTOM_STRING)) { 609 receivedContent.put(DF_CUSTOM_STRING, cb.getContent(DF_CUSTOM_STRING)); 610 String s = (String) cb.getContent(DF_CUSTOM_STRING); 611 transferedContentPane.getChildren().addAll(new WrappedLabel("customString: " + s)); 612 log("Dropped custom string: " + s); 613 gotData = true; 614 } 615 if (targetFormats.contains(DF_CUSTOM_CLASS) && cb.hasContent(DF_CUSTOM_CLASS)) { 616 receivedContent.put(DF_CUSTOM_CLASS, cb.getContent(DF_CUSTOM_CLASS)); 617 String s = cb.getContent(DF_CUSTOM_CLASS).toString(); 618 transferedContentPane.getChildren().addAll(new WrappedLabel("customClass: " + s)); 619 log("Dropped custom class: " + s); 620 gotData = true; 621 } 622 623 return gotData; 624 } 625 626 private Node createTMSelect(final Set<TransferMode> tms) { 627 VBox box = new VBox(); 628 629 for (final TransferMode tm : TransferMode.values()) { 630 CheckBox cb = new CheckBox(tm.toString()); 631 cb.selectedProperty().addListener(new ChangeListener<Boolean>() { 632 @Override 633 public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { 634 if (t1) { 635 tms.add(tm); 636 } else { 637 tms.remove(tm); 638 } 639 } 640 }); 641 if (tm == TransferMode.COPY) { 642 cb.selectedProperty().set(true); 643 } 644 box.getChildren().add(cb); 645 } 646 647 return box; 648 } 649 650 private Node createFormatSelect(final Set<DataFormat> dataFormats) { 651 VBox box = new VBox(); 652 653 654 655 for (final Map.Entry<DataFormat, Pair<String, Object>> df : dataFormatToCheckBoxID.entrySet()) { 656 CheckBox cb = new CheckBox(df.getValue().getKey()); 657 cb.selectedProperty().addListener(new ChangeListener<Boolean>() { 658 @Override 659 public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { 660 if (t1) { 661 dataFormats.add(df.getKey()); 662 } else { 663 dataFormats.remove(df.getKey()); 664 } 665 } 666 }); 667 box.getChildren().add(cb); 668 } 669 670 ((CheckBox) box.getChildren().get(0)).selectedProperty().set(true); 671 672 return box; 673 } 674 675 private void log(String text) { 676 System.out.println(text); 677 678 messages.add(text); 679 if (messages.size() > 15) { 680 messages.remove(0); 681 } 682 683 StringBuilder sb = new StringBuilder(); 684 for (String msg : messages) { 685 sb.append(msg).append("\n"); 686 } 687 log.setText(sb.toString()); 688 } 689 690 public static void main(String[] args) { 691 Utils.launch(DragDropWithControls.class, args); 692 } 693 694 private static class WrappedLabel extends VBox { 695 696 public WrappedLabel(String string) { 697 getChildren().add(new Label(string) { 698 { 699 setWrapText(true); 700 } 701 }); 702 getChildren().add(new Separator()); 703 } 704 } 705 }