【问题标题】:JavaFX - bind property from another class onto a status barJavaFX - 将另一个类的属性绑定到状态栏
【发布时间】:2015-10-22 10:41:36
【问题描述】:

所以,我有一个非常简单的应用程序,它应该处理下载某些文件并将它们更新到某个目录。该应用程序有一个简单的界面和一个状态栏,它应该告诉用户下载过程是如何进行的。到目前为止,一切顺利。

我有一些扩展 javafx.concurrent.Task 类的类实现。这些类处理每个系统的文件下载和保存,并照顾每个系统的特殊性。下载过程本身(实际上来自远程数据库)对每个人都是一样的,因此,它在另一个名为 FileDownloader 的类中实现,因为它自然应该是可重用的。

因此,我们有一个带有 call() 方法的 UpdateTask 类,该方法又调用 FileDownloader 类中的某些方法。

问题是:我需要将 progressProperty 绑定到栏,但只有 UpdateTask 有这个属性,而我想在栏中显示的大部分工作在 FileDownloader 内完成。我无法从下载方法中调用 updateProgress,因为它不在 Task 类中。我无法将任务传递给方法并在那里调用更新方法。我无法在进度属性上创建监听器并监听下载器类中字段的更改。似乎我无能为力,唯一真正的解决方案是计算 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 方法中获取信息的人将获得免费的互联网 cookie。

【问题讨论】:

    标签: java multithreading user-interface javafx progress-bar


    【解决方案1】:

    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

    【讨论】:

    • 工作就像一个魅力。我最终选择了 ReadOnlyLongWrapper,因为这应该是一个真正简单的应用程序,而且我只需要某种程度的解耦。
    【解决方案2】:

    在您的 UpdateTask 类中,添加:

    @Override
        public void updateProgress(double workDone, double max) {
            super.updateProgress(workDone, max);
        }
    

    您需要以某种方式将 UpdateTask 实例传递给您的 FileDownlader 实例实例,可能是通过构造函数,或者无论如何。 然后你应该可以调用 updateProgress。

    【讨论】:

    • 这使得FileDownloader 的可重用性降低,因为它会依赖UpdateTask
    • 对不起。看来我不明白他到底想要什么。
    • 我尝试了这种方法,但它不起作用,因为我似乎只能从 call 方法中调用 updateProgress 方法。是的,它会降低它的可用性,但我还是出于绝望尝试了它。
    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2018-01-13
    • 2017-12-17
    • 2020-07-21
    • 1970-01-01
    相关资源
    最近更新 更多