- Forward


Drag and Drop
in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Introduction
Back SMYC Forward
  • Drag and Drop (DnD):
    • A gesture-based mechanism that allows for data transfer from one GUI component to another
  • Cut, Copy and Paste (CCP):
    • A keyboard-based or virtual keyboard-based mechanism that allows for data transfer from one GUI compoenent to another
  • An Important Detail:
    • DnD can either involve a copy or a move and the OS may only allow cross-application DnD for one or the other (or both)
Participants
Back SMYC Forward
  • An Object that implements the Transferable interface
  • A DataFlavor that describes the Transferable
  • A Component that has an associated DragSource
  • A DragGestureListener that is informed when a drag gesture is recognized by a DragSource
  • A Component that has an associated DropTarget
  • A TransferHandler that handles the transfer of the Transferable to/from the Component objects.
The Process
Back SMYC Forward
  • When the drag starts, the source object's getTransferHandler() method is invoked
  • That TransferHandler object's createTransferable() method is invoked which results in a call to the source object's get____() method (where ____ denotes the name of the attribute)
  • Each time the mouse is moved (during the drag) the TransferHandler object's getSourceActions() and canImport() methods are invoked
  • On the drop, the current Component object's set____() method is invoked and the source object's exportDone() method is invoked
Support in Existing Components
Back SMYC Forward
  • Components that Recognize the Drag Gesture:
    • After a call to setDragEnabled(true) the following components recognize the drag gesture: JColorChooser, JEditorPane, JFileChooser, JFormattedTextField, JList, JTable, JTextArea, JTextField, JTextPane, and JTree
  • Components that Support Drop:
    • The following components support dropping with no additional code: JEditorPane, JFormattedTextField, JPasswordField, JTextArea, JTextField, and JTextPane
    • The following components require some custom code to support dropping: JList, JTable, JTree
An Example with Text Components
Back SMYC Forward
  • The Transferable:
    • A java.awt.datatransfer.StringSelection
  • The DataFlavor:
    • DataFlavor.stringFlavor
  • The Source and Target:
    • A JList (with a java.awt.dnd.DragSource) and a JTextArea (with a javax.swing.TransferHandler.SwingDropTarget)
  • The TransferHandler:
    • A javax.swing.plaf.basic.BasicTextUI.TextTransferHandler
An Example with Text Components
Back SMYC Forward
javaexamples/draganddrop/outofthebox/OutOfTheBoxDemo.java
 
Adding Support to Other Text Components
Back SMYC Forward
  • Hooks:
    • Other components have "hooks" that can be used to add drag-and-drop support
  • The Simple Cases:
    • When the standard TransferHandler can be used to transfer String objects to/from components that have the "text" property (i.e., getText() and setText() methods) using DataFlavor.stringFlavor
Adding Support to Other Text Components (cont.)
Back SMYC Forward
  • An Example:
    • JLabel has getText() and setText() methods
  • Adding Drop Support:
    • Invoke setTransferHandler()
  • Adding Drag Support:
    • Export the initiation of a drag gesture to the TransferHandler
Adding Support to Other Text Components (cont.)
Back SMYC Forward
javaexamples/draganddrop/hooks/LabelDemo.java (Fragment: drop)
 
Adding Support to Other Text Components (cont.)
Back SMYC Forward
javaexamples/draganddrop/hooks/LabelDemo.java (Fragment: drag)
 
Drop Support using the "Standard" TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • A Component that can display words at random locations (like a collage)
  • The Custom Classes:
    • A class with a String and a location
    • A specialization of JPanel
  • The Existing Classes:
    • TransferHandler
Drop Support using TransferHandler (cont.)
Back SMYC Forward
The Positioned String
javaexamples/draganddrop/drop/standardhandler/StringContent.java
 
