-1

I want to drag and drop swing components to a windows explorer.

I found that answer which does the opposite that I need although the title says the opposite : Swing application -> Drag & drop to the desktop / folder

Also found that answer mentioning the OLE interface and JNI interface : https://coderanch.com/t/659365/java/Drag-Drop-Explorer

And also this thread in which OP has the exact same problem as me : https://www.dreamincode.net/forums/topic/148892-drag-and-drop-to-windows-explorer/

Sybuser
  • 735
  • 10
  • 27
  • 1
    In your last link, they posted a link to a [BasicDnD](https://docs.oracle.com/javase/tutorial/uiswing/examples/dnd/BasicDnDProject/src/dnd/BasicDnD.java) Java class that if you copy-paste, compile and run, and enable Drag & Drop at the bottom left corner of the program you'll get a working example that handles Drag & Drop both ways, from Swing to another program and viceversa. If that doesn't work then please post a proper [mre] that demonstrates your issue. – Frakcool Jul 08 '20 at 16:12

1 Answers1

1

Here is an example that involves drag-n-drop of files from a JTree to a windows explorer :

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

public class FileBrowser implements Runnable {

    private DefaultMutableTreeNode root;

    private DefaultTreeModel treeModel;

    private JTree tree;

    @Override
    public void run() {
        JFrame frame = new JFrame("File Browser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        File fileRoot = File.listRoots()[0];
        root = new DefaultMutableTreeNode(new FileNode(fileRoot));
        treeModel = new DefaultTreeModel(root);

        tree = new JTree(treeModel);
        tree.setShowsRootHandles(true);
        tree.setDragEnabled(true);
        tree.setTransferHandler(new FileTransferHandler());
        JScrollPane scrollPane = new JScrollPane(tree);

        frame.add(scrollPane);
        frame.setLocationByPlatform(true);
        frame.setSize(640, 480);
        frame.setVisible(true);

        CreateChildNodes ccn = new CreateChildNodes(fileRoot, root);
        new Thread(ccn).start();
    }

    public class CreateChildNodes implements Runnable {

        private DefaultMutableTreeNode root;

        private File fileRoot;

        public CreateChildNodes(File fileRoot, DefaultMutableTreeNode root) {
            this.fileRoot = fileRoot;
            this.root = root;
        }

        @Override
        public void run() {
            createChildren(fileRoot, root);
        }

        private void createChildren(File fileRoot, DefaultMutableTreeNode node) {
            File[] files = fileRoot.listFiles();
            if (files == null)
                return;

            for (File file : files) {
                DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(new FileNode(file));
                node.add(childNode);
                if (file.isDirectory()) {
                    createChildren(file, childNode);
                }
            }
        }

    }

    public class FileNode {

        private File file;

        public FileNode(File file) {
            this.file = file;
        }

        @Override
        public String toString() {
            String name = file.getName();
            if (name.equals("")) {
                return file.getAbsolutePath();
            } else {
                return name;
            }
        }
    }

    private class FileTransferHandler extends TransferHandler {

        private static final long serialVersionUID = 1L;

        @Override
        protected Transferable createTransferable(JComponent c) {
            JTree list = (JTree) c;
            List<File> files = new ArrayList<File>();
            for (TreePath path : list.getSelectionPaths()) {
                files.add(new File(Arrays.stream(path.getPath()).map(Object::toString).collect(Collectors.joining(File.separator))));
            }
            return new FileTransferable(files);
        }

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

    private 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;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new FileBrowser());
    }

}
Sybuser
  • 735
  • 10
  • 27