まず、javafx.concurrent
パッケージはFX Toolkitの実行に依存しますが、JavaFX Propertiesクラスにはそのような要件はありません。したがって、単一のスレッドからのみJavaFXプロパティにアクセスする限り、FX Toolkitの実行を必要とせずに、使用したいクラスでJavaFXプロパティを使用することは完全に有効です。
だから例えば、あなたが行うことができます:
public class MyProcess implements Callable<SomeData> {
private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper();
public ReadOnlyDoubleProperty progressProperty() {
return progress.getReadOnlyProperty() ;
}
public final double getProgress() {
return progressProperty().get();
}
@Override
public SomeData call() {
final int numSteps = ... ;
SomeData data = new SomeData();
for (int i = 0 ; i < numSteps ; i++) {
progress.set(1.0*i/numSteps);
data.update(i);
}
return data ;
}
}
このクラスは罰金実行され、FXツールキットの実行には依存しません。次のようにして、タスクでそれをラップすることができます:
public class MyProcessTask extends Task<SomeData> {
@Override
protected SomeData call() throws Exception {
MyProcess process = new MyProcess();
process.progressProperty().addListener((obs, oldProgress, newProgress) ->
updateProgress(newProgress, 1.0));
return process.call();
}
}
あなたCallable
実装は(だけでなく、実行されているツールキットを必要としないという意味で)APIレベルでのJavaFXに依存しないようにしたい場合は、それがありますjava.util.function
APIを使用して適切なコールバックを簡単に実装できます。たとえば、
public class MyProcess implements Callable<SomeData> {
private DoubleConsumer progressUpdate = d -> {} ; // no-op
private double progress ;
public void setProgressUpdate(DoubleConsumer progressUpdate) {
this.progressUpdate = progressUpdate ;
}
public final double getProgress() {
return progress;
}
private void setProgress(double progress) {
this.progress = progress ;
progressUpdate.accept(progress);
}
@Override
public SomeData call() {
final int numSteps = ... ;
SomeData data = new SomeData();
for (int i = 0 ; i < numSteps ; i++) {
setProgress(1.0*i/numSteps) ;
data.update(i);
}
return data ;
}
}
と
public class MyProcessTask extends Task<SomeData> {
@Override
protected SomeData call() throws Exception {
MyProcess process = new MyProcess();
process.setProgressUpdate(p -> updateProgress(p, 1.0));
return process.call();
}
}
パーフェクトとして上記をリファクタリングできます!私は 'updateMessage()'にも同様のアプローチを使用できます。しかし、取り消しはどうですか?そのために「Consumer」を使用するのは意味がありますか? –
kerner1000
'Callable'は' Task'sと同じ意味でキャンセルできません。 「取り消されました」は、FXアプリケーションスレッド上で更新される(タスクランクに対応する状態の一部です(したがって、 'RUNNING'、' SUCCEEDED'などと同じカテゴリに入ります)。 –
したがって、ユーザーによるキャンセル要求を聞くにはどうすればよいでしょうか? 'Thread.isInterrupted()'をチェックしますか? – kerner1000