1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
package ij.io;
import ij.*;
import ij.gui.*;
import ij.plugin.frame.Recorder;
import ij.util.Java2;
import java.awt.*;
import java.io.*;
import java.util.ArrayList; //no need to import java.util.List; it would be ambiguous because of java.awt.List
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.*;
import javax.swing.filechooser.*;
import java.awt.datatransfer.*;
/** This class handles drag&drop onto JFileChoosers. */
public class DragAndDropHandler extends TransferHandler {
private JFileChooser jFileChooser;
/** Given a JFileChooser 'fc', this is how to use this class:
* <pre>
* fc.setDragEnabled(true);
* fc.setTransferHandler(new DragAndDropHandler(fc));
* </pre>
*/
public DragAndDropHandler(JFileChooser jFileChooser) {
super();
this.jFileChooser = jFileChooser;
}
/** Returns whether any of the transfer flavors is supported */
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
for (DataFlavor dataFlavor : transferFlavors) {
if (isSupportedTransferFlavor(dataFlavor))
return true;
}
return false;
}
/** Imports the drag&drop file or list of files and sets the JFileChooser to this.
* Returns true if successful */
public boolean importData(JComponent comp, Transferable t) {
DataFlavor[] transferFlavors = t.getTransferDataFlavors();
for (DataFlavor dataFlavor : transferFlavors) {
try {
java.util.List<File> fileList = null;
if (dataFlavor.isFlavorJavaFileListType()) {
fileList = (java.util.List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
if (IJ.debugMode) IJ.log("dragAndDrop FileList size="+fileList.size()+" first: "+fileList.get(0));
} else if (isSupportedTransferFlavor(dataFlavor)) {
String str = (String)t.getTransferData(dataFlavor);
if (IJ.debugMode) IJ.log("dragAndDrop str="+str);
String[] strs = str.split("[\n\r]+"); //multiple files are separate lines
fileList = new ArrayList<File>(strs.length);
for (String s : strs) {
if (s.length() > 0) {
File file = new File(s); //Try whether it is a plain path (pointing to an existing file)
if (!file.exists()) try {
file = new File(new URI(s)); //When not successful, try a whether it is a URL, e.g. file:///absolute/path/to/file
} catch (URISyntaxException e) {continue;}
if (file.exists()) //We only accept drag&drop of existing files
fileList.add(file);
}
}
}
if (fileList == null || fileList.size() ==0) continue; //this data flavor did not work
File firstFile = fileList.get(0);
if (jFileChooser.isMultiSelectionEnabled()) { //multiple files accepted
File dir = firstFile.getParentFile();
jFileChooser.setCurrentDirectory(dir);
File[] files = fileList.toArray(new File[0]);
jFileChooser.setSelectedFiles(files);
} else {
File file = firstFile; //single file required; if we get more take the first one
if (jFileChooser.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY && !file.isDirectory())
file = file.getParentFile(); //if a directory is required and we get a file, use its directory
if (jFileChooser.getDialogType() == JFileChooser.SAVE_DIALOG && file.isDirectory())
jFileChooser.setCurrentDirectory(file); //in a save operation, if we get a directory, move there
else
jFileChooser.setSelectedFile(file);
}
jFileChooser.rescanCurrentDirectory();
return true;
} catch (Exception e) {if (IJ.debugMode) IJ.handleException(e);}
}
return false;
}
/** Returns whether this transfer flavor is supported. We support File Lists and Strings (plain or as list of URLs). */
public boolean isSupportedTransferFlavor(DataFlavor flavor) {
return flavor.isFlavorJavaFileListType() ||
(flavor.getRepresentationClass() == String.class &&
(flavor.getMimeType().startsWith("text/uri-list") || flavor.getMimeType().startsWith("text/plain")));
}
}
|