Drop Support using TransferHandler (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/drop/standardhandler/StringCollage.java
 
Drop Support using TransferHandler (cont.)
Back SMYC Forward
An Application
javaexamples/draganddrop/drop/standardhandler/StringCollageDemo.java
 
Drop Location Support
Back SMYC Forward
  • The Desired Functionality:
    • Drop at the mouse location instead of at random locations
  • Possible Approaches:
    • Use a custom TransferHandler
    • Register a DropTargetListener and a DropTarget to register it with
  • The Design:
    • Since we'll discuss customizing the TransferHandler for other purposes later, let's use the second approach now
    • Have StringCollage implement DropTargetListener
Drop Location Support (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/drop/standardhandler/locationsupport/StringCollage.java
 
Drag Support using TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • The ability to drag a copy of the last piece of text on a Component that displays words at different locations (like a collage)
  • What's Needed:
    • The ability to inform the TransferHandler that a drag gesture has started
  • Possible Approaches:
    • Add a DragGestureRecognizer and a DragSource to register it with
    • Use a MouseListener
  • The Design:
    • Since will use a DragSource later, we'll use the second approach now
    • Since the MouseListener will only be used locally and once, we'll use an anonymous class
Drag Support using TransferHandler (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/drag/standardhandler/StringCollage.java (Fragment: constructor)
 
Adding Move Support using TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • The ability to move (rather than copy) the last piece of text on a Component that displays words at different locations (like a collage)
  • What's Needed:
    • The ability to remove the text from the source after the drop has been completed
  • Possible Approaches:
    • Use a custom TransferHandler
    • Add a DragGestureListener and DragSourceListener and a DragSource to register them with
  • The Design:
    • We'll consider a custom TransferHandler later so will use the second approach now
    • Have StringCollage implement DragGestureListener and DragSourceListener
Move Support using TransferHandler (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/drag/standardhandler/movesupport/StringCollage.java
 
Move Support with a Custom TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • The ability to move (rather than copy) the last piece of text on a Component that displays words at different locations (like a collage)
  • The Design:
    • Use a custom TransferHandler that controls the process
Move Support using a Custom TransferHandler (cont.)
Back SMYC Forward
The StringTransferHandler
javaexamples/draganddrop/drag/customhandler/StringTransferHandler.java
 
Move Support using a Custom TransferHandler (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/drag/customhandler/StringCollage.java (Fragment: constructor)
 
What's Next?
Back SMYC Forward
  • Images:
    • Using the "standard" TransferHandler and DataFlavor
    • Using a custom TransferHndler
  • Other Objects:
    • Using a custom TransferHndler
What's Next? (cont.)
Back SMYC Forward
  • Up Until Now:
    • When discussing text, we could use exitsing GUI components for the "other half" of the operation
  • Now:
    • We must add both drag and drop capabiltiies at the same time in order to be able to do anything
Image Drag-and-Drop using a "Standard" TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • Drag a copy of an image from one instance and drop it on another
  • The Classes:
    • The GUI component
Image DnD using TransferHandler
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/dnd/image/standardhandler/ImagePanel.java
 
Image DnD using TransferHandler
Back SMYC Forward
An Application
javaexamples/draganddrop/dnd/image/standardhandler/ImagePanelDemo.java
 
Before We Continue
Back SMYC Forward
  • An Unnoticed Capability:
    • DnD only works with objects that implement the Transferable interface
    • Until now we have been able to use existing classes (e.g., the StringSelection class) for this purpose
  • What's Needed:
    • A Transferable version of the object of interest
Before We Continue (cont.)
Back SMYC Forward
  • Providing the Functionality of Both:
    • Extend/decorate the class/object of interest and implement the Transferable interface
  • Providing Only Transferable Functionality:
    • Wrap the object in another object that implements the Transferable interface
Ways to Create a Transferable Image
Back SMYC Forward
  • Difficulties of Using Specialization:
    • Image is an abstract class, so we must extend either BufferedImage or VolatileImage which is limiting
  • Difficulties of Using Decoration:
    • Image isn't an interface so the decorator must extend it rather than implement it which can be confusing
  • Difficulties of Wrapping:
    • The DnD objects must wrap and unwrap
Ways to Create a Transferable Image (cont.)
Back SMYC Forward
  • What About StringSelection?
    • It's a wrapper
  • Implications:
    • The DnD objects must wrap and unwrap String objects so nothing new is required
Move Support with TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • The ability to remove the dragged object from the source (i.e., move rather than copy)
  • The Classes:
    • The Transferable (which must use a local object reference)
    • The GUI Component
Move Support with TransferHandler (cont.)
Back SMYC Forward
The Transferable
javaexamples/draganddrop/dnd/image/standardhandler/movesupport/ImageSelection.java
 
Move Support with TransferHandler (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/dnd/image/standardhandler/movesupport/ImagePanel.java
 
Image DnD with a Custom TransferHandler
Back SMYC Forward
  • The Desired Functionality:
    • Full DnD (move and copy)
  • The Necessary Classes:
    • The Transferable (which can now use a more flexible DataFlavor)
    • The TransferHandler
    • The GUI Component
  • Improving the Design:
    • An interface that describes the capabilities of the GUI component
Image DnD with a Custom TransferHandler (cont.)
Back SMYC Forward
The Requirements of the GUI Component
javaexamples/draganddrop/dnd/image/customhandler/ImageTransferer.java
 
Image DnD with a Custom TransferHandler (cont.)
Back SMYC Forward
The Transferable
javaexamples/draganddrop/dnd/image/customhandler/ImageSelection.java
 
Image DnD with a Custom TransferHandler (cont.)
Back SMYC Forward
The Custom TransferHandler
javaexamples/draganddrop/dnd/image/customhandler/ImageTransferHandler.java
 
Image DnD with a Custom TransferHandler (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/dnd/image/customhandler/ImagePanel.java
 
DnD with other Objects
Back SMYC Forward
  • Desired Functionality:
    • The ability to drag-and-drop an object containing an Appointment (which has Date and String attributes) from one GUI component to another
  • The Necessary Classes:
    • An Appointment class (which implements Transferable)
    • A custom TransferHandler
    • The GUI component
  • A Design Improvement:
    • An interface that describes the capabilities of the GUI component
DnD with other Objects (cont.)
Back SMYC Forward
The Appoinment Class
javaexamples/draganddrop/dnd/appointment/Appointment.java
 
DnD with other Objects (cont.)
Back SMYC Forward
Requirements of the GUI Component
javaexamples/draganddrop/dnd/appointment/AppointmentTransferer.java
 
DnD with other Objects (cont.)
Back SMYC Forward
The Custom TransferHandler
javaexamples/draganddrop/dnd/appointment/AppointmentTransferHandler.java
 
DnD with other Objects (cont.)
Back SMYC Forward
The GUI Component
javaexamples/draganddrop/dnd/appointment/AppointmentPanel.java
 
DnD with other Objects (cont.)
Back SMYC Forward
An Application
javaexamples/draganddrop/dnd/appointment/AppointmentPanelDemo.java
 
What Else is Possible?
Back SMYC Forward
  • Using the "Standard" TransferHandler:
    • Use a String representation for the transfer and create/parse as needed (with DataFlavor.stringFlavor )
    • Use a serialization for the transfer (with DataFlavor.javaSerializedObjectMimeType )
    • Use a local object for the transfer (with new DataFlavor("application/x-java-jvm-local-objectref;class=Appointment") )
  • Using a Custom TransferHandler:
    • Almost anything (especially if you also use a DragSource and or DropTarget)
There's Always More to Learn
Back -