2009-11-08 11 views
7

Estoy haciendo un programa de Java, y una forma de cargar archivos es arrastrar el archivo a la ventana de la aplicación (swing). Tengo un código que funciona en Windows y Linux. Funciona en OS X, pero el primer archivo que arrastro arroja una excepción, y luego el resto funciona bien.Java arrastrar y soltar en Mac OS X

Aquí está el código que uso para habilitar 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()); 
    } 
} 

Por alguna razón, OS X, se emite una ArrayIndexOutOfBoundsException en esta línea:

flavor = (flavor == null) ? flavors[0] : flavor; 

Después de que se lanza una excepción, si arrastro otro archivo en la ventana, funciona. ¿Por qué arroja una excepción?

NOTA: mainWindow.openFile() es una función que abre un archivo. Toma un parámetro de cadena (el nombre del archivo) y el programa abre ese archivo.

NOTA 2: Esto está en OS X 10.6.2 (Snow Leopard).

+0

Eso sólo puede significar que los sabores en ese punto no contiene ningún registro. ¿Verificaste si getTransferDataFlavors() o getCurrentDataFlavors() devuelve algo en el primer arrastrar/soltar? – jitter

+0

Bueno, sabores [0] me está dando una excepción fuera de límites. Compruebo si tr.getTransferDataFlavors() tiene una longitud cero, si lo hago, uso dtde.getCurrentDataFlavors() en su lugar. Entonces, aparentemente, dtde.getCurrentDataFlavors() tiene una longitud cero, que es lo que está causando la excepción de fuera de límites. –

+0

Tal vez si trato de obtener los DataFlavors en el evento dragEnter, no serán nulos cuando se desencadene el evento drop. –

Respuesta

4

tuve este problema también, pero parece estar fijo con la última versión de Java:

[email protected]:~/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) 
+0

Finalmente. Parecía que este problema estaba por un tiempo sin una solución. Voy a probarlo pronto, para estar seguro. –

+0

¡Yay! Apple arregló esto en Java 1.6.0_17 :-D –