我有一个javafx应用程序,用于签署用户上传的文件。它分别显示这些文件的名称。
问题是,要在屏幕上显示文件,它会等待所有文件都被签名。签署所有文件后,突然显示所有文件。
以下gif显示当前状态:
但我想以不同的方式展示它们。因此,在开始签名过程之前,每个文件都应该等待显示以前的文件。这就像一次显示一个元素(但不使用setInterval或setTimeout)。换句话说,我想让Java和Javascript相互通信。
我在java端使用for循环。在这个for循环中,我调用javascript函数在div中显示文件名。
Java代码:
List<String> files = new ArrayList<String>();
for ( Iterator<File> iterator = fWrapper.getFiles().iterator(); iterator.hasNext(); ) {
File unsignedFile = iterator.next();
String targetFileStr = targetPath + "/" + unsignedFile.getName();
File signedFile = signer.signUDF(unsignedFile);
files.add(targetFileStr);
signedFile.renameTo(new File(targetFileStr));
Browser.webEngine.executeScript("signedSuccessfully('" + unsignedFile.getName() + " is signed.')"
}
和Javascript代码:
function signedSuccessfully(msg) {
$("#statusText").append('<br><span style="color:green"> - ' + msg + '</span>');
}
有没有人能给我一些关于我该怎么做的建议?
提前谢谢。
答案 0 :(得分:0)
在后台线程中运行签名并使用Platform.runLater(...)
由于您正在列表中收集文件名,因此我假设您在完成该过程时需要该文件名。您可以使用onSucceeded
进行此操作,并在任务完成后使用Task<List<String>> signingTask = new Task<List<String>>() {
@Override
public List<String> call() throws Exception {
List<String> files = new ArrayList<String>();
for (File unsignedFile : fWrapper.getFiles()) {
String targetFileStr = targetPath + "/" + unsignedFile.getName();
File signedFile = signer.signUDF(unsignedFile);
files.add(targetFileStr);
signedFile.renameTo(new File(targetFileStr));
Platform.runLater(() -> Browser.webEngine.executeScript("signedSuccessfully('" + unsignedFile.getName() + " is signed.')"));
}
return files ;
}
};
signingTask.setOnSucceeded(e -> {
// this is executed on the FX Application Thread when the task completes successfully
List<String> signedFiles = signingTask.getValue();
// do something with signedFiles...
});
signingTask.setOnFailed(e -> {
Throwable exception = signingTask.getException();
// this is executed on the FX Application Thread if the task throws an exception
// inform user something went wrong, etc...
});
Thread t = new Thread(signingTask);
t.start();
处理程序执行代码。
myPool = Executors.newCachedThreadPool(new ThreadFactory(){
//override newThread(Runnable r)...
});
Future<Result> futureResult = myPool.submit(new Callable<Result>(){
@Override public Result call(){
return dangerousMethod();
}
});