tags:

views:

640

answers:

1

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).

+1  A: 

I had this problem too but it appears to be fixed with the latest java version:

ray@featuritis:~/projects>java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04-248-10M3025)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)
depsypher
Finally. It seemed like this problem was around for a while without a fix. I will test it soon, to make sure.
Rocket
Yay! Apple fixed this in Java 1.6.0_17 :-D
Rocket