我想创建一个从 JList 到操作系统的免打扰操作。我现在的解决方案是使用 TransferHandler。在 createTransferable 方法中,我使用要复制的文件创建了 Transferable。
但现在我的问题是:在某些情况下,我必须先从 FTP 服务器下载文件,然后才能复制文件。非常繁重的下载操作在 JavaSwingWorker 中运行(隐藏在语句 d.download(tmpDir); 后面)。现在系统尝试复制尚未下载的文件。
现在我需要一种机制,允许我在下载文件后创建可转让文件。我的问题有解决方案吗?请帮助我!
谢谢!
这是我的方法:
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;
}
我需要一些东西来启动拖动过程,然后我得到拖动的路径,然后我可以下载图片并将其复制到目标路径。
编辑:或另一种表述:当我放入操作系统时如何找到放置目的地?
最佳答案
要开始拖动,您需要 JList
上的 TransferHandler
或者 DragSource
结合 DragGestureListener
。您可以在下面看到使用 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
并且您应该返回 List
的 File
来自 getTransferData(DataFlavor flavor)
方法。
我相信这也是应该进行下载的方法,因为这是 JVM-OS 接管之前您可以控制的最后一点。
现在关于 SwingWorker
问题,您可以在方法内等待,直到下载完成。也许修改您的 Downloader
类以公开一个 boolean 标志,这样您就可以执行类似 while (!downloader.isDone()) { Thread.sleep(millisToSleep) };
[编辑:我必须承认我不喜欢让 EventDispath 线程保持忙碌的想法,但如果这能解决您当前的问题,也许您可以稍后研究更优雅的解决方案]
一点警告:由于您无权访问放置位置,因此您无法知道 getTransferData
将被调用多少次。最好考虑到这一点,并使用目前下载的临时文件创建一个简单的缓存(Map
听起来很合理)。如果您在缓存中找到该文件,您会直接返回其对应的临时文件,而不会再次下载。
希望对你有帮助
关于java - 使用 Swing Worker 拖放 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17763336/