2013-07-20 50 views
3

我想从JList创建DND操作到操作系统。现在我的解决方案是使用TransferHandler。在createTransferable方法中,我使用我想要复制的文件创建Transferable。
但现在我的问题是:在某些情况下,我必须从FTP服务器下载文件,然后才能复制这些文件。非常繁重的下载操作在JavaSwingWorker(隐藏在语句d.download(tmpDir);)后面运行。现在系统尝试复制尚未下载的文件。

使用Swing Worker拖放Java

现在我需要一个机制,允许我在之后创建可转移的我已经下载了这些文件。有没有解决我的问题?请帮帮我!

谢谢!

这里是我的方法:

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; 
} 

我需要的东西,开始拖动程序然后我得到的路径是拖动去,然后我可以下载的图片,并将其复制到目标路径。

编辑:或另一个公式:当我放入操作系统时如何找到放置目标?

+0

目前还不清楚你在做什么。为什么在DnD期间执行如此繁重的操作?您只需要传输要下载的信息即文件名称的一组字符串。当下降结束时,决定什么文件,然后开始下载 –

+0

感谢您的答案,但我试图将文件放到操作系统而不是我的程序的另一个控制!我怎么才能找出用户放置文件的位置? – badhazelnoot

+0

我的歉意。我完全错过了OS部分。虽然我不确定这是否是要等待任务完成的方式。 'while(!d.isDone()){Thread.sleep(...)}'? –

回答

1

要开始拖动,您需要JList上的TransferHandlerDragSourceDragGestureListener的组合。下面你可以看到这样做有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); 

你可以把上面的代码你的窗口创建过程中。

,您的最终转让(在你的情况TransferableFile)应支持DataFlavor.javaFileListFlavor,你应该从getTransferData(DataFlavor flavor)方法返回FileList秒。

我相信这也是下载应该发生的方法,因为这是JVM-OS接管之前的最后一点。

现在关于SwingWorker问题,您可以在该方法内部等待,直到下载完成。也许修改Downloader类暴露一个布尔标记,这样你就可以像做while (!downloader.isDone()) { Thread.sleep(millisToSleep) };

[编辑:我必须承认,我不喜欢保持EventDispath线程繁忙的想法,但是否能解决当前的问题也许你可以稍后调查一个更优雅的解决方案]

有点警告:由于您无权访问放置位置,因此无法知道getTransferData将被调用多少次。最好考虑到这一点,并使用到目前为止已下载的临时文件创建一个简单的缓存(Map听起来合理)。如果您在缓存中找到该文件,则直接返回其相应的临时文件,并且不要再次下载它。

希望可以帮到