簡體   English   中英

JavaFX-將另一個類的屬性綁定到狀態欄

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM