2017-08-02 92 views
1

我有一個javafx應用程序,用於簽署用戶上傳的文件。它會分別顯示這些文件的名稱。一次顯示一個元素

問題是,要在屏幕上顯示文件,它會等待所有文件被簽名。所有文件簽名後,突然顯示所有文件。

繼GIF顯示當前狀態:

Displayed Files 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>'); 
} 

是否有任何人誰可以給我約我怎麼能做到這一點一些建議?

預先感謝您。

+1

我猜你所發佈的代碼是在FX應用程序線程上執行的。在後臺線程中執行循環並將調用封裝到'Platform.runLater(...)'中的'executeScript(...)'中。 –

+0

感謝您的評論James,其實我是javafx中的貪婪人物。我想我沒有使用線程,我猜我的代碼沒有在FX應用程序線程上執行。你能更好地描述它嗎?或者你有其他想法嗎? –

回答

0

運行在後臺線程的簽署和使用Platform.runLater(...)

既然你在列表中收集的文件名中的FX應用程序線程每次更新UI,我想你需要的是,當該過程完成。您可以使用Task來完成此任務,並使用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(); 
+0

感謝您的回答James,但是我得到了「java.lang.IllegalStateException:不在FX應用程序線程上; currentThread = Thread-10」。我已經嘗試了很多東西來解決它,但我無法實現。你有什麼想法來解決這個問題嗎?謝謝。 –

+0

哪一行引發異常? –

+0

我解決了它。這個例外是從另一行發生的。這不是關於你的代碼。感謝您的時間。 –