为什么拖放大文件需要时间?
Why is drag and drop taking time on huge files?
我创建了一个 java 程序,该程序通过接受拖放的文件来工作。
每当我拖动小文件时,它都会起作用。但是当我将大文件拖到 100MB 以上时,它会挂起直到完成文件处理。
我正在使用装有 macOS High Sierra 的 Macbook。
public ArrayList result() {
TransferHandler th;
th = new TransferHandler() {
@Override
public boolean canImport(JComponent comp, DataFlavor[] transfarFlavors) {
return true;
}
@Override
public boolean importData(JComponent comp, Transferable t) {
try {
List<File> files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
files.forEach((File file) -> {
String fName = file.getName();
String fPath = file.getAbsolutePath();
//I even added animation to show when the file is dropped, since small files are executed fast the animation doesn't show, but large files hang so no animation too.
ImageIcon loadPage = new ImageIcon(new ImageIcon("/Users/me/Pictures/hit.gif").getImage());
loadingImage.setIcon(loadPage);
Processor starts = new Processor();
try {
result = starts.getFile(fPath, fName);
setResult(result());
//fileNameText.setOpaque(true);
} catch (IOException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
});
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
};
DnD.setTransferHandler(th);
return result;
}
要解决被阻止的 EDT 问题,您可以使用 javax.swing.SwingWorker
。
您的代码对于 Processor.getFile()
的结果是什么以及该结果会发生什么非常模糊,因此我只能对 SwingWorker 中的结果处理提出基本建议。
public ArrayList<Object> result() {
TransferHandler th;
th = new TransferHandler() {
@Override
public boolean canImport(JComponent comp, DataFlavor[] transfarFlavors) {
return true;
}
@Override
public boolean importData(JComponent comp, Transferable t) {
try {
ImageIcon loadPage = new ImageIcon(new ImageIcon("/Users/me/Pictures/hit.gif").getImage());
loadingImage.setIcon(loadPage);
List<File> files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
FileWorker fw = new FileWorker(files);
fw.execute();
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
};
DnD.setTransferHandler(th);
return null;
}
private static class FileWorker extends SwingWorker<Object, Object> {
private final List<File> files;
public FileWorker(List<File> files) {
this.files = files;
}
@Override
protected List<Object> doInBackground() throws Exception {
List<Object> results = new ArrayList<>();
files.forEach((File file) -> {
String fName = file.getName();
String fPath = file.getAbsolutePath();
Processor starts = new Processor();
try {
Object result = starts.getFile(fPath, fName);
results.add(result);
publish(result);
} catch (IOException | InterruptedException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
});
return results;
}
@Override
protected void process(List<Object> chunks) {
// here you could update UI elements with some intermediate results
}
@Override
protected void done() {
// here you could update UI elements with the final results
}
}
我创建了一个 java 程序,该程序通过接受拖放的文件来工作。 每当我拖动小文件时,它都会起作用。但是当我将大文件拖到 100MB 以上时,它会挂起直到完成文件处理。 我正在使用装有 macOS High Sierra 的 Macbook。
public ArrayList result() {
TransferHandler th;
th = new TransferHandler() {
@Override
public boolean canImport(JComponent comp, DataFlavor[] transfarFlavors) {
return true;
}
@Override
public boolean importData(JComponent comp, Transferable t) {
try {
List<File> files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
files.forEach((File file) -> {
String fName = file.getName();
String fPath = file.getAbsolutePath();
//I even added animation to show when the file is dropped, since small files are executed fast the animation doesn't show, but large files hang so no animation too.
ImageIcon loadPage = new ImageIcon(new ImageIcon("/Users/me/Pictures/hit.gif").getImage());
loadingImage.setIcon(loadPage);
Processor starts = new Processor();
try {
result = starts.getFile(fPath, fName);
setResult(result());
//fileNameText.setOpaque(true);
} catch (IOException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
});
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
};
DnD.setTransferHandler(th);
return result;
}
要解决被阻止的 EDT 问题,您可以使用 javax.swing.SwingWorker
。
您的代码对于 Processor.getFile()
的结果是什么以及该结果会发生什么非常模糊,因此我只能对 SwingWorker 中的结果处理提出基本建议。
public ArrayList<Object> result() {
TransferHandler th;
th = new TransferHandler() {
@Override
public boolean canImport(JComponent comp, DataFlavor[] transfarFlavors) {
return true;
}
@Override
public boolean importData(JComponent comp, Transferable t) {
try {
ImageIcon loadPage = new ImageIcon(new ImageIcon("/Users/me/Pictures/hit.gif").getImage());
loadingImage.setIcon(loadPage);
List<File> files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
FileWorker fw = new FileWorker(files);
fw.execute();
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
};
DnD.setTransferHandler(th);
return null;
}
private static class FileWorker extends SwingWorker<Object, Object> {
private final List<File> files;
public FileWorker(List<File> files) {
this.files = files;
}
@Override
protected List<Object> doInBackground() throws Exception {
List<Object> results = new ArrayList<>();
files.forEach((File file) -> {
String fName = file.getName();
String fPath = file.getAbsolutePath();
Processor starts = new Processor();
try {
Object result = starts.getFile(fPath, fName);
results.add(result);
publish(result);
} catch (IOException | InterruptedException ex) {
Logger.getLogger(DragnDrop.class.getName()).log(Level.SEVERE, null, ex);
}
});
return results;
}
@Override
protected void process(List<Object> chunks) {
// here you could update UI elements with some intermediate results
}
@Override
protected void done() {
// here you could update UI elements with the final results
}
}