【问题标题】:SWT Drag to Explorer (Windows) or Finder (OS X)SWT 拖动到资源管理器 (Windows) 或 Finder (OS X)
【发布时间】:2013-04-26 22:40:33
【问题描述】:

我有一个带有一堆图形元素的 SWT 应用程序。我希望用户能够将元素拖到他们的桌面/Windows 资源管理器/OS X Finder。当他们删除元素时,我需要他们将其删除到的路径,以便我可以在该位置创建一个代表该元素的文件。

我认为我不能使用FileTransfer,因为没有源文件。有一个源对象可以创建一个文件,但只有在它知道将它放在哪里时。

下面的内联是我想要实现的一个简单示例,有一个带有标签的文本框可供拖动。如果用户拖动到某个文件夹或文件,我想获取他们拖动到的路径。如果他们拖到一个文件,我想用文本框中的任何内容替换该文件的内容。如果他们拖到一个文件夹,我想创建一个名为“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 + "'");
}

}

这里有一些其他人也有同样的问题,但目前看来还没有解决方案: Drag from SWT to Desktop, ..want destination path as String

【问题讨论】:

    标签: java swt drag-and-drop


    【解决方案1】:

    唯一的方法是创建一个临时文件,然后使用 FileTransfer。我怀疑这就是你必须在本机代码中做的事情。我会看看我是否有足够的时间来绘制样本......

    【讨论】:

    • 创建临时文件开销大的情况怎么办?例如,假设被拖动的对象是慢速 FTP 服务器上的 1GB 文件。如果我可以创建一个临时文件,在 DragStart 中开始写入,然后在拖动开始后继续写入,那么这可能会起作用......但我真的希望能够自己控制副本:例如如果用户决定取消,我想知道这样我就可以停止写入临时文件。
    • @NedTwigg 我很确定你可以在 Linux/Mac 上使用管道(不熟悉 Windows)——但这可能需要本机代码。
    • 看起来 Windows 的命名管道可以完成这项工作:en.wikipedia.org/wiki/Named_pipe 这对于拖动文件的情况非常有用。但是,如果您想在目的地创建文件夹,仍然存在问题(我不相信您可以通过管道创建文件夹......)。我会尝试考虑管道的想法是否可以帮助实现“跟踪”的想法(也许有特定于平台的方法可以找到开放的管道,这可能会使跟踪的想法可行?)。
    • 如果您查看存档器 7-zip,请注意,如果您将文件从 7-zip 拖放到 Windows 资源管理器,它会将其解压缩到临时文件,然后将其复制. 7-zip 是 Windows 原生的,所以我认为您可能必须这样做。
    【解决方案2】:

    您不会自己获取文件位置并自己编写文件。拖动到桌面意味着 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; 
            }
        };
    

    【讨论】:

      猜你喜欢
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多