简体   繁体   English

使用Swing Worker拖放Java

[英]Drag and Drop Java with Swing Worker

I want to create a DND action from a JList to the OS. 我想创建一个从JList到操作系统的DND操作。 My solution for now is to use a TransferHandler. 我现在的解决方案是使用TransferHandler。 In the method createTransferable I create the Transferable with the files I want to copy. 在createTransferable方法中,我使用要复制的文件创建Transferable。
But now there is my Problem: in some cases I have to download the files from a FTP-Server before I can copy the files. 但现在有我的问题:在某些情况下,我必须先从FTP服务器下载文件,然后才能复制文件。 The very heavy download operation runs in a JavaSwingWorker ( hidden behind the statement d.download(tmpDir); ). 非常繁重的下载操作在JavaSwingWorker中运行( 隐藏在语句d.download(tmpDir);后面 Now the system trys to copy files which are not downloaded already. 现在,系统尝试复制尚未下载的文件。

Now i need a mechanism that allows me to create the transferable after I have downloaded the files. 现在我需要一种机制,允许我下载文件创建transferable。 Is there a solution for my problem? 我的问题有解决方案吗? Please help me! 请帮我!

Thanks! 谢谢!

Here is my method: 这是我的方法:

public Transferable createTransferable(JComponent c) {
    JList list = (JList) c; // we know it's a JList
    List<PictureDecorator> selectedPictures = getSelectedValues(list.getModel());
    Vector cpFiles = new Vector();

    List<Picture> donePictures = new ArrayList<Picture>();
    List<Picture> notDonePictures = new ArrayList<Picture>();
    String tmpDir = System.getProperty("java.io.tmpdir");

    for(PictureDecorator pd : selectedPictures){
        if(pd.getPic().getStatus() == PictureStatus.DONE)
            donePictures.add(pd.getPic());
        else
            notDonePictures.add(pd.getPic());
    }

    Downloader d = new Downloader(parent, loginInformation, sced, donePictures, order);

    d.download(tmpDir);

    for(Picture p : donePictures){
        cpFiles.add(new File(tmpDir + File.separator + p.getPicture().getName()));
    }

    for(Picture p : notDonePictures) {
        cpFiles.add(p.getPicture());
    }

    TransferableFile tf = new TransferableFile(cpFiles);
    return tf;
}

I need something that initiates the drag procedure then I get the path where the drag goes and then I can download the pictures and copy it to the destination path. 我需要启动拖动过程的东西然后我得到拖动的路径,然后我可以下载图片并将其复制到目标路径。

EDIT: Or another formulation: How I can find out the drop destination when I drop into the operating system? 编辑:或另一种表述:当我进入操作系统时,如何找到丢弃目的地?

To start the drag you need either a TransferHandler on the JList or alternatively a DragSource in combination with a DragGestureListener . 要开始拖动,您需要在JList上使用TransferHandler ,或者将DragSourceDragGestureListener结合使用。 Below you can see an example for doing that with a JTextField : 您可以在下面看到使用JTextField执行此操作的示例:

final JTextField textField = new JTextField(50);
DragGestureListener dragListener = new DragGestureListener() {
    @Override
    public void dragGestureRecognized(DragGestureEvent dge) {
        // how the drag cursor should look like
        Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);

        // the component being dragged
        JTextField tf = (JTextField) dge.getComponent();

        // Here a Transferable is created directly for a single file name
        dge.startDrag(cursor, new TransferableFile(tf.getText()));
    }
};

final DragSource ds = new DragSource();
ds.createDefaultDragGestureRecognizer(textField, DnDConstants.ACTION_COPY, dragListener);

You can put the above code inside your window creation procedure. 您可以将上面的代码放在窗口创建过程中。

Your resulting transferable ( TransferableFile in your case) should support the DataFlavor.javaFileListFlavor and you should return a List of File s from the getTransferData(DataFlavor flavor) method. 您生成的transferable(在您的情况下为TransferableFile )应该支持DataFlavor.javaFileListFlavor ,您应该从getTransferData(DataFlavor flavor)方法返回一个List of File

I believe this is also the method where the downloading should take place because that's the last point under your control before JVM-OS take over. 我相信这也是下载应该发生的方法,因为这是JVM-OS接管之前你控制的最后一点。

Now regarding the SwingWorker problem you can wait inside the method until the download completes. 现在关于SwingWorker问题,您可以在方法内等待,直到下载完成。 Perhaps modify your Downloader class to expose a boolean flag so you would be able to do something like while (!downloader.isDone()) { Thread.sleep(millisToSleep) }; 也许修改你的Downloader类来暴露一个布尔标志,这样你就可以做像while (!downloader.isDone()) { Thread.sleep(millisToSleep) };

[Edit: I must admit I don't like the idea of keeping the EventDispath thread busy but if this solves your current problem perhaps you can investigate later a more elegant solution] [编辑:我必须承认我不喜欢保持EventDispath线程忙的想法,但如果这解决了你当前的问题,也许你可以稍后调查一个更优雅的解决方案]

A little warning: Since you don't have access to the drop location you cannot know how many times the getTransferData will be called. 一点警告:由于您无法访问放置位置,因此您无法知道将调用getTransferData次数。 It is better to take this into account and create a simple cache (a Map sounds reasonable) with the temp files you have downloaded so far. 最好将此考虑在内,并使用目前已下载的临时文件创建一个简单的缓存( Map听起来合理)。 In case you find the file in the cache you return its corresponding temp file directly and don't download it again. 如果您在缓存中找到该文件,则直接返回其对应的临时文件,不要再次下载。

Hope that helps 希望有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM