Java SWT拖动到资源管理器(Windows)或查找器(OS X)
我有一个SWT应用程序,其中包含一系列图形元素。我希望用户能够将元素拖动到桌面/Windows资源管理器/OS X Finder。当他们删除元素时,我需要他们删除元素的路径,以便我可以在该位置创建一个表示元素的文件 我认为我不能使用Java SWT拖动到资源管理器(Windows)或查找器(OS X),java,swt,drag-and-drop,Java,Swt,Drag And Drop,我有一个SWT应用程序,其中包含一系列图形元素。我希望用户能够将元素拖动到桌面/Windows资源管理器/OS X Finder。当他们删除元素时,我需要他们删除元素的路径,以便我可以在该位置创建一个表示元素的文件 我认为我不能使用文件传输,因为没有源文件。有一个源对象可以创建一个文件,但只有当它知道把它放在哪里时 下面内联的是我试图实现的一个简单示例,有一个带有标签的文本框可以从中拖动。如果用户拖动到某个文件夹或文件,我希望获得他们拖动到的路径。如果它们拖到一个文件中,我想用文本框中的内容替换
文件传输
,因为没有源文件。有一个源对象可以创建一个文件,但只有当它知道把它放在哪里时
下面内联的是我试图实现的一个简单示例,有一个带有标签的文本框可以从中拖动。如果用户拖动到某个文件夹或文件,我希望获得他们拖动到的路径。如果它们拖到一个文件中,我想用文本框中的内容替换该文件的内容。如果它们被拖到一个文件夹中,我想创建一个名为“TestFile”的文件,其中包含文本框中的任何内容
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class DesktopDragExample {
public static void main(String[] args) {
// put together the SWT main loop
final Display display = Display.getDefault();
display.syncExec(new Runnable() {
@Override
public void run() {
Shell shell = new Shell(display, SWT.SHELL_TRIM);
initializeGui(shell);
//open the shell
shell.open();
//run the event loop
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
});
}
// create the gui
private static void initializeGui(Composite parent) {
GridLayout layout = new GridLayout(2, false);
parent.setLayout(layout);
// make the instructions label
Label infoLbl = new Label(parent, SWT.WRAP);
GridData gd = new GridData();
gd.grabExcessHorizontalSpace = true;
gd.horizontalAlignment = SWT.FILL;
gd.horizontalSpan = 2;
infoLbl.setLayoutData(gd);
infoLbl.setText(
"You should be able to drag to the desktop, Windows Explorer, or OS X Finder.\n" +
"If you drag to a file, it will replace the contents of that file with the contents of the text box.\n" +
"If you drag to a folder, it will create a file named 'TestFile' whose contents are whatever is in the text box.");
// make the text element
final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
gd = new GridData();
gd.grabExcessHorizontalSpace = true;
gd.horizontalAlignment = SWT.FILL;
text.setLayoutData(gd);
// make the label element
Label label = new Label(parent, SWT.NONE);
label.setText("Drag me");
// listener for drags
DragSourceListener dragListener = new DragSourceListener() {
@Override
public void dragStart(DragSourceEvent e) {
e.detail = DND.DROP_COPY;
}
@Override
public void dragFinished(DragSourceEvent e) {
System.out.println("--dragFinished--");
System.out.println("e.data=" + e.data);
}
@Override
public void dragSetData(DragSourceEvent e) {
System.out.println("--dragSetData--");
System.out.println("e.data=" + e.data);
}
};
// the DragSource
DragSource dragSource = new DragSource(label, DND.DROP_COPY);
dragSource.setTransfer(new Transfer[]{FileTransfer.getInstance()});
dragSource.addDragListener(dragListener);
}
private static void draggedTo(String path, String textBoxContents) {
System.out.println("Dragged the contents '" + textBoxContents + "' to '" + path + "'");
}
}
以下是一些其他人也有同样的问题,但目前似乎没有解决方案:
,执行此操作的唯一方法是创建一个临时文件,然后使用FileTransfer。我怀疑这就是您在本机代码中必须做的事情。我会看看我是否有足够的时间来绘制样本…您没有从中获取文件位置,也没有自己编写文件。拖动到桌面意味着文件传输(您可以检查dragSetData中支持的传输类型) 这意味着SWT在DragSourceEvent.data中需要文件路径的字符串[]。如果您在dragSetData方法中设置此选项,则SWT会将这些文件复制到您的放置目标,例如桌面
@Override
public void dragSetData(DragSourceEvent e) {
System.out.println("--dragSetData--");
System.out.println("Is supported: " + FileTransfer.getInstance().isSupportedType(e.dataType));
FileTransfer f = FileTransfer.getInstance();
String[] filePaths = {"C:\\CamelOut\\4.xml" } ;
e.data = filePaths;
}
};
如果创建临时文件的成本很高,那该怎么办?例如,假设正在拖动的对象是速度较慢的FTP服务器上的1GB文件。如果我可以创建一个临时文件,在DragStart中开始写入,然后即使在开始拖动之后也继续写入,那么这可能会起作用。。。但是我真的很想自己控制拷贝:例如,如果用户决定取消,我想知道,这样我就可以停止写入临时文件。@NedTwigg我很确定你可以在Linux/Mac上使用管道(不熟悉Windows)-但这可能需要本机代码。看起来Windows的命名管道可以完成这项工作:这对于拖动文件的情况非常有用。但是,如果您想在目标位置创建文件夹,仍然存在一个问题(我不相信您可以通过管道创建文件夹…)。我会尝试思考管道的想法是否有助于“跟踪”的想法(也许有特定于平台的方法来查找打开的管道,这可能使跟踪想法可行?)。如果您查看archiver 7-zip,请注意,如果您将文件从7-zip拖放到windows资源管理器,它会将其解压缩到临时文件,然后将其复制过来。7-zip是Windows自带的,所以我认为您可能必须这样做。