javaswingfor-loopjprogressbar

Creating a Progress Bar to update with results from a for loop in java


I have created a for loop that counts from 0 to 850000. I have chosen a high number because I want to create a progress bar that will update using the results in the for loop. Here is the code that I have so far.

public class ProgressBarTest extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {





        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ProgressBarTest frame = new ProgressBarTest();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ProgressBarTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        for(int i = 850000; i>0; i--) {
            System.out.println("i = " + i);
        }

    }

}

I cannot seem to find a way to get a progress bar to update using a for loop. I did create a progress bar that worked on a timer but that is not what I want it to do. I basically want it to update from 0% to 100%. This does seem simple to me but I have been stuck on it for a while. I appreciate any sort of sample code that will help me to understand how it works.


Solution

  • Here is the complete example, using SwingWorker proposed by the Saran

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.util.List;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.SwingWorker;
    import javax.swing.border.EmptyBorder;
    
    public class ProgressBarTest extends JFrame {
    
        private static final long LOOP_LENGTH = 85000000;
    
        private JPanel contentPane;
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
    
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        ProgressBarTest frame = new ProgressBarTest();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public ProgressBarTest() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 450, 300);
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            contentPane.setLayout(new BorderLayout(0, 0));
            JProgressBar progress = new JProgressBar();
            progress.setStringPainted(true);
            contentPane.add(new JLabel("Loop progress is: "), BorderLayout.NORTH);
            contentPane.add(progress, BorderLayout.SOUTH);
            setContentPane(contentPane);
            ProgressWorker worker = new ProgressWorker(progress);
            worker.execute();
        }
    
        private static class ProgressWorker extends SwingWorker<Void, Integer> {
            private final JProgressBar progress;
    
            public ProgressWorker(JProgressBar progress) {
                this.progress = progress;
            }
    
            @Override
            protected Void doInBackground() throws Exception {
                for (long i = LOOP_LENGTH; i > 0; i--) {
                    final int progr = (int) ((100L * (LOOP_LENGTH - i)) / LOOP_LENGTH);
                    publish(progr);
                }
                return null;
            }
    
            @Override
            protected void process(List<Integer> chunks) {
                progress.setValue(chunks.get(chunks.size() - 1));
                super.process(chunks);
            }
    
            @Override
            protected void done() {
                progress.setValue(100);
            }
        }
    }