I am making a Java program, and one way to load files is to drag the file onto the application window (swing). I have code that works in Windows and Linux. It works in OS X, but the 1st file I drag throws an exception, and then the rest work fine.
Here is the code I use to enable DnD.
/*
* Allow a file to be opened by dragging it onto the window
*/
public void drop(DropTargetDropEvent dtde){
try {
// Get the object to be transferred
Transferable tr = dtde.getTransferable();
DataFlavor[] flavors = tr.getTransferDataFlavors();
// If flavors is empty get flavor list from DropTarget
flavors = (flavors.length == 0) ? dtde.getCurrentDataFlavors() : flavors;
// Select best data flavor
DataFlavor flavor = DataFlavor.selectBestTextFlavor(flavors);
// Flavor will be null on Windows
// In which case use the 1st available flavor
flavor = (flavor == null) ? flavors[0] : flavor;
// Flavors to check
DataFlavor Linux = new DataFlavor("text/uri-list;class=java.io.Reader");
DataFlavor Windows = DataFlavor.javaFileListFlavor;
// On Linux (and OS X) file DnD is a reader
if(flavor.equals(Linux)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
BufferedReader read = new BufferedReader(flavor.getReaderForText(tr));
// Remove 'file://' from file name
String fileName = read.readLine().substring(7).replace("%20"," ");
// Remove 'localhost' from OS X file names
if(fileName.substring(0,9).equals("localhost")) {
fileName = fileName.substring(9);
}
read.close();
dtde.dropComplete(true);
System.out.println("File Dragged:" + fileName);
mainWindow.openFile(fileName);
}
// On Windows file DnD is a file list
else if(flavor.equals(Windows)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
@SuppressWarnings("unchecked")
List<File> list = (List<File>)tr.getTransferData(flavor);
dtde.dropComplete(true);
if(list.size() == 1) {
System.out.println("File Dragged: " + list.get(0));
mainWindow.openFile(list.get(0).toString());
}
} else {
System.err.println("DnD Error");
dtde.rejectDrop();
}
}
//TODO: OS X Throws ArrayIndexOutOfBoundsException on first DnD
catch(ArrayIndexOutOfBoundsException e){
System.err.println("DnD not initalized properly, please try again.");
} catch(IOException e){
System.err.println(e.getMessage());
} catch(UnsupportedFlavorException e){
System.err.println(e.getMessage());
} catch (ClassNotFoundException e){
System.err.println(e.getMessage());
}
}
For some reason, OS X throws an ArrayIndexOutOfBoundsException on this line:
flavor = (flavor == null) ? flavors[0] : flavor;
After that exception is thrown, if I drag another file onto the window, it works. Why does it throw an exception?
NOTE: mainWindow.openFile() is a function that opens a file. It takes a sting parameter (the file name), and the program opens that file.
NOTE 2: This is on OS X 10.6.2 (Snow Leopard).