我正在阅读class Task的文档

    final Task<Void> task = new Task<Void>() {
        @Override public Void call() {
            for(int i=0;i<datesAndStudies.length;i++){
                updateProgress(i,datesAndStudies.length);
                DoSomething something = new DoSomething();
                something.VeryLongAndTimeConsumingMethod(i);
            }
            return null;
        }
    };


而且我注意到updateProgress受保护,并且workdone / totalwork都定义为公共最终ReadOnlyDoubleProperty。

有没有一种方法/解决方法来更新/调用updateProgress或编辑DoSomething类中的方法VeryLongAndTimeConsumingMethod(int i)中的这些值(工作完成/总计)?

最佳答案

即使updateProgress(...)是公开的,您也必须将对Task的引用传递给您的DoSomething类,这会造成一些非常丑陋的耦合。如果您在Task实现和DoSomething类之间具有这种级别的耦合,那么还可以只在Task子类本身中定义长而耗时的方法,并摆脱其他类:

final Task<Void> task = new Task<Void>() {
    @Override
    public Void call() {
        for (int i=0; i<datesAndStudies.length; i++) {
            veryLongAndTimeConsumingMethod(i);
        }
        return null ;
    }

    private void veryLongAndTimeConsumingMethod(int i) {
        // do whatever...
        updateProgress(...);
    }
};


为了保持解耦,只需定义一个表示DoubleProperty中进度的DoSomething,并从Task观察它,并在更改时调用updateProgress(...)

public class DoSomething {
    private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper(this, "progress");
    public double getProgress() {
        return progress.get();
    }
    public ReadOnlyDoubleProperty progressProperty() {
        return progress.getReadOnlyProperty();
    }
    public void veryLongAndTimeConsumingMethod(int i) {
        // ..
        progress.set(...);
    }
}


然后:

final Task<Void> task = new Task<>() {
    @Override
    public Void call() {
        for (int i=0; i<datesAndStudies.length; i++) {
            DoSomething something = new DoSomething();
            something.progressProperty().addListener(
                (obs, oldProgress, newProgress) -> updateProgress(...));
            something.veryLongAndTimeConsumingMethod();
        }
    }
}

10-04 17:22