Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How to drag a file from a JTable to native filesystem?

My Java 7 Swing application features a JTable that contains the following objects:

public class MyFile {

    private long id;
    private long created;
    private long modified;
    private String description;
    private File file;

    public MyFile(long id) {
        this.id = id;
        this.created = System.currentTimeMillis();
    }

    // getter & setter methods ...

}

The goal is to drag these MyFile objects out of my application and drop them to the filesystem (e.g. to the desktop). When setting setDragEnabled(true) to my JTable, the icon already turns to a "+" symbol when dragging a table entry, as known by regular drag&drop actions from other applications. But when actually dropping the object to the desktop nothing happens...

How can I tell my JTable to only drop the File object inside the MyFile object ? Did I forgot more things ?

Could someone provide a short sample ?

Many thanks for your help in advance!

like image 950
salocinx Avatar asked May 02 '13 08:05

salocinx


2 Answers

You must make sure that the created Transferable contains the DataFlavor#javaFileListFlavor and that the data for that flavor is the File contained in your MyFile instance (to be more precise: a List with the File, as explained in the javadoc of that flavor).

This will probably require a custom TransferHandler on your JTable.

like image 83
Robin Avatar answered Sep 19 '22 18:09

Robin


Configure your table with the following properties:

tblDocuments.setDragEnabled(true);
tblDocuments.setTransferHandler(new FileTransferHandler());

Here's the TransferHandler implementation:

public class FileTransferHandler extends TransferHandler {

    @Override
    protected Transferable createTransferable(JComponent c) {
        List<File> files = new ArrayList<File>();
        // copy your files from the component to a concrete List<File> files ...
        // the following code would be a sample for a JList filled with java.io.File(s) ...
        /*JList list = (JList) c;
        for (Object obj: list.getSelectedValues()) {
            files.add((File)obj);
        }*/
        return new FileTransferable(files);
    }

    @Override
    public int getSourceActions(JComponent c) {
        return MOVE;
    }
}

Here's the FileTransferable implementation:

public class FileTransferable implements Transferable {

    private List<File> files;

    public FileTransferable(List<File> files) {
        this.files = files;
    }

    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[]{DataFlavor.javaFileListFlavor};
    }

    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return flavor.equals(DataFlavor.javaFileListFlavor);
    }

    public Object getTransferData(DataFlavor flavor)
            throws UnsupportedFlavorException, IOException {
        if (!isDataFlavorSupported(flavor)) {
            throw new UnsupportedFlavorException(flavor);
        }
        return files;
    }
}
like image 37
salocinx Avatar answered Sep 18 '22 18:09

salocinx