2012-05-03 16 views
4

私は次のコードを持っています。私のJProgressBarは100%まで更新されていません

public class MyProgressBar extends JPanel implements MyData, Serializable { 

    /** 
    * 
    */ 

    public static final int MAX    = 10000; 
    public static final int WIDTH    = 400; 
    public static final int HEIGHT    = 75; 

    private JProgressBar MyBar    = new JProgressBar(SwingConstants.HORIZONTAL, 0, MAX); 
    private JFrame   MyFrame   = new JFrame(); 

    private int    MyValue   = 0; 

    private Thread   MyThread   = new Thread(new ProgressThread()); 



    public MyProgressBar() { 
     add(MyBar); 

     int x = (MyData.SCREEN.width/2) - (WIDTH/2); 
     int y = (MyData.SCREEN.height/2) - (HEIGHT/2); 

     this.setBounds(x, y, WIDTH, HEIGHT); 

     MyFrame.setBounds(x, y, WIDTH, HEIGHT); 
     MyFrame.setUndecorated(true); 
     MyFrame.getContentPane().setSize(new Dimension(WIDTH, HEIGHT)); 
     MyFrame.setMinimumSize(new Dimension(WIDTH, HEIGHT)); 
     MyFrame.setPreferredSize(new Dimension(WIDTH, HEIGHT)); 
     MyFrame.setSize(new Dimension(WIDTH, HEIGHT)); 
     MyFrame.setVisible(false); 
     MyFrame.getContentPane().setLayout(null); 

     MyBar.setStringPainted(true); 
     MyBar.setBorderPainted(true); 
     MyBar.setValue(0); 
     MyBar.setBounds(0, 0, WIDTH, HEIGHT); 

     MyFrame.add(MyBar); 
     MyFrame.pack(); 
     MyFrame.repaint(); 

    } 

    public void MyUpdateBar() { 
     MyBar.setValue(MyValue); 
     MyBar.repaint(); 
     MyFrame.repaint(); 
     this.repaint(); 
     //dbug.Message("MYPROGRESSBAR", "MyUpdateBar", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue); 
    } 

    public void MySetValue(int percent) { 
     MyValue = (int)(MAX * ((double)percent/100.0)); 
     MyUpdateBar(); 
     //dbug.Message("MYPROGRESSBAR", "MySetValue", "Value is %3.2f %d percent was %d", MyBar.getPercentComplete(), MyValue, percent); 
    } 

    public void CreateAndShow() { 
     MyFrame.setVisible(true); 
     MyThread.start(); 
    } 

    public void HideAndClear() { 
     MyThread.stop(); 
     //frame.setVisible(false); 
    } 

    class ProgressThread implements Runnable { 
     public void run() { 
      EventQueue.invokeLater(new Runnable() { 
       public void run() { 
        while(MyValue < MyBar.getMaximum()) { 
         MyBar.setValue(MyValue); 
         MyBar.repaint(); 
         MyFrame.repaint(); 
         dbug.Message("MYPROGRESSBAR", "THREAD", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue); 
        } 
       } 
      }); 
     } 

    } 



} 

ご覧のとおり、進捗状況を表示したいクラスを作成しました。私はクラスをインスタンス化します。私のXMLファイルをロードして、私がデータを解析しているときに、私のdbugメッセージが出てくるときに私が見るMyValueを更新するよう呼びかけています。しかし、バー自体は100%完成するまで表示されません。私はスレッディングと他の人の例を読んだことがあります。私が彼の例として残しておけばそれはうまくいったのです。スレッドのループを変更してプログレスバーの設定値を読み込んで値を読み込むと、100までは表示されません。

どうしましたか?

ありがとうございます!

+0

にいる間、プログレスバーを更新します、私はここに書きました(ProgressBarForDataFetching:http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/ui/ex/ DataFetcherからの更新を処理します。別のクラスはInputStreamを読み込みます)DataFetcherはtjacobs.ioの同じサイト – ControlAltDel

答えて

14

あなたスレッドはSwingUtilities.invokeLaterを実行します。あなたはSwingのEvent Dispatch Threadを効果的に実行しています。何を達成しようとしているのか分かりません。しかし、あなたがブロックしているように見えるEDTwhileループは更新されません。MySetValueは実行されません。

長時間の操作にはSwingWorkerを使用することを検討してください。 How to Use Progress BarsSwingWorkerの使用をJProgressBarと示しています。

Event Dispatch ThreadからsetValueメソッドを呼び出してください。これにはSwingUtilities.invokeLaterを使用できます。 Threads and Swingについてもっと読む。

は、この単純化されたサンプルを考えてみましょう:

public static void main(String[] arguments) { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 

    final JProgressBar bar = new JProgressBar(0, 100); 

    Thread t = new Thread(){ 
     public void run(){ 
      for(int i = 0 ; i < 100 ; i++){ 
       final int percent = i; 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         bar.setValue(percent); 
        } 
        }); 

       try { 
        Thread.sleep(100); 
       } catch (InterruptedException e) {} 
      } 
     } 
    }; 
    frame.add(bar); 
    frame.pack(); 
    frame.setVisible(true); 
    t.start(); 
} 
+0

私はEventQueuを変更しましたeはSwingUtilitiesであり、同じ動作をします。 –

+0

@JesterHawk 'SwingUtilities.invokeLater'は実際には' EventQueue.invokeLater'を呼び出しています。問題はあなたの 'while'ループでEDTをブロックしているということです。 – tenorsax

+0

私が持っている問題は、私が働くような何かを得ることができるということです。しかし、私はメソッドを呼び出すことができ、別のクラス(これを宣言したクラス)から完全なパーセンテージを設定する必要があり、それを追加しようとすると何も得られません。 –

5

問題は、あなたが進捗状況を更新EDTでループを使用することです。そのループが終了するまで、EDTはプログレスバーのリフレッシュを妨げるイベント(repaint、revalidate、invokeLater、マウスイベント、キーイベントなど)をディスパッチできません。

EDTが進行状況バーの各更新の間にイベントをディスパッチさせる方法を見つける必要があります。理想的には、SwingWorkerを使用してEDTの外に自分の「仕事」を移動し、EDTのプロパティー変更リスナーを通じてプログレスバーを更新することが理想的です。

Javaの場合、メソッドと変数は小文字で始まります。あなたのコードは、他人のために読むのが本当に難しいです。

+0

私は変数とメソッドについては知らなかった。コードを読みやすくするためにコードを変更します。ありがとう。 –

+0

@JesterHawkそれは私が考えたものなので、少なくともあなたに知らせることを考えました;-) –

1

私はチュートリアルに従おうとしましたが、ここで私はここにいます。

私はチュートリアルに続いて試してみましたが、どこかで失われ続けています。必要なのは、プログレスバー(JProgressBar)を作成して表示するクラスで、ファイルから読み込まれたデータを反復処理してデータベースメモリに格納するときの値を設定できます。私の問題は、私が見つけたすべての例では、プログレスバーを塗りつぶし、「メイン」機能から実行する何らかの種類のカウンタがあることがわかります。そのチュートリアルを変更して、私が呼び出してバーを表示できるクラスにするたびに、バーが表示されません(つまり、フレームが表示されますが、バーがフレームまで追加されたように見えません繰り返しが行われます)。私は同じ問題を抱えているSwingUtilities.invokeLaterとSwingWorker(下のクラスの最新の試み)を使ってみました。さらに悪いことに、私はdbug.myMessage(基本的にSystem.outに送信)を行い、バーが表示されていないだけでメモリが変化していることを示すメッセージを見ることができます。私は明らかにおそらく単純な何かを欠いているが、それは何かを考えることができない。

私はチュートリアルを(http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/ProgressBarDemo2Project/src/components/ProgressBarDemo2.java)のままにして、メインをcreateAndShowメソッドに変更するだけで動作しますが、もちろん必要なことはしません。

私はこれについて別の質問を投稿しましたが、クラスを変更して、新しい質問を投稿することをお勧めしました。

