2

まず最初に、私はJavaの同時実行パッケージをかなり最近使用していますが、私が立ち往生している問題を見つけました。欲しいのですが、アプリケーションとアプリケーションにはSplashScreen、ステータスバーと他のデータの読み込みがあります。そこで、を使用することにしましたSwingUtilities.invokeAndWait( call the splash component here )。次にSplashScreen、が表示され、JProgressBarスレッドのグループが実行されます。しかし、私は物事をうまく処理できないようです。私はこれを調べてSwingWorkerこの目的で使用しようとしましたが、スレッドが戻ってきます。これが少しの擬似コードです。そして私が達成しようとしているポイント。

  • SplashScreen情報の読み込み中に一時停止するアプリケーションがある
  • の下で複数のスレッドを実行できるSplashScreen
  • Update-ableのプログレスバーをSplashScreen用意しますが、すべてのスレッドが完了するまで終了しないでください。

スプラッシュ画面の起動

try {
    SwingUtilities.invokeAndWait( SplashScreen );
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }

スプラッシュスクリーンの構築

SplashScreen extends JFrame implements Runnable{

    public void run() {
        //run threads
        //while updating status bar
    }
}

SwingWorkers、CountDownLatchを使用したスレッドなど、さまざまなことを試しました。CountDownLatchは実際には処理を実行したい方法で機能しましたが、GUIを更新できませんでした。を使用すると、基本的に無効化されるSwingWorkersinvokeAndWait(これが目的です)、を使用してもGUIが更新されませんPropertyChangedListener。他の誰かがいくつかのアイデアを持っているなら、それを聞くのは素晴らしいことです。前もって感謝します。

私は実際に役立つコードを投稿する準備をして、自分の解決策を見つけました。助けてくれたすべての人に感謝します。

4

2 に答える 2

5

バックグラウンドで一連の操作を実行し、進行状況を報告するには、SwingWorkerを使用します。

このbackgroundメソッドはバックグラウンド処理を行います。
このメソッドを使用して、publish定期的なステータスの更新を投稿します。メソッドを
オーバーライドして更新を処理します(常にEDTで実行されます)。processprocess

progressBar = new JProgressBar();
sw = new SwingWorker<Boolean,Integer>() {
    protected Boolean doInBackground() throws Exception {
        // If any of the operations fail, return false to notify done() 
        // Do thing 1
        publish(25);  // 25% done
        // Do thing 2
        publish(50);  // 50% done
        // Do thing 3
        publish(75);  // 75% done
        // Do thing 4
        return true;
    }
    protected void process(List<Integer> chunks) {
        for (Integer i : chunks)
            progressBar.setValue(i);
    }
    protected void done() {
        try {
            boolean b = get();
            if (b)
                progressBar.setValue(100); // 100% done
            else
                // Notify the user processing failed
        }
        catch (InterruptedException ex) {
                // Notify the user processing was interrupted
        }
        catch (ExecutionException ex) {
                // Notify the user processing raised an exception
        }
    }
};

補遺:

これは複数のタスクに拡張できます。プログレスバーの設定方法を変更するだけです。頭に浮かぶのは次のとおりです。

タスクごとに1つずつ、完了カウンターの配列を用意します。

int[] completions = new int[numTasks];
Arrays.fill(completions,0);

SwingWorkersを起動し、それぞれにインデックス番号を渡します。次にprocess、ordoneメソッドはこのようなものを呼び出して、全体的なプログレスバーを更新します。

void update(int index, int percComplete) {
    completions[index] = percComplete;
    int total = 0;
    for(int comp: completions)
        total += comp/numTasks;
    overallPB.setValue(total);
}

オプションで、タスクごとにJProgressBarを表示します。

補遺2:

タスクの完了時間が異なる場合(たとえば、キャッシュヒットとキャッシュミス)、ProgressMonitorを調査することをお勧めします。これは進行状況ダイアログであり、タスクに一定(構成可能、デフォルトは500ミリ秒)以上の時間がかかる場合にのみ表示されます。

于 2011-03-02T18:30:16.010 に答える
0

invokeAndWait内のフレームを呼び出す必要はありませんが、このようにプログレスバーの状態を更新する必要があります。

try {
   SwingUtilities.invokeAndWait( new Runnable() {
     public void run() {
//update state of the progress bar here
     }
   });
 } catch (InterruptedException e) {
 } catch (InvocationTargetException e) { }
于 2011-03-02T07:20:46.720 に答える