2

I can't update my progressbar... this is my code

Thread t=new Thread(new Runnable(){
        public void run(){
            int i=1;
            jProgBar.setMinimum(0);
            jProgBar.setMaximum(100);
            try {
                while(i<=100 || true){
                    jProgBar.setValue(i);
                    i++;
                    Thread.sleep(50);
                }
            }
            catch (InterruptedException ex){
                jProgBar.setValue(jProgBar.getMaximum());
            }
        }
    });
    t.start();

    .... Something code that correctly works

    t.interrupt();

The progress bar state is updated only at the end of thread. Can someone help me??

ColinD
  • 108,630
  • 30
  • 201
  • 202
raf
  • 1,121
  • 3
  • 13
  • 14

6 Answers6

4

Before the sleep, add a call to SwingUtilties.invokeLater() that spawns a thread to fire a firePropertyChange on the progressbar in the EDT.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • Yes, this is according to the principle that any changes to the states of components should be done from the Event Dispatch Thread. Swing was apparently designed in this way (single threaded) to avoid too much complexity. Any calls from outside could cause potential interblocking. My understanding is that invokeLater() places a call at the end of a sort of execution queue. – James P. Jul 04 '10 at 13:48
3

Use a model instead of the JProgressBar directly:

DefaultBoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar bar = new JProgressBar(model);

// Somewhere else, perhaps in another Thread
model.setValue(i)

The following example works fine:

public static void main(String[] args) throws InterruptedException {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200, 100);
    frame.setVisible(true);
    final DefaultBoundedRangeModel model = new DefaultBoundedRangeModel();
    frame.add(new JProgressBar(model));
    Thread t = new Thread(new Runnable() {
        public void run() {
            int i = 1;
            model.setMinimum(0);
            model.setMaximum(100);
            try {
                while (i <= 100 || true) {
                    model.setValue(i);
                    i++;
                    Thread.sleep(50);
                }
            } catch (InterruptedException ex) {
                model.setValue(model.getMaximum());
            }
        }
    });
    t.start();

    Thread.sleep(2000);

    t.interrupt();
}
mhaller
  • 14,122
  • 1
  • 42
  • 61
  • Yes, it works. See BasicProgressBarUI lines 1226-1229 in JDK1.6.0_20, which issues a repaint() resulting in Toolkit.getEventQueue().postEvent(e); – mhaller Jul 04 '10 at 19:06
1

The best advice for your situation is to use SwingWorker. Check out the API at http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

Override process method to update value of progress bar ( then it will be done correctly on EDT)

More info can be obtained at http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html

Eugene Ryzhikov
  • 17,131
  • 3
  • 38
  • 60
1

Per eugener, SwingWorker is definitely what you want to be using here, or any time a long-running task is spawned that could otherwise lock up your GUI prior to completion. A full tutorial on using progress bars with SwingWorker is available from Sun^H^H^HOracle here:

http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html

Starchy
  • 103
  • 6
1

Thanks All. I solved in this way

try{
       jProgBar.setIndeterminate(true);
       jProgBar.setStringPainted(true);
       jProgBar.setBorderPainted(true);
       new Thread(new Runnable() {
           public void run() {
               ...
               // here is code that i've to wait
               // after this i stop my jProgressBar
               ...
               jProgBar.setStringPainted(false);
               jProgBar.setBorderPainted(true);
               jProgBar.setIndeterminate(false);
       }
       }).start();
   }
   catch(IllegalStateException ex){
       //some code
   }
raf
  • 1,121
  • 3
  • 13
  • 14
0

Putting this snippet

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        jProgBar.repaint();
    }
}

Between 'i++' and 'Thread.sleep()' should do the job. To get it compiling, mark jProgBar as 'final'.

Vanya
  • 3,091
  • 2
  • 18
  • 12