how to drag and drop files from a directory in java

16,243

Solution 1

This is my take on the idea. I've used the "traditional" drag and drop API in this example. It has some extra "paint" tweaks just to show off what you might be able to do.

enter image description hereenter image description here

This example doesn't scan folders dropped onto it, so any folder will only register as a single file, but I'm sure you can work it out

public class TestDragNDropFiles {

    public static void main(String[] args) {
        new TestDragNDropFiles();
    }

    public TestDragNDropFiles() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new DropPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DropPane extends JPanel {

        private DropTarget dropTarget;
        private DropTargetHandler dropTargetHandler;
        private Point dragPoint;

        private boolean dragOver = false;
        private BufferedImage target;

        private JLabel message;

        public DropPane() {
            try {
                target = ImageIO.read(new File("target.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setLayout(new GridBagLayout());
            message = new JLabel();
            message.setFont(message.getFont().deriveFont(Font.BOLD, 24));
            add(message);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        protected DropTarget getMyDropTarget() {
            if (dropTarget == null) {
                dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, null);
            }
            return dropTarget;
        }

        protected DropTargetHandler getDropTargetHandler() {
            if (dropTargetHandler == null) {
                dropTargetHandler = new DropTargetHandler();
            }
            return dropTargetHandler;
        }

        @Override
        public void addNotify() {
            super.addNotify();
            try {
                getMyDropTarget().addDropTargetListener(getDropTargetHandler());
            } catch (TooManyListenersException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            getMyDropTarget().removeDropTargetListener(getDropTargetHandler());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (dragOver) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(new Color(0, 255, 0, 64));
                g2d.fill(new Rectangle(getWidth(), getHeight()));
                if (dragPoint != null && target != null) {
                    int x = dragPoint.x - 12;
                    int y = dragPoint.y - 12;
                    g2d.drawImage(target, x, y, this);
                }
                g2d.dispose();
            }
        }

        protected void importFiles(final List files) {
            Runnable run = new Runnable() {
                @Override
                public void run() {
                    message.setText("You dropped " + files.size() + " files");
                }
            };
            SwingUtilities.invokeLater(run);
        }

        protected class DropTargetHandler implements DropTargetListener {

            protected void processDrag(DropTargetDragEvent dtde) {
                if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    dtde.acceptDrag(DnDConstants.ACTION_COPY);
                } else {
                    dtde.rejectDrag();
                }
            }

            @Override
            public void dragEnter(DropTargetDragEvent dtde) {
                processDrag(dtde);
                SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
                repaint();
            }

            @Override
            public void dragOver(DropTargetDragEvent dtde) {
                processDrag(dtde);
                SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
                repaint();
            }

            @Override
            public void dropActionChanged(DropTargetDragEvent dtde) {
            }

            @Override
            public void dragExit(DropTargetEvent dte) {
                SwingUtilities.invokeLater(new DragUpdate(false, null));
                repaint();
            }

            @Override
            public void drop(DropTargetDropEvent dtde) {

                SwingUtilities.invokeLater(new DragUpdate(false, null));

                Transferable transferable = dtde.getTransferable();
                if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    dtde.acceptDrop(dtde.getDropAction());
                    try {

                        List transferData = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor);
                        if (transferData != null && transferData.size() > 0) {
                            importFiles(transferData);
                            dtde.dropComplete(true);
                        }

                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                } else {
                    dtde.rejectDrop();
                }
            }
        }

        public class DragUpdate implements Runnable {

            private boolean dragOver;
            private Point dragPoint;

            public DragUpdate(boolean dragOver, Point dragPoint) {
                this.dragOver = dragOver;
                this.dragPoint = dragPoint;
            }

            @Override
            public void run() {
                DropPane.this.dragOver = dragOver;
                DropPane.this.dragPoint = dragPoint;
                DropPane.this.repaint();
            }
        }

    }
}

Solution 2

You need to experiment with Drag & Drop and see exactly what flavors are available when you try to drag files. If you do this in your custom TransferHandler you'll be pleasantly surprised one Flavor is the DataFlavor.javaFileListFlavor, which indicates that the item can be used simply as a List. Try it and you'll see that it works!

Note on review of your posted code, I don't see any code for your attempt at using a TransferHandler, so it is hard to say what you could be doing wrong here.

Edit 1
You seem to be trying to use a MouseListener for your drag and drop, and I'm not familiar with this usage. Can you show a reference to a tutorial that tells you to do this?

Edit 2

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class FileDragDemo extends JPanel {
   private JList list = new JList();

   public FileDragDemo() {
      list.setDragEnabled(true);
      list.setTransferHandler(new FileListTransferHandler(list));

      add(new JScrollPane(list));
   }

   private static void createAndShowGui() {
      FileDragDemo mainPanel = new FileDragDemo();

      JFrame frame = new JFrame("FileDragDemo");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

@SuppressWarnings("serial")
class FileListTransferHandler extends TransferHandler {
   private JList list;

   public FileListTransferHandler(JList list) {
      this.list = list;
   }

   public int getSourceActions(JComponent c) {
      return COPY_OR_MOVE;
   }

   public boolean canImport(TransferSupport ts) {
      return ts.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
   }

   public boolean importData(TransferSupport ts) {
      try {
         @SuppressWarnings("rawtypes")
         List data = (List) ts.getTransferable().getTransferData(
               DataFlavor.javaFileListFlavor);
         if (data.size() < 1) {
            return false;
         }

         DefaultListModel listModel = new DefaultListModel();
         for (Object item : data) {
            File file = (File) item;
            listModel.addElement(file);
         }

         list.setModel(listModel);
         return true;

      } catch (UnsupportedFlavorException e) {
         return false;
      } catch (IOException e) {
         return false;
      }
   }
}
Share:
16,243
rogerthat
Author by

rogerthat

Updated on June 04, 2022

Comments

  • rogerthat
    rogerthat almost 2 years

    I want to implement dragging and dropping of files from a directory such as someones hard drive but can't figure out how to do it. I've read the java api but it talks of color pickers and dragging and dropping between lists but how to drag files from a computers file system and drop into my application. I tried writing the transferhandler class and a mouse event for when the drag starts but nothing seems to work. Now I'm back to just having my JFileChooser set so drag has been enabled but how to drop?

    Any info or point in the right direction greatly appreciated.

      import javax.swing.*;
    
      import java.awt.BorderLayout;
     import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    
    import javax.swing.BorderFactory;
    import javax.swing.DefaultListModel;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFileChooser;
    import javax.swing.JFrame;
    
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.SwingUtilities;
    import javax.swing.filechooser.FileFilter;
    
     public class FileChooserDemo
     extends JPanel
     implements ActionListener 
      {
    
    JLabel selectedFileLabel;
     JList selectedFilesList;
     JLabel returnCodeLabel;
    
     public FileChooserDemo() 
        {
     super();
     createContent();
     }
    
    
    void initFrameContent() 
        {
            JPanel closePanel = new JPanel();
            add(closePanel, BorderLayout.SOUTH);
    }
    
    
     private void createContent()
        {
     setLayout(new BorderLayout());
    
            JPanel NorthPanel = new JPanel();
    
         JMenuBar menuBar = new JMenuBar();
            JMenu menu = new JMenu("File");
            JMenuItem quit = new JMenuItem("Quit");
    
            menuBar.add(menu);
            menu.add(quit);
    
            NorthPanel.add(menu,BorderLayout.NORTH);
    
    
      JPanel buttonPanel = new JPanel(new GridLayout(7,1 ));
      JButton openButton = new JButton("Open...");
      openButton.setActionCommand("OPEN");
      openButton.addActionListener(this);
     buttonPanel.add(openButton);
    
     JButton saveButton = new JButton("Save...");
     saveButton.setActionCommand("SAVE");
     saveButton.addActionListener(this);
     buttonPanel.add(saveButton);
    
    
    
    
      JButton delete = new JButton("Delete");
      delete.addActionListener(this);
      delete.setActionCommand("DELETE");
      buttonPanel.add(delete);
    
     add(buttonPanel, BorderLayout.WEST);
    
    
    
     // create a panel to display the selected file(s) and the return code
     JPanel displayPanel = new JPanel(new BorderLayout()); 
     selectedFileLabel = new JLabel("-");
    
     selectedFileLabel.setBorder(BorderFactory.createTitledBorder
     ("Selected File/Directory   "));
    
     displayPanel.add(selectedFileLabel, BorderLayout.NORTH);
    
     selectedFilesList = new JList();
     JScrollPane sp = new JScrollPane(selectedFilesList);
     sp.setBorder(BorderFactory.createTitledBorder("Selected Files "));
     MouseListener listener = new MouseAdapter()
     {
       public void mousePressed(MouseEvent me)
       {
           JComponent comp = (JComponent) me.getSource();
           TransferHandler handler = comp.getTransferHandler();
           handler.exportAsDrag(comp, me, TransferHandler.MOVE);   
       }
     };
     selectedFilesList.addMouseListener(listener);
    
     displayPanel.add(sp);
    
     returnCodeLabel = new JLabel("");
     returnCodeLabel.setBorder(BorderFactory.createTitledBorder("Return Code"));
     displayPanel.add(returnCodeLabel, BorderLayout.SOUTH);
    
     add(displayPanel);
    }
    
    
     public void actionPerformed(ActionEvent e)
        {
              int option = 0;
     File selectedFile = null;
     File[] selectedFiles = new File[0];
    
     if (e.getActionCommand().equals("CLOSE"))
          {
       System.exit(0);
     }
     else if (e.getActionCommand().equals("OPEN"))
            {
         JFileChooser chooser = new JFileChooser();
            chooser.setDragEnabled(true);
            chooser.setMultiSelectionEnabled(true);
         option = chooser.showOpenDialog(this);
         selectedFiles = chooser.getSelectedFiles();
       }
     else if (e.getActionCommand().equals("SAVE"))
            {
         JFileChooser chooser = new JFileChooser();
         option = chooser.showSaveDialog(this);
         selectedFiles = chooser.getSelectedFiles();
       }
    
     // display the selection and return code
     if (selectedFile != null)
       selectedFileLabel.setText(selectedFile.toString());
     else
       selectedFileLabel.setText("null");
     DefaultListModel listModel = new DefaultListModel();
     for (int i =0; i < selectedFiles.length; i++)
       listModel.addElement(selectedFiles[i]);
    
     selectedFilesList.setModel(listModel);
     returnCodeLabel.setText(Integer.toString(option));
     }
    
     public static void main(String[] args) 
        {
     SwingUtilities.invokeLater
     (new Runnable()
           {
        public void run()
             {
          FileChooserDemo app = new FileChooserDemo();
          app.initFrameContent();
          JFrame frame = new JFrame("LoquetUP");
          frame.getContentPane().add(app);
             frame.setDefaultCloseOperation(3);
             frame.setSize(600,400);
             frame.setResizable(false);
             frame.setLocationRelativeTo(null);
    
          //frame.pack();
          frame.setVisible(true);
        }
      });
     }
    
    }
    
    • Andrew Thompson
      Andrew Thompson over 11 years
      Why does this D'n'D code import nothing from the java.awt.dnd package?
    • rogerthat
      rogerthat over 11 years
      because I removed my transferHandler and mouselistener code
    • Thorn
      Thorn over 11 years
      Take a look at [this other stack overflow question][1]. I think it has some of what you're looking for. [1]: stackoverflow.com/questions/811248/…
    • rogerthat
      rogerthat over 11 years
      @Thorn is there something in java 1.7 that makes this code different?
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels over 11 years
    @healix: please don't try to post code in a comment since it remains unformatted and thus impossible to read. Instead edit your original question with an addendum, and then comment to let me know that you've done this.
  • MadProgrammer
    MadProgrammer over 11 years
    (Actually, unless it's change in Java 7, I always get java.util.List which contains File objects - I've not begin able to get generics to work for this ;))
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels over 11 years
    @MadProgrammer: you're probably correct. Let me edit my answer.
  • rogerthat
    rogerthat over 11 years
    I edited the main code and put back in my transferHandler. Its right under the JList implementation
  • rogerthat
    rogerthat over 11 years
    @Hovercraft I used a mouselistener becuase I figured the drag needs to know where to start
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels over 11 years
    @healix: have you gone through any tutorial on this? You don't need or use a MouseListener for this type of behavior, and you certainly can't guess at how to do this. Please see my Edit 2 for some sample code.
  • rogerthat
    rogerthat over 11 years
    @HovercraftFullOfEels Yeah. I went through some tutorials but most were dragging from list to list. I couldn't really find many on drag and drop files from a directory into a java application. Thanks for the code. Is it really that simple? I'm coming from a c++ b.g and I haven't yet gotten over all the built in functionality of java
  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels over 11 years
    Bookmarking this page just for this answer. Very nice, and thanks! 1+
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer Thanks. Real nice.
  • rogerthat
    rogerthat over 11 years
    Damn. I feel like in java you can almost write "Make a GUI with buttons and drag and drop functionality" and compile
  • MadProgrammer
    MadProgrammer over 11 years
    @healix it's a bit rushed, but the basic idea is sound
  • MadProgrammer
    MadProgrammer over 11 years
    @HovercraftFullOfEels been wanting to mix this with JXLayer but haven't had the time :(
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer will this example run? I would like to see it work so I can trace what is going on. This is my first drag and drop GUI. Also do you know where I can get more knowledge on DnD besides from the API?
  • MadProgrammer
    MadProgrammer over 11 years
    @healix The example will run, but unless you change the image, you won't get a "drop target" indicator...(I updated the example to allow for null images)
  • MadProgrammer
    MadProgrammer over 11 years
    @healix Sorry, I don't normally include them as it takes up room that could be used for the example. What editor are you using? ctrl+shift+I will fix the imports in Netbeans
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer I'm using Eclipse. Should be Ok. Also any advice on where to learn more about drag and drop?
  • MadProgrammer
    MadProgrammer over 11 years
    @healix You could take a look at How to drag and drop with Java 2, Part 1, which introduces the basic/core API and How to drag and drop with Java 2, Part 2, which looks like it's focused on the newer "transferable" API
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer So I've been going over your example and I have a question. What does this do? what is target.png? public DropPane() { try { //----> target = ImageIO.read(new File("target.png")); } catch (IOException ex) { ex.printStackTrace(); } Sorry in advance for pasting code. Would be easier than me trying to explain
  • MadProgrammer
    MadProgrammer over 11 years
    @Healix Basically, it loads a little png file I paint at drag location when something is dragged over the panel. It's just an example of what you might be able to do to show the drop location
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer so I can make my own image file to show the drop location? Is there one by default or if you want one you have to load one in? So then whatever I put in there would show up when the drop area in hovered? Because since I don't have target.png I just see an icon of the item being dropped
  • MadProgrammer
    MadProgrammer over 11 years
    @healix No, there isn't one by default. You can create what effect you want (I used an image to illustrate the point). JTable for example renders a fall off of the columns as you move the columns (and moves the remaining columns around it) for example
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer So "target.png" is being created in the program not loaded from your computer? I figured you had it in there for yourself but it makes more sense if its being created. Is that right?
  • rogerthat
    rogerthat over 11 years
    @MadProgrammer That last comment was wrong. target.png is being converted. I've been staring at code too long.
  • MadProgrammer
    MadProgrammer over 11 years
    @healix, Sorry, misunderstood, yes target.png is an image I'm loading from the file system, obviously you will need to supply your own. The code assumes a image size of 24x24, but it wouldn't be difficult to modify it to support variable size images
  • rogerthat
    rogerthat over 11 years
  • Mohammed Housseyn Taleb
    Mohammed Housseyn Taleb over 7 years
    even if it is against the rules: I ll say it Thank you a lot
  • Krismorte
    Krismorte over 6 years
    Awesome Example!