3層(gui-> services-> dao)のデスクトップアプリケーション(JavaFX + Spring 4)があります。 私のサービス層(fx依存関係なし)で実現した私のメソッドの中には、長時間の計算があります。私はguiでの進捗状況を報告したいと思います。Spring Listenerメソッドからアクティブ化されたJavaFXプログレスバーコンポーネント
しかし、問題があります。私のサービス層はguiに直接アクセスできず、IO操作のログを作り、それを要約するだけです。 GUI層は、中間操作の進捗状況を知らない。
一般的な進捗コンポーネントを作成しようとしています。リスナーメソッドがidのGUIレイヤーに配置されたSpring Beanとして実現できます。私のサービスはApplicationEvent
を公開することができ、guiの進捗コンポーネントを介して受け取ることができます。イベントを取得したら、進行状況バーをアクティブにして次のイベントを報告する必要があります。
私はProgressTask
を起動し、progressProperty
を私のGUIプログレスバーコントロールでバインドしています。
私のProgressTask
の呼び出し方法は実際のカウンタがその最大ステップ数より少ない間に実行されます。
は私のコンポーネントがあります:
@Component
@Controller
public class ProgressBarComponent {
@FXML
private ProgressBar progressBar;
private ProgressTask actTask;
@FXML
public void initialize(){
}
private void initProgressBar(int aMax){
actTask=new ProgressTask();
actTask.initState(aMax);
progressBar.progressProperty().bind(actTask.progressProperty());
new Thread(actTask).start();
}
@EventListener
public void handleProgressEvent(ProgressEvent event) {
if(event.getGetActStep()==0){
initProgressBar(event.getMaxStep());
}
actTask.changeState(event.getGetActStep());
}
class ProgressTask extends Task<Object>{
private int max=100;
private int act=0;
private volatile boolean cancelled;
public void initState(int aMax){
this.max=aMax;
}
public void changeState(int newVal){
act=newVal;
updateProgress(act, max);
updateMessage("progress: " + act);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new IllegalArgumentException(e);
}
}
@Override
protected Object call() throws Exception {
while(act<max){
}
return null;
}
}
}
しかし、それは動作しません。 プログレスバーコントロールがアクティブになっていますが、一度に100%の値があります。
プログレスバーFXコントロールの例はたくさんありますが、それらのすべてはメインロジックがcall()
メソッドProgressTask
の中で計算されると仮定しています。私の場合、それは不可能です。
ProgressBar
コンポーネントはリスナーメソッドからアクティブにできますか?はいの場合、どのコードをProgressTask.call()
メソッドに含める必要がありますか?
私はこれが動作するようになっている方法を理解するために春のイベントについて十分に知らないかもしれないが、 'ProgressEvent'とは何か、そしてどのようにあなたのサービスがこれを呼び出しています? 'Task'の全目的はバックグラウンド作業を行うことです。それが他の場所で行われている場合、' Task'実装のポイントが何であるかは本当に明確ではありません。しかし、最低限、「max」と「act」は1つのスレッドで書かれ、別のスレッドから読み込まれるため、「volatile」でなければなりません。 'call()'メソッドのbusy-waitループは良い考えではありません。 –
おそらく実際の作業は、FXアプリケーションスレッドではなく、バックグラウンドスレッドで実行されています... –