2017-02-19 6 views
-2

私はswingListを使用してコードを記述しました。これはactionListenerを追加するとprogressBarを更新しません。java swing progressBar

ボタンとアクションリスナーなしで、それは素晴らしい作品です。 progressBarの更新をできるだけ簡単かつきれいにする方法はありますか?添付されたコードは、私の問題を要約した分かりやすい例です。 ActionPerformedメソッドをコメントアウトしてmainからプログラムを実行すると、正常に動作します。

説明せずにコードを貼り付けるだけではありません。私はこれを見てきました。:

PSは:swing progressBar threading

public class Okno { 

    private JProgressBar progressBar = new JProgressBar(0,306); 
    JFrame f = new JFrame("JProgressBar Sample"); 
    JButton b = new JButton("start"); 
    ActionListener a = new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      barupdate(); 
     } 
    }; 


    private void barupdate(){ 
     for(int p = 1; p<308;p=p+2){ 
      System.out.println(p); 

      progressBar.setValue(p); 

       try { 
         Thread.sleep(50); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
     } 
} 

private Okno(){ 

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    progressBar.setStringPainted(true); 

    f.add(progressBar, BorderLayout.SOUTH); 
    f.add(b, BorderLayout.NORTH); 
    b.addActionListener(a); 
    f.setSize(300, 300); 
    f.setVisible(true); 

} 

public static void main(String[] args) { 
    Okno okno = new Okno(); 
} 
} 
+0

これは一般的に同じ方法で解決される非常に一般的な問題です。この場合の最適な解決策は通常、[SwingWorker]を使用しています[例えば、](http://stackoverflow.com/questions/12020949/jprogressbar-isnt -progressing/12021971#12021971)。また、この問題の詳細については、[同時実行性(Concurrency in Swing)](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)を参照してください。ほとんどの場合、Swingはスレッドセーフではなく、UIを更新するために特別な注意を払わなければならないので、別の 'Thread'を使うことは最良の選択ではありません。SwingWorkerが自由にあなたに提供します; – MadProgrammer

+0

@ MadProgrammer、 'この場合の最善の解決法は、通常SwingWorkerを使用しています...あなたはSwingのConcurrencyを見なければなりません。 – camickr

+0

@camickr質問は終了する必要がありますが、私はあなたがそれをしている人に問題があることを知っているので、私はコメントを残しました(あなたの答えをサポートする)。 – MadProgrammer

答えて

1

問題は、あなたがアクションリスナーから呼び出されているプログレスバーの設定を調整しているループを持っています。問題は、リスナーが終了するまでバーが更新されないことです。そしてあなたは更新を得ません。それだけでなく、あなたがそのアクションリスナーにいる間にウィンドウがマウスクリックなどに反応することができないので、あなたはGUIを動かすことになります。

これを処理する最善の方法は、アクションリスナーにスイングタイマーを作成し、そこにボタンを更新するコードを入れ、アクションリスナーでタイマーを開始することです。

タイマーはバーを1回だけ更新する必要があります。スイングタイマーが複数回呼び出され、反復性の部分を演奏するという事実を許すべきです。だから、あなたのコードにループを持たせたくありません。

+0

私はある方向に私を指してくれてありがとう...私はそれが行ってどのように行って報告します –

0
Thread.sleep(50); 

Thread.sleep(...)は使用しないでください。これにより、ループの実行が終了するまでGUIが再描画されなくなります。

代わりにSwingWorkerを使用できます。

Concurrency in SwingのSwingチュートリアルのセクションを参照してください。詳細については、SwingWorkerの動作例が含まれています。

また、チュートリアルの目次もご覧ください。 How to Use ProgressBarsには、実際の例も含まれています。このチュートリアルは、例を探す最初の場所です。

+0

コードは私の問題を要約する例であり、sleep()メソッドはプログレッシブバーの進行を遅くすることです。アクションリスニングコードを削除してメインバーからプログレスバーコードを開始すると、正常に動作します。 –

+0

私は知っています。 main()からプログレスバーを開始すると、コードは別のスレッドで実行されます。 ActionListenerでプログレスバーを開始すると、コードはGUIをペイントするスレッドである 'Event Dispatch Thread(EDT)'で実行されます。したがって、別のスレッドでプログレスバーを開始する必要があります。スイングの仕組みを理解するためにチュートリアルを読む必要があります。 'このチュートリアルには実例があります。 – camickr