だから、ここで働いていないようだ私の変更されたコードです:あなたは正しくプログレスバーを使用しての例をしたい場合は

public class MyProgressBar extends JPanel implements PropertyChangeListener, 
                MyData, 
                Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -1632492668549544408L; 

    private MyDebug   dbug    = new MyDebug(MyData.MYDEBUGCHECK.MYPROGRESSBAR.getOn()); 

    public static final int MAX    = 100; 
    public static final int WIDTH    = 400; 
    public static final int HEIGHT    = 75; 

    private JProgressBar myBar    = new JProgressBar(SwingConstants.HORIZONTAL, 0, MAX); 
    private JFrame   myFrame   = new JFrame(); 

    public Task   task; 


    class Task extends SwingWorker<Void, Void> { 

     public int myValue = 0; 

     @Override 
     public Void doInBackground() { 
      //Initialize progress property. 
      setProgress(0); 
      while (myValue < 100) { 
       //Make random progress. 
       //myValue += random.nextInt(10); 
       setProgress(Math.min(myValue, 100)); 
       dbug.myMessage("MYPROGRESSBAR", "doInBackground", "Value is %3.2f %d", myBar.getPercentComplete(), myValue); 
       myBar.repaint(); 
      } 
      return null; 
     } 

     public void done() { 
     } 

     public void mySetValue(int percent) { 
      myValue = (int)(MAX * ((double)percent/100.0)); 
      dbug.myMessage("MYPROGRESSBAR", "mySetValue", "Value is %3.2f %d percent was %d", myBar.getPercentComplete(), myValue, percent); 
     } 

    } 



    public MyProgressBar() { 
     add(myBar); 

     int x = (MyData.SCREEN.width/2) - (WIDTH/2); 
     int y = (MyData.SCREEN.height/2) - (HEIGHT/2); 

     this.setBounds(x, y, WIDTH, HEIGHT); 

     myFrame.setBounds(x, y, WIDTH, HEIGHT); 
     myFrame.setUndecorated(true); 
     myFrame.getContentPane().setSize(new Dimension(WIDTH, HEIGHT)); 
     myFrame.setMinimumSize(new Dimension(WIDTH, HEIGHT)); 
     myFrame.setPreferredSize(new Dimension(WIDTH, HEIGHT)); 
     myFrame.setSize(new Dimension(WIDTH, HEIGHT)); 
     myFrame.setVisible(false); 
     myFrame.getContentPane().setLayout(null); 
     myFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); 

     myBar.setStringPainted(true); 
     myBar.setBorderPainted(true); 
     myBar.setValue(0); 
     myBar.setBounds(0, 0, WIDTH, HEIGHT); 
     myBar.addPropertyChangeListener(this); 

     myFrame.add(myBar); 

     //Create and set up the content pane. 
     //JComponent newContentPane = new MyProgressBar(); 
     JComponent newContentPane = myBar; 
     newContentPane.setOpaque(true);      //content panes must be opaque 

     myFrame.setContentPane(newContentPane); 
     myFrame.pack(); 

    } 

    public void createAndShow() { 

     //Display the window. 
     myFrame.setVisible(true); 
     myFrame.repaint(); 

    } 

    public void hideAndClear() { 
     //myFrame.setVisible(false); 
    } 


    @Override 
    public void propertyChange(PropertyChangeEvent args) { 
     dbug.myMessage("MYPROGRESSBAR", "propertyChange", "Value is %s", args.getPropertyName()); 
     if ("progress" == args.getPropertyName()) { 
      int progress = (Integer) args.getNewValue(); 
      //myBar.setValue(progress); 
     } 
    } 

    public void start() { 
     //Instances of javax.swing.SwingWorker are not reusuable, so 
     //we create new instances as needed. 
     task = new Task(); 
     task.addPropertyChangeListener(this); 
     task.execute(); 
    } 

} 
0

以下のスニペットは、進行

SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
      progressBar.setValue((int)percentage); 
      //below code to update progress bar while running on thread 
      progressBar.update(progressBar.getGraphics());} 
     }); 
関連する問題