title: Testing drag-and-drop files onto application
body: <p>I am looking for a method to perform a drag-and-drop of a file/multiple files onto my application from a unit test. For example selecting some files in Windows Explorer, drag them and drop them on my application.</p>
  
  <p>I am capable of testing drag-and-drop behavior between two components in my application (see below - feel free to indicate if you know a better way), but I have no idea how to do the same when the data has to come from outside my application.</p>
  
  <p>I thought about using the debugger to inspect a 'file' <code>Transferable</code> when I do the drag-and-drop operation by hand, but there must be a better way then hard-coding a complete <code>Transferable</code>.</p>
  
  <p>Example of a drag-and-drop test between components</p>
  
  <pre><code>import org.junit.Test;
  
  import javax.swing.Action;
  import javax.swing.JTextField;
  import javax.swing.TransferHandler;
  import java.awt.event.ActionEvent;
  
  import static org.junit.Assert.assertEquals;
  
  public class DragAndDropTest {
    @Test
    public void dragAndDropBetweenTwoTextFields() {
      JTextField firstField = new JTextField();
      JTextField secondField = new JTextField();
      String testText = "Test text";
      firstField.setText( testText );
      firstField.selectAll();
      Action copyAction = TransferHandler.getCopyAction();
      copyAction.actionPerformed( new ActionEvent( firstField, ActionEvent.ACTION_PERFORMED, "Copy" ) );
      Action pasteAction = TransferHandler.getPasteAction();
      pasteAction.actionPerformed( new ActionEvent( secondField, ActionEvent.ACTION_PERFORMED, "Paste" ) );
      assertEquals( "Text is not copied", testText, secondField.getText() );
    }
  }
  </code></pre>
  
  <p><strong>Edit</strong></p>
  
  <p>Based on the comments under this question, I have updated my code snippet to 'fake' a drag-and-drop by providing a hard-coded <code>Transferable</code>. The code also  contains a little main program which just creates an empty frame on which you can drop files. The path will then be printed on the console.</p>
  
  <p>On my PC, drag-and-drop of a file does not use the <code>javaFileListFlavor</code> but the URI flavor. 
  Previous experiences (see <a href="https://stackoverflow.com/questions/8700073/drag-and-drop-differences-between-jdk1-6-and-jdk1-7">this question</a>) already teached me that the <code>Transferable</code> a component receives when dragging something from outside the Java application might differ in subtle ways.</p>
  
  <p>So to be completely clear: I want to test the part of my code that extracts the information from the received <code>Transferable</code>. The 'information-handling' code (e.g. what happens when the application receives the file) can easily be tested without bothering with D&amp;D. I just need to make sure I extract the correct information from the <code>Transferable</code>, and it is silly to test this with a hard-coded <code>Transferable</code>.</p>
  
  <pre><code>import org.junit.Test;
  
  import javax.swing.Action;
  import javax.swing.JComponent;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  import javax.swing.TransferHandler;
  import java.awt.BorderLayout;
  import java.awt.EventQueue;
  import java.awt.datatransfer.Clipboard;
  import java.awt.datatransfer.DataFlavor;
  import java.awt.datatransfer.Transferable;
  import java.awt.datatransfer.UnsupportedFlavorException;
  import java.awt.event.ActionEvent;
  import java.io.File;
  import java.io.IOException;
  import java.util.List;
  
  import static org.junit.Assert.assertEquals;
  
  public class DragAndDropTest {
    private static DataFlavor URI_LIST_FLAVOR = null;
    static {
      try {
        URI_LIST_FLAVOR = new DataFlavor( "text/uri-list;class=java.lang.String" );
      }
      catch ( ClassNotFoundException ignore ) {
      }
    }
  
    @Test
    public void testFileDragAndDrop() throws IOException, UnsupportedFlavorException {
      JComponent testComponent = new JPanel();
      TestingTransferHandler transferHandler = new TestingTransferHandler();
      testComponent.setTransferHandler( transferHandler );
      Clipboard clipBoard = new JLabel(  ).getToolkit().getSystemClipboard();
      Transferable transferable = new Transferable() {
        @Override
        public DataFlavor[] getTransferDataFlavors() {
          return new DataFlavor[]{URI_LIST_FLAVOR};
        }
  
        @Override
        public boolean isDataFlavorSupported( DataFlavor flavor ) {
          return flavor == URI_LIST_FLAVOR;
        }
  
        @Override
        public Object getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException, IOException {
          if ( flavor == URI_LIST_FLAVOR ) {
            return new String( "file:///home/robins/Desktop/swingx-1.0-javadoc.jar" );
          }
          throw new UnsupportedFlavorException( flavor );
        }
      };
      clipBoard.setContents( transferable, null );
      Action pasteAction = TransferHandler.getPasteAction();
      pasteAction.actionPerformed( new ActionEvent( testComponent, ActionEvent.ACTION_PERFORMED, "Paste" ) );
      assertEquals( transferable.getTransferData( URI_LIST_FLAVOR ), transferHandler.transferable.getTransferData( URI_LIST_FLAVOR ) );
    }
  
    private static class TestingTransferHandler extends TransferHandler{
      public Transferable transferable;
      @Override
      public boolean canImport( TransferSupport support ) {
        return true;
      }
      @Override
      public boolean importData( TransferSupport support ) {
        transferable = support.getTransferable();
        try{
          if ( transferable.isDataFlavorSupported( DataFlavor.javaFileListFlavor ) ) {
            System.out.println("File list flavor");
            List&lt;File&gt; fileList = ( List&lt;File&gt; ) transferable.getTransferData( DataFlavor.javaFileListFlavor );
            System.out.println( "fileList = " + fileList );
          }
          if ( transferable.isDataFlavorSupported( URI_LIST_FLAVOR )){
            System.out.println("URI list flavor");
            String uriList = ( String ) transferable.getTransferData( URI_LIST_FLAVOR );
            System.out.println( "uriList = " + uriList );
          }
          return true;
        } catch ( UnsupportedFlavorException e ) {
          return false;
        } catch ( IOException e ) {
          return false;
        }
      }
    }
  
    public static void main( String[] args ) {
      EventQueue.invokeLater( new Runnable() {
        @Override
        public void run() {
          JFrame frame = new JFrame( "TestFrame" );
          JPanel contentPane = new JPanel( new BorderLayout(  ) );
          contentPane.setTransferHandler( new TestingTransferHandler() );
          frame.setContentPane( contentPane );
          frame.setSize( 200,200 );
          frame.setVisible( true );
          frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        }
      } );
    }
  }
  </code></pre>