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).
Đó 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
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. –
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. –