开发者

Java Drag and Drop on Mac OS X

开发者 https://www.devze.com 2022-12-10 09:03 出处:网络
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 thro

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 B开发者_Go百科ufferedReader(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 string parameter (the file name), and the program opens that file.

NOTE 2: This is on OS X 10.6.2 (Snow Leopard).


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

精彩评论

暂无评论...
验证码 换一张
取 消