2009-11-08 38 views
7

Tôi đang tạo một chương trình Java và một cách để tải tệp là kéo tệp vào cửa sổ ứng dụng (xoay). Tôi có mã hoạt động trong Windows và Linux. Nó hoạt động trong OS X, nhưng tập tin đầu tiên tôi kéo ném một ngoại lệ, và sau đó phần còn lại làm việc tốt.Kéo và thả Java trên Mac OS X

Đây là mã tôi sử dụng để bật 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()); 
    } 
} 

Đối với một số lý do, OS X ném một ArrayIndexOutOfBoundsException trên dòng này:

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

Sau ngoại lệ được ném ra, nếu tôi kéo tập tin khác vào cửa sổ, nó hoạt động. Tại sao nó ném một ngoại lệ?

LƯU Ý: mainWindow.openFile() là một hàm mở tệp. Nó lấy một tham số chuỗi (tên tệp) và chương trình sẽ mở tệp đó.

CHÚ Ý 2: Đây là trên OS X 10.6.2 (Snow Leopard).

+0

Đó chỉ có thể có nghĩa là hương vị tại thời điểm đó không chứa bất kỳ hồ sơ. Bạn đã kiểm tra xem getTransferDataFlavors() hoặc getCurrentDataFlavors() có trả về một cái gì đó trong lần kéo/thả đầu tiên không? – jitter

+0

Vâng, hương vị [0] cho tôi một ngoại lệ. Tôi kiểm tra nếu tr.getTransferDataFlavors() có độ dài bằng không, nếu tôi sử dụng dtde.getCurrentDataFlavors() để thay thế. Vì vậy, rõ ràng, dtde.getCurrentDataFlavors() có độ dài bằng 0, đó là những gì gây ra ngoại lệ giới hạn. –

+0

Có thể nếu tôi cố gắng lấy DataFlavors về sự kiện kéoEnter, chúng sẽ không rỗng khi sự kiện thả được kích hoạt. –

Trả lời

4

Tôi có vấn đề này quá nhưng nó dường như được cố định với phiên bản java mới nhất:

[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

Cuối cùng. Có vẻ như vấn đề này đã xảy ra một lúc mà không cần sửa chữa. Tôi sẽ kiểm tra nó sớm, để chắc chắn. –

+0

Yay! Apple đã sửa lỗi này trong Java 1.6.0_17 :-D –