2

私は ExectorService と次のコードを持っています。すべてが先物と同時実行で正常に動作しています。ただし、SomeClass() からプログレス バーを更新しようとすると、invokeAll() が完了した後にのみ UI が更新されるようです...基本的に、プログレス バーはすべてが完了すると更新され、役に立たないと見なされます。

どうすればこれを解決できますか? CompletionServices と SwingWorkers を見てきましたが、それらを自分のコードに適用する方法がわかりません。任意の支援をいただければ幸いです。

class SomeClass() {
  private static class Result {
    private final String someVar;

    public Result(String code) {
        this.someVar = code;
    }
  }

 public static Result compute(Object obj) {
   // ... compute stuff
   someVar = "computedResult";
   return Result(someVar);
 }
 public someFunction() {
    List<Callable<Result>> tasks = new ArrayList<Callable<Result>>();
    for (Object f : listOfObjects) {
        Callable<Result> c = new Callable<Result>() {
            @Override
            public Result call() throws Exception {
                someClassUI.jProgressBar.setValue(50);
                return compute(file);
            }
        };
        tasks.add(c); 
    }

    List<Callable<Result>> tasks = new ArrayList<Callable<Result>>();
    List<Future<Result>> results = executorService.invokeAll(tasks);

    for (Future<Result> fr : results) {
     String value = fr.get().resultValue;
    }
  }
}

class SomeClassUI {
  public static jProgressBar;

  public someClassUI() {
    jProgressBar = new JProgressBar(0,100);
  }

  private void button1ActionPerformed(ActionEvent e) {
    SomeClass theClass = new SomeClass();
    theClass.someFunction();
  }

}

編集:理解を助けるためにいくつかの余分なコードを追加するために編集されました

4

2 に答える 2

0

イベントディスパッチスレッド以外のスレッドから Swing コンポーネントにアクセスしています。これは、 Swing のスレッド ポリシーで禁止されています。

このコードを使用して、バックグラウンド スレッドから進行状況バーを更新します。

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        someClassUI.jProgressBar.setValue(50);
    }
});

公式の swing チュートリアルで、swing での同時実行の詳細をお読みください。

于 2013-05-16T22:26:56.857 に答える