--- /dev/null
+package tim.prune;
+
+import java.awt.datatransfer.DataFlavor;
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+
+import javax.swing.TransferHandler;
+
+/**
+ * Class to listen for drag/drop events and react to dropping files on to the application
+ */
+public class FileDropHandler extends TransferHandler
+{
+ /** App object for passing results back to */
+ private App _app = null;
+
+ /** Fixed flavour in case the java file list flavour isn't available */
+ private static DataFlavor _uriListFlavour = null;
+
+ /** Static block to initialise the list flavour */
+ static
+ {
+ try {_uriListFlavour = new DataFlavor("text/uri-list;class=java.lang.String");
+ } catch (ClassNotFoundException nfe) {}
+ }
+
+
+ /**
+ * Constructor
+ * @param inApp App object to pass results of drop back to
+ */
+ public FileDropHandler(App inApp)
+ {
+ _app = inApp;
+ }
+
+ /**
+ * Check if the object being dragged can be accepted
+ * @param inSupport object to check
+ */
+ public boolean canImport(TransferSupport inSupport)
+ {
+ boolean retval = inSupport.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
+ || inSupport.isDataFlavorSupported(_uriListFlavour);
+ // Modify icon to show a copy, not a move (+ icon on cursor)
+ if (retval) {
+ inSupport.setDropAction(COPY);
+ }
+ return retval;
+ }
+
+ /**
+ * Accept the incoming data and pass it on to the App
+ * @param inSupport contents of drop
+ */
+ public boolean importData(TransferSupport inSupport)
+ {
+ if (!canImport(inSupport)) {return false;} // not allowed
+
+ boolean success = false;
+ ArrayList<File> dataFiles = new ArrayList<File>();
+
+ // Try a java file list flavour first
+ try
+ {
+ @SuppressWarnings("unchecked")
+ java.util.List<File> fileList = (java.util.List<File>)
+ inSupport.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
+ success = true;
+
+ for (File f : fileList)
+ {
+ if (f != null && f.exists())
+ {
+ if (f.isDirectory()) {
+ addDirectoryToList(f, dataFiles);
+ }
+ else if (f.isFile()) {
+ dataFiles.add(f);
+ }
+ }
+ }
+ } catch (Exception e) {} // exception caught, probably missing a javafilelist flavour - just continue
+
+ // If that didn't work, try a list of strings instead
+ if (!success)
+ {
+ try
+ {
+ String pathList = inSupport.getTransferable().getTransferData(_uriListFlavour).toString();
+ success = true;
+
+ for (String s : pathList.split("[\n\r]+"))
+ {
+ if (s != null && !s.equals(""))
+ {
+ File f = new File(new URI(s));
+ if (f.exists())
+ {
+ if (f.isDirectory()) {
+ addDirectoryToList(f, dataFiles);
+ }
+ else if (f.isFile()) {
+ dataFiles.add(f);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ System.err.println("exception: " + e.getClass().getName() + " - " + e.getMessage());
+ return false;
+ }
+ }
+
+ // Pass files back to app
+ if (!dataFiles.isEmpty()) {
+ _app.loadDataFiles(dataFiles);
+ }
+ return true;
+ }
+
+
+ /**
+ * Recursively-called method to add files from the given directory (and its subdirectories)
+ * to the given list of files
+ * @param inDir directory to add
+ * @param inList file list to append to
+ */
+ private void addDirectoryToList(File inDir, ArrayList<File> inList)
+ {
+ if (inDir != null && inDir.exists() && inDir.canRead() && inDir.isDirectory() && inList != null)
+ {
+ for (String path : inDir.list())
+ {
+ if (path != null)
+ {
+ File f = new File(inDir, path);
+ if (f.exists() && f.canRead())
+ {
+ if (f.isFile())
+ {
+ // Add the found file to the list (if it's not in there already)
+ if (!inList.contains(f)) {
+ inList.add(f);
+ }
+ }
+ else if (f.isDirectory())
+ {
+ // Recursively add the files from subdirectories
+ addDirectoryToList(f, inList);
+ }
+ }
+ }
+ }
+ }
+ }
+}