为啥我不能将文件从 Windows 中的 CD 拖放到 Eclipse / SWT Drop Target
Posted
技术标签:
【中文标题】为啥我不能将文件从 Windows 中的 CD 拖放到 Eclipse / SWT Drop Target【英文标题】:Why can't I drop files on to Eclipse / SWT Drop Target from a CD in windows为什么我不能将文件从 Windows 中的 CD 拖放到 Eclipse / SWT Drop Target 【发布时间】:2012-10-06 10:50:26 【问题描述】:在我的 Eclipse RCP 应用程序中,我有一个 TreeViewer,它是文件的放置目标,它在大多数情况下都可以正常工作,但是当我尝试将存储在 CD ROM 上的文件从 Windows 资源管理器拖动到节点时,指示放置的图标are allowed 不会改变,而 drop 什么都不做。
由于人们似乎对我的问题感到困惑,这里有一个更详细的解释:
执行下面的代码(由 Baz 提供)时,我可以将文件拖放到文本框中,当我从机器上的大多数位置拖动文件时,窗口显示如下 ->
光标表示我可以放下,当我松开鼠标时会调用drop(DropTargetEvent event)
方法。
现在,当我做同样的事情,但从资源管理器中获取一个位于我的光驱 DVD 上的文件时,它看起来像这样:
表示不允许放置,当我释放鼠标时,drop(DropTargetEvent event)
方法不会被调用。
还值得注意的是,我可以将相同的 DVD 文件放入 eclipse 导航器中的文件夹中,这表明这不是特定于机器的问题,在 eclipse 树中一定有不同的东西允许它但是我看不到。
package widgets;
import java.util.Arrays;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.PluginTransfer;
public class SourceTest
public static void main(String[] args)
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1,false));
final Text text = new Text(shell, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
DropTarget dt = new DropTarget(text, DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK);
dt.setTransfer(new Transfer[] FileTransfer.getInstance(), PluginTransfer.getInstance() );
dt.addDropListener(new DropTargetAdapter()
public void drop(DropTargetEvent event)
String fileList[] = null;
FileTransfer ft = FileTransfer.getInstance();
if (ft.isSupportedType(event.currentDataType))
fileList = (String[]) event.data;
System.out.println(Arrays.toString(fileList));
);
shell.setSize(300, 100);
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
【问题讨论】:
您是否检查过validateDrop
方法中的transferType
是否与从HDD 删除时的不同?
它们是 TransferData 对象,在结构上似乎没有任何重大差异,但对于 ROM 文件,操作似乎始终为 16,而对于工作的文件,操作结束时变为 2一个节点,如果不是,则为 16,这向我表明该节点没有注册为被拖动对象的可行目标。对 validateDrop 的调用是很奇怪的,即使它实际上并没有允许您执行它的意图。
基于名称 **validate**Drop()
这是有道理的。会研究一下。也许我会找到解决办法。
这个名字听起来好像应该被删除,但在这种情况下,即使它返回 true,框架也不会尝试执行删除,因为它已经确定目标无效。提前感谢您的时间 Baz
【参考方案1】:
当来自 CDROM 设备时,似乎并非所有可能的 DND 操作都受支持。因此,您需要在 DropTargetAdapter
上实现更多方法,以便在进行中修改 Drop 操作以缩小实际执行的操作范围,以便操作系统不会阻止 drop。
我以你的例子为例,只是对DropTargetAdapter
做了一点小改动
@Override
public void dropAccept( DropTargetEvent event )
Object object = FileTransfer.getInstance().nativeToJava( event.currentDataType );
if( object instanceof String[] )
String[] strs = (String[]) object;
System.out.println("dropAccept " + strs[0]);
event.detail = DND.DROP_COPY;
event.detail = DND.DROP_COPY;
@Override
public void dragEnter( DropTargetEvent event )
event.detail = DND.DROP_COPY;
【讨论】:
我的好伙计做得很好。所以本质上覆盖细节总是看起来好像它是一个副本?这不会导致其他事件类型出现奇怪的行为吗? 因此您可以添加一些代码以便在“修改”此事件时更有选择性。我将在我的答案中添加一些代码,以显示您如何“嗅探”将要删除的内容的位置,并确定何时修改以及何时不理会。span> 谢谢,我看看能否在 Eclipse 树中找到等价物。【参考方案2】:我认为更新你的问题澄清了问题是什么。
您的放置目标使用DND_MOVE
作为标志。
由于我们无法删除 DVD 等只读媒体中的文件,
无论接收者的决定是否正确,发送者(在本例中为 OS 的 shell)都会拒绝 DND 通信。
您的屏幕截图显示正在移动 DND 反馈不是复制。
dropAccept()
给你最后一次修改通讯请求的机会,
请谨慎使用,因为每个传输类型可以存在多个放置目标侦听器。为了支持这种情况,TreeViewer 的 DND API 与 SWT 的略有不同。
【讨论】:
【参考方案3】:DND 并不像你想象的那样工作。
考虑从网络下载一些文件。 当您验证下载时,没有实际的文件内容,但您有一个网络资源的唯一 URL。
同样,当您验证 drop 操作时,您无法知道实际数据,因为在您接受 drop 操作之前,没有 没有建立连接。在验证阶段您唯一能知道的是传输类型。
因此,您只能根据内容类型验证 drop,而不是“实际内容”
典型的验证码是:
public boolean validateDrop(...)
return FileTransfer.getInstance().isSupportedType(transferData);
在您接受“TransferData”后,传输将从连接中检索实际数据。
所以请记住,“TransferData”与实际数据不同。
FileTransfer
以 String
数组的形式检索文件,其中包含每个文件的绝对路径,而不是 Java File
对象。
P.S.:剪贴板的工作方式相同。
【讨论】:
谢谢我知道这一切。那你建议问题的答案是什么? 我自己对此投了反对票,这肯定是一个详细的信息,但它不是答案,jeeyul 认为我不明白如何使用拖放,只是希望文件能够自动移动。事实并非如此。以上是关于为啥我不能将文件从 Windows 中的 CD 拖放到 Eclipse / SWT Drop Target的主要内容,如果未能解决你的问题,请参考以下文章
我虚拟机里面装了ubuntu的desktop版本,请问为啥我windows里的文件拖不进去虚拟机?
VMware tools 安装成功后,文件可以从虚拟机拖出去,但是拖不进来,为啥?
为啥图片拖不进对话框,拖的话,会从网页上打开,复制粘贴都没用