[英]JavaFX - bind property from another class onto a status bar
因此,我有一個非常非常簡單的應用程序,應該可以處理下載某些文件並將它們更新到某個目錄的情況。 該應用程序具有一個帶狀態欄的簡單界面,該欄應告訴用戶下載過程的進展情況。 到現在為止還挺好。
我有一些擴展javafx.concurrent.Task類的類的實現。 這些類負責處理每個系統的文件下載和保存,並注意每個系統的特殊性。 每個人的下載過程本身(實際上來自遠程數據庫)是相同的,因此,它在另一個稱為FileDownloader的類中實現,因為它自然是可以重用的。
因此,我們有一個帶有Task ()方法的UpdateTask類,該方法又調用FileDownloader類中的某些方法。
麻煩是:我需要將progressProperty綁定到欄中,但是只有UpdateTask才具有此屬性,而我想在欄中顯示的大部分工作都在FileDownloader中完成。 我無法從download方法中調用updateProgress,因為它不在Task類中。 我無法將任務傳遞給方法並在那里調用update方法。 我無法在progress屬性上創建偵聽器,也無法偵聽downloader類內部字段的更改。 看來我什么也做不了,唯一的解決辦法是計算出call()方法內正在完成的工作。 麻煩是我。
有沒有解決這個問題的方法,而無需我編寫更少可重用的代碼? 示例代碼如下:
public class UpdateTask extends Task<Void> {
@Override
protected Void call() throws Exception {
//some other operations are performed before this part
FileDownloader downloader = new FileDownloader();
//The stuff I wanna count is in there :(
boolean isDownloaded = downloader.downloadSysVersion();
//some other stuff happens that depends on the completion of the download
}
誰向我展示了如何從downloadSysVersion方法內部獲取信息,則將獲得免費的Internet cookie。
在FileDownloader
類中添加代表進度的屬性。 例如,如果要公開下載的字節數,則可以執行
public class FileDownloader {
private final ReadOnlyLongWrapper bytesDownloaded = new ReadOnlyLongWrapper();
public final long getBytesDownloaded() {
return bytesDownloaded.get();
}
public final ReadOnlyLongProperty bytesDownloadedProperty() {
return bytesDownloaded.getReadOnlyProperty();
}
private long totalBytes ;
public long getTotalBytes() {
return totalBytes ;
}
// other code as before...
public boolean downloadSysVersion() {
// code as before, but periodically call
bytesDownloaded.set(...);
// ...
}
}
你現在做
@Override
protected Void call() throws Exception {
FileDownloader downloader = new FileDownloader();
downloader.bytesDownloadedProperty().addListener((obs, oldValue, newValue) ->
updateProgress(newValue.longValue(), downloader.getTotalBytes()));
boolean isDownloaded = downloader.downloadSysVersion();
// ...
}
如果要使FileDownloader
類獨立於整個JavaFX API(包括屬性類),則可以改用LongConsumer
:
public class FileDownloader {
private LongConsumer progressUpdate ;
public void setProgressUpdate(LongConsumer progressUpdate) {
this.progressUpdate = progressUpdate ;
}
private long totalBytes ;
public long getTotalBytes() {
return totalBytes ;
}
public boolean downloadSysVersion() {
// periodically do
if (progressUpdate != null) {
progressUpdate.accept(...); // pass in number of bytes downloaded
}
// ...
}
}
在這種情況下,您的任務看起來像
@Override
protected Void call() throws Exception {
FileDownloader downloader = new FileDownloader();
downloader.setProgressUpdate(bytesDownloaded ->
updateProgress(bytesDownloaded, downloader.getTotalBytes()));
boolean isDownloaded = downloader.downloadSysVersion();
// ...
}
無論使用哪種設置,您都可以照常將進度條的progressProperty
綁定到任務的progressProperty
。
在您的UpdateTask類中,添加:
@Override
public void updateProgress(double workDone, double max) {
super.updateProgress(workDone, max);
}
您需要以某種方式(可能是通過構造函數)將UpdateTask實例傳遞給FileDownlader實例實例。 然后,您應該可以調用updateProgress。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.