当前位置: 代码迷 >> java >> JavaFX-将另一个类的属性绑定到状态栏
  详细解决方案

JavaFX-将另一个类的属性绑定到状态栏

热度:71   发布时间:2023-07-17 20:57:23.0

因此,我有一个非常非常简单的应用程序,应该可以处理下载某些文件并将它们更新到某个目录的情况。 该应用程序具有一个带状态栏的简单界面,该栏应告诉用户下载过程的进展情况。 到现在为止还挺好。

我有一些扩展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。

  相关解决方案