javaswingappletjprogressbarswingutilities

java applet: JProgressBar updating/refreshing only at completion


I'm just trying to iterate in for loop and updating values of JProgressBar inside the loop, initiating SwingUtilities.invokeLater.. but it's only updating after completion. Below is my simple code:

import java.awt.Color;
import java.awt.Rectangle;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ProgressBar extends JApplet {
    JProgressBar pg = null;
    JPanel panel = null;
    JButton start = null;
    int i;

    public void init() {
        pg = new JProgressBar(0, 100);
        pg.setStringPainted(true);
        this.setSize(1200, 600);
        this.setLayout(null);
        panel = new JPanel();
        panel.setLayout(null);
        panel.setBackground(Color.white);
        this.setContentPane(panel);
        this.setVisible(true);
        pg.setBounds(new Rectangle(630, 20, 150, 30));
        add(pg);


        start = new JButton("start");
        start.setBounds(new Rectangle(330, 20, 200, 30));
        start.setBackground(Color.lightGray);
        panel.add(start);

        start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pg.setValue(0);
                pg.setStringPainted(true);

                for (i = 0; i <= 100; i = i + 1) {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            try {
                                pg.setValue(i);
                                java.lang.Thread.sleep(100);
                            } catch (Exception e) {}
                        }
                    });
                }
            }
        });
    }
}

How to reflect the updation of progress bar in incrementing way as it's updating only 100% after for loop completion.


Solution

  • You have to process any calculation/handling stuff in a separate thread and update UI within the Event Dispatch Thread (EDT):

        start.addActionListener ( new ActionListener ()
        {
            public void actionPerformed ( ActionEvent e )
            {
                pg.setValue ( 0 );
                pg.setStringPainted ( true );
                new Thread ( new Runnable ()
                {
                    public void run ()
                    {
                        for ( i = 0; i <= 100; i = i + 1 )
                        {
                            SwingUtilities.invokeLater ( new Runnable ()
                            {
                                public void run ()
                                {
                                    pg.setValue ( i );
                                }
                            } );
                            try
                            {
                                java.lang.Thread.sleep ( 100 );
                            }
                            catch ( Exception e )
                            {
                                //
                            }
                        }
                    }
                } ).start ();
    
            }
        } );
    

    Any action/mouse/key and other listeners methods are always executed within the EDT thread, so you have to move your code into a separate thread. Otherwise you will do all the calculations/handling inside the EDT thread (and that causes the UI stuck).