Sergey has posted 7 posts at DZone. You can read more from them at their website. View Full User Profile

Drag'n'drop in JavaFX

03.09.2008
| 14104 views |
  • submit to reddit

Using drag'n'drop in JavaFX applications.

What is drag'n'drop from the point of view of the operating system?

The drag'n'drop operation is a sequence of actions that includes the following:

  • the operating system receives a message from the source application indicating the start of the drag operation
  • the source application places data about the objects being dragged in the buffer
  • once the cursor is placed over the window of the receiver application, the operating system requests the receiver application to allow dragging
  • when the dragging finishes, the receiver application notifies the source application

You can drag several objects simultaneously. The objects can be in different formats. For example, when you drag the browser link, the data that is placed in the buffer can be either the URL or the text associated with the link.

It is recommended to notify the source application about the end of the operation because additional actions may be required. For example, the drag operation may result in file copying or moving the file from one folder to another. In these cases, the source must delete the file.

Drag'n'drop support in JavaFX.

The following functions are used to implement the drag operation:

public attribute canAcceptDrop: function(e:CanvasDropEvent):Boolean?;

- is used to confirm that the drag operation is allowed. The 'e' variable contains a link to objects that are to be dragged.

public attribute onDrop: function(e:CanvasDropEvent)?;

- is called when the object was dragged.

The following code snippet shows how to extract the information about objects that are being dragged:

operation isFiles(e:CanvasDropEvent):Boolean {
var yes=false;
try{
(File)(e.transferData[0]);
yes=true;
} catch(any) {
//ignore
}
return yes;
}

- The code provides verification as to whether dragged objects are files or not

Examples of handling of the drag operation.

 

Dragging files or folders (for example, from the file manager):

 

Dragging an image from the graphic editor:

 

Dragging text:

 

Dragging a link from the browser:

 

Dragging a letter from the MS Outlook folder:

 

The source code of the example.

package dragondrop;

import javafx.ui.*;
import javafx.ui.canvas.*;
import javafx.ui.filter.*;
import java.io.File;
import java.lang.System;
import java.awt.datatransfer.DataFlavor;
import java.awt.image.BufferedImage;
import java.io.InputStreamReader;
import java.net.URL;
import java.io.ByteArrayOutputStream;

operation isInputStreamReader(e:CanvasDropEvent):Boolean {
var yes=false;
try{
(InputStreamReader)(e.transferData[0]);
yes=true;
} catch(any) {
//ignore
}
return yes;
}
operation isFiles(e:CanvasDropEvent):Boolean {
var yes=false;
try{
(File)(e.transferData[0]);
yes=true;
} catch(any) {
//ignore
}
return yes;
}
operation isBufferedImage(e:CanvasDropEvent):Boolean {
var yes=false;
try{
(BufferedImage)(e.transferData[0]);
yes=true;
} catch(any) {
//ignore
}
return yes;
}
operation isURL(e:CanvasDropEvent):Boolean {
var yes=false;
try{
(URL)(e.transferData[0]);
yes=true;
} catch(any) {
//ignore
}
return yes;
}

Frame {
var: me
visible: true
width: 300
height: 300
title: "Drop something here"
content: Canvas {
canAcceptDrop: operation(e:CanvasDropEvent):Boolean {
return true;
}
onDrop: operation(e:CanvasDropEvent) {
var info;
if(isFiles(e)){
var file=(File)(e.transferData[0]);
var fileName=file.getAbsolutePath();
info="this is File\n{fileName}";
} else {
if(isBufferedImage(e)){
var image=(BufferedImage)(e.transferData[0]);
var h=image.getHeight();
var w=image.getWidth();
info="this is BufferedImage\nwidth={w}, height={h}";
} else {
if(isURL(e)){
var url=(URL)(e.transferData[0]);
info="this is URL\n{url}";
}else {
if(isInputStreamReader(e)){
var isr=(InputStreamReader)(e.transferData[0]);
var baos=new ByteArrayOutputStream();
var b=isr.read();
while(b>-1){
baos.write(b);
b=isr.read();
}
info="this is InputStreamReader\n{baos}";
} else {
var o=e.transferData[0];
info="unknown\n{o}";
}
}
}
}
MessageDialog {
owner: me
visible: true
message: info
};
}
}
}
 
5
Your rating: None Average: 5 (1 vote)
Published at DZone with permission of its author, Sergey Surikov.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Artur Biesiadowski replied on Mon, 2008/03/10 - 5:10pm

Isn't there any nicer way to solve argument polymorphism than swallowing exceptions for each case? Something like instanceof, or even better, dynamic dispatch on argument type?

I still cannot grasp the idea of JavaFX language - it's design looks quite strange to me (looks like java subset with few syntax sugar cubes for initialization of objects/variables). Isn't groovy with it builders better? Leave the deployment/scenegraph/etc elements of JavaFX, just get rid of this half-baked scripting language.

Sergey Surikov replied on Mon, 2008/03/10 - 5:26pm in response to: Artur Biesiadowski

this is the simplest way. And it works.

Change your code to
if(x.getClass=="java.io.File")...
or something else

Eric Warrines replied on Sun, 2009/02/01 - 1:21pm

Hi Sergey, Any updates to this article since the recent changes to the JavaFX api that exclude the canvas object? Thanks Eric http://ericonjavafx.com/

Eric Warrines replied on Sun, 2009/02/01 - 1:22pm

.

Sergey Surikov replied on Mon, 2009/02/02 - 3:33am in response to: Eric Warrines

No. I'v got no time

Sergey Surikov replied on Tue, 2009/03/03 - 10:22am in response to: Eric Warrines

JavaFX text editor with drag'n'drop support

http://jfxstudio.wordpress.com/2009/02/18/something-usefull/

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.