2009-11-08 14 views
7

私はJavaプログラムを作成していますが、ファイルをロードする方法の1つは、ファイルをアプリケーションウィンドウ(スイング)にドラッグすることです。私はWindowsとLinuxで動作するコードを持っています。それはOS Xで動作しますが、最初のファイルをドラッグすると例外がスローされ、その後は正常に動作します。Mac OS XのJavaドラッグアンドドロップ

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()); 
    } 
} 

は、OS Xは、この行には、ArrayIndexOutOfBoundsExceptionがスローされます。その例外がスローされ

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

た後、私は窓の上に別のファイルをドラッグすると、それが動作します。なぜそれは例外をスローしますか?

注:mainWindow.openFile()は、ファイルを開く関数です。それは文字列パラメータ(ファイル名)をとり、プログラムはそのファイルを開きます。

注2:これはOS X 10.6.2(Snow Leopard)です。

+0

のみ、その時点で味がすべてのレコードが含まれていないことを意味することができます。 getTransferDataFlavors()またはgetCurrentDataFlavors()が最初のドラッグ/ドロップで何かを返すかどうかチェックしましたか? – jitter

+0

まあ、フレーバー[0]は私に境界外の例外を与えています。 tr.getTransferDataFlavors()の長さがゼロであるかどうかを確認します。代わりにdtde.getCurrentDataFlavors()を使用します。したがって、明らかにdtde.getCurrentDataFlavors()の長さはゼロです。これは、範囲外の例外の原因となっています。 –

+0

DragEnterイベントでDataFlavorsを取得しようとすると、ドロップイベントが発生したときにnullになることはありません。 –

答えて

4

私もこの問題を抱えていたが、最新の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

最後に。この問題はしばらくの間修正されていなかったようだった。私はすぐにそれをテストして、確かめる。 –

+0

よろしく! AppleはこれをJava 1.6.0_17:-Dで修正しました –