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