6

長いダウンロードが行われているときに、フレームの左下隅に不確定なJProgressBarをアニメーション化させたいだけです。

私は多くのチュートリアルを調べましたが、どれも私にはわかりません。ファイルがバックグラウンドでダウンロードされている間、アニメーション化するだけです。私がこれを試したそれぞれの方法で、ダウンロードが完了するまでプログレスバーはアニメーション化されませ

download()呼び出しをどこに置くかを知るのに助けが必要です。

class MyFunClass extends JFrame {
  JProgressBar progressBar = new JProgressBar();

  public void buttonClicked() {
    progressBar.setVisible(true);
    progressBar.setIndeterminate(true);

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        progressBar.setIndeterminate(true);
        progressBar.setVisible(true);

        // Do I do my download() in here??

    }});

    // Do download() here???
    progressBar.setVisible(false);
  }
}

前もって感謝します!



解決

編集:将来私と同様の問題を抱えている人にとって、これは基本的な問題の基本的な解決策です。これは私のコードではありませんが、一般的なスケッチです。内部buttonClicked()

public void buttonClicked() {
  class MyWorker extends SwingWorker(String, Object) {
     protected String doInBackground() {
       progressBar.setVisible(true);
       progressBar.setIndeterminate(true);

       // Do my downloading code
       return "Done."
     }

     protected void done() {
        progressBar.setVisible(false)
     }
  }

  new MyWorker().execute();

}
4

1 に答える 1

10

現在のコードは、バックグラウンドスレッドの作成を示していませんが、Swingスレッド内からSwingスレッドのコードをキューに入れようとしていることを示しています。これは、この問題には意味がありません(ただし、必要な場合があります)。これですが、ここでもありません)。これを成功させる唯一の方法は、バックグラウンドスレッドを使用することです。標準のOracleJProgressBarチュートリアルSwingの並行性は、これらすべてを実行します。

基本的なことは、SwingスレッドからJProgressBarを更新する必要があるということです。これにより、SwingWorkerオブジェクトによって提供されるようなバックグラウンドスレッドで長時間実行されるプロセスが実行されます。詳細が多すぎてここですべてを確認できないため、リンクを提供するだけですが、チュートリアルを確認したら、詳細を理解できるようにサポートさせていただきます。チュートリアルを確認して、まだ行き詰まっている場合は、特定の質問に戻ってください。

編集1
あなたは次のように述べています。

buttonClicked()関数内に新しいスレッドオブジェクトを作成できますか?

はい、buttonClicked() メソッド内にSwingWorkerオブジェクトを作成し、そこで実行できます。

問題は、GUIを開発しているすべての機能のAPIとライブラリを持っていることです。その関数呼び出しをスレッドでラップするのは、長い回避策のようです。

申し訳ありませんが、ここで何を言っているのか、スレッド化によってどのような問題が発生すると思われるのかわかりません。buttonClicked()メソッドは、バックグラウンドスレッドではなく、EDTで実行する必要がある可能性があります

また、私のより複雑なSwing GUIのほとんどでは、ファイルを別の(モデル)オブジェクトでダウンロードし、GUIオブジェクト(ビュー)とは別のオブジェクト(コントロール)でSwingWorkerを作成することがよくあります。この方法で行うのはより複雑に思えるかもしれませんが、この方法で行うと、特にインターフェイスを頻繁に使用してすべてのプログラムコンポーネントを個別にテストできるようにする場合、プログラムのデバッグ、保守、および拡張がはるかに簡単になります

編集2
ソリューションの投稿にいくつかの修正を加えます。あなたが投稿した:

public void buttonClicked() {
  class MyWorker extends SwingWorker(String, Object) {
     protected String runInBackground() {
       progressBar.setVisible(true);
       progressBar.setIndeterminate(true);

       // ...

問題がある

  • それdoInBackground()は、ではありませんrunInBackground()
  • しかし、もっと重要なことは、バックグラウンドスレッド内からSwing呼び出しを行っていることです。これは、絶対に行わないでください(呼び出しがスレッドセーフでない限り、さらには...)。

だからそれを変更します:

public void buttonClicked() {
  progressBar.setVisible(true);
  progressBar.setIndeterminate(true);
  class MyWorker extends SwingWorker<String, Void> {
     protected String doInBackground() {

       // ...
于 2012-05-04T03:48:19.380 に答える