[英]How can I use Drag-and-Drop in Swing to get file path?
I have a JTextField
in my Swing application that holds the file path of a file selected to be used.我的Swing应用程序中有一个JTextField
,用于保存选择使用的文件的文件路径。 Currently I have a JFileChooser
that is used to populate this value.目前我有一个用于填充此值的JFileChooser
。 However, I would like to add the ability for a user to drag-and-drop a file onto this JTextField
and have it place the file path of that file into the JTextField
instead of always having using the JFileChooser
.但是,我想为用户添加将文件拖放到此JTextField
上的功能,并将该文件的文件路径放入JTextField
而不是始终使用JFileChooser
。
How can this be done?如何才能做到这一点?
In case you don't want to spend too much time researching this relatively complex subject, and you're on Java 7 or later, here's a quick example of how to accept dropped files with a JTextArea
as a drop target:如果您不想花太多时间研究这个相对复杂的主题,并且您使用的是 Java 7 或更高版本,这里有一个快速示例,说明如何接受以JTextArea
作为放置目标的放置文件:
JTextArea myPanel = new JTextArea();
myPanel.setDropTarget(new DropTarget() {
public synchronized void drop(DropTargetDropEvent evt) {
try {
evt.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>)
evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
for (File file : droppedFiles) {
// process files
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
First you should look into Swing DragDrop support .首先,您应该查看Swing DragDrop 支持。 After that there are few little tricks for different operating systems.之后,针对不同操作系统的一些小技巧。 Once you've got things going you'll be handling the drop() callback.一旦事情进展顺利,您将处理 drop() 回调。 In this callback you'll want to check the DataFlavor of the Transferable.在此回调中,您需要检查 Transferable 的 DataFlavor。
For Windows you can just check the DataFlavor.isFlavorJavaFileListType() and then get your data like this对于 Windows,您只需检查DataFlavor.isFlavorJavaFileListType()然后像这样获取数据
List<File> dropppedFiles = (List<File>)transferable.getTransferData(DataFlavor.javaFileListFlavor)
For Linux (and probably Solaris) the DataFlavor is a little trickier.对于 Linux(可能还有 Solaris),DataFlavor 有点棘手。 You'll need to make your own DataFlavor and the Transferable type will be different您需要制作自己的 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
....
}
}
There is an example program which contains a class which can be used for facilitating drag and drop for files and folders:有一个示例程序,其中包含一个类,可用于促进文件和文件夹的拖放:
http://www.iharder.net/current/java/filedrop/ http://www.iharder.net/current/java/filedrop/
I tested this with both Windows 7 and Ubuntu 10.10, and it appears to work well in both environments.我在 Windows 7 和 Ubuntu 10.10 上对此进行了测试,它似乎在两种环境中都运行良好。
To use it, you add something like this to your code:要使用它,您可以在代码中添加如下内容:
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
I know this is an old question but the current answers are all a bit outdated:我知道这是一个老问题,但目前的答案都有些过时:
This works on Linux (KDE5) and Windows 7:这适用于 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;
List<File> files;
try {
files = (List<File>) 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;
}
}
Use it on any component with在任何组件上使用它
myComponent.setTransferHandler(new FileDropHandler());
This works for me.这对我有用。 I am using it like this (scala):我像这样使用它(scala):
def onDrop(files: List[java.io.File]): Unit = { ... }
val lblDrop = new Label {
peer.setTransferHandler(new FileDropHandler(onDrop))
border = EtchedBorder
}
class FileDropHandler(val onDrop: List[java.io.File] => Unit) extends javax.swing.TransferHandler {
import javax.swing.JComponent
import java.awt.datatransfer.{Transferable, DataFlavor}
import java.net.URI
import java.io.File
val stdFileListFlavor = DataFlavor.javaFileListFlavor
val nixFileListFlavor = new DataFlavor("text/uri-list;class=java.lang.String")
override def canImport(comp: JComponent, flavors: Array[DataFlavor]): Boolean =
flavors.exists(flavor =>
(flavor == stdFileListFlavor) ||
(flavor == nixFileListFlavor)
)
override def importData(comp: JComponent, t: Transferable): Boolean = {
val flavors = t.getTransferDataFlavors()
val files = if (flavors.exists(_ == stdFileListFlavor)) {
val data = t.getTransferData(stdFileListFlavor)
importStdFileList( data )
} else if (flavors.exists(_ == nixFileListFlavor)) {
val data = t.getTransferData(nixFileListFlavor)
importNixFileList( data )
} else List()
onDrop( files )
!files.isEmpty
}
private def importStdFileList(data: Any): List[File] = {
data.asInstanceOf[List[File]] //XXX NOT TESTED
}
private def importNixFileList(data: Any): List[File] = {
def clean(rawLine: String): Option[String] = {
val line = rawLine.trim
if (line.length == 0 || line == "#") None
else Some(line)
}
def asURI(line: String): Option[URI] = {
try { Some(new URI(line)) }
catch { case e:Exception => println(e); None }
}
def asFile(uri: URI): Option[File] = {
try { Some(new File(uri)) }
catch { case e:Exception => println(e); None }
}
data.asInstanceOf[java.lang.String].split("\n")
.toList flatMap clean flatMap asURI flatMap asFile
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.