9

我想实现从某个目录(例如某人的硬盘驱动器)拖放文件,但不知道该怎么做。我已经阅读了 java api,但它谈到了颜色选择器和列表之间的拖放,以及如何从计算机文件系统中拖动文件并放入我的应用程序中。我尝试为拖动开始时编写 transferhandler 类和鼠标事件,但似乎没有任何效果。现在我回到只设置我的 JFileChooser 以便启用拖动但如何放下?

非常感谢任何信息或指向正确方向的信息。

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

}
4

2 回答 2

24

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();
            }
        }

    }
}
于 2012-11-28T04:05:26.457 回答
8

您需要尝试拖放,并在尝试拖动文件时准确查看可用的风格。如果您在自定义 TransferHandler 中执行此操作,您会惊喜地发现 Flavor 是DataFlavor.javaFileListFlavor,这表明该项目可以简单地用作List. 试试看,你会发现它有效!

请注意查看您发布的代码,我没有看到您尝试使用 TransferHandler 的任何代码,因此很难说您在这里可能做错了什么。

编辑 1
您似乎正在尝试使用 MouseListener 进行拖放,我不熟悉这种用法。你能参考一个告诉你这样做的教程吗?

编辑 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;
      }
   }
}
于 2012-11-28T03:29:53.767 回答