我的swing应用程序中有一个JTextField,它包含选择使用的文件的文件路径.目前我有一个JFileChooser用于填充此值.但是,我想为用户添加将文件拖放到此JTextField上的功能,并让它将该文件的文件路径放入JTextField,而不是始终使用JFileChooser.
如何才能做到这一点?
首先,您应该查看Swing DragDrop支持.之后,不同的操作系统几乎没有什么小技巧.一旦你有了事情,你将处理drop()回调.在此回调中,您将要检查Transferable的DataFlavor.
对于Windows,您只需检查DataFlavor.isFlavorJavaFileListType()然后获取这样的数据
ListdropppedFiles = (List )transferable.getTransferData(DataFlavor.javaFileListFlavor)
对于Linux(可能还有Solaris),DataFlavor有点棘手.您需要创建自己的DataFlavor,Transferable类型将不同
nixFileDataFlavor = new DataFlavor("text/uri-list;class=java.lang.String"); String data = (String)transferable.getTransferData(nixFileDataFlavor); for(StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens();) { String token = st.nextToken().trim(); if(token.startsWith("#") || token.isEmpty()) { // comment line, by RFC 2483 continue; } try { File file = new File(new URI(token)) // store this somewhere } catch(...) { // do something good .... } }
有一个示例程序,其中包含一个类,可用于促进文件和文件夹的拖放:
http://www.iharder.net/current/java/filedrop/
我用Windows 7和Ubuntu 10.10测试了它,它似乎在两种环境中都能很好地工作.
要使用它,您可以在代码中添加以下内容:
JPanel myPanel = new JPanel(); new FileDrop( myPanel, new FileDrop.Listener() { public void filesDropped( java.io.File[] files ) { // handle file drop ... } // end filesDropped }); // end FileDrop.Listener
如果您不想花太多时间研究这个相对复杂的主题,并且您使用的是Windows(或使用Java 7或更高版本),这里有一个关于如何使用JTextArea作为放置目标接受删除文件的快速示例:
JTextArea myPanel = new JTextArea(); myPanel.setDropTarget(new DropTarget() { public synchronized void drop(DropTargetDropEvent evt) { try { evt.acceptDrop(DnDConstants.ACTION_COPY); ListdroppedFiles = (List ) evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); for (File file : droppedFiles) { // process files } } catch (Exception ex) { ex.printStackTrace(); } } });
我知道这是一个老问题,但目前的答案都有点过时了:
从JDK 1.6开始,类"TransferHandler"应该与新的(覆盖的)方法一起使用
对Linux的支持变得更好,不需要自定义处理
这适用于Linux(KDE5)和Windows 7:
final class FileDropHandler extends TransferHandler { @Override public boolean canImport(TransferHandler.TransferSupport support) { for (DataFlavor flavor : support.getDataFlavors()) { if (flavor.isFlavorJavaFileListType()) { return true; } } return false; } @Override @SuppressWarnings("unchecked") public boolean importData(TransferHandler.TransferSupport support) { if (!this.canImport(support)) return false; Listfiles; try { files = (List ) support.getTransferable() .getTransferData(DataFlavor.javaFileListFlavor); } catch (UnsupportedFlavorException | IOException ex) { // should never happen (or JDK is buggy) return false; } for (File file: files) { // do something... } return true; } }
在任何组件上使用它
myComponent.setTransferHandler(new FileDropHandler());