0

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.

David Gardener
  • 93
  • 2
  • 13

2 Answers2

3

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);
        }
    }
}
Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
2

You need to use SwingWorker, When a Swing program needs to execute a long-running task, it usually uses one of the worker threads. So, try this:

public class JProgressBarTest extends SwingWorker<Void,Integer> {

private JProgressBar jpb;
  public ProgrssBarTest(JProgressBar jpb){
    this.jpb = jpb;
  }
  
  @Override
  protected void process(List<Integer> chunks){
    int i = chunks.get(chunks.size()-1);
    jpb.setValue(i);
  }

  @Override
  protected void doInBackground() throws Exception{
    int x = 0;
    for(int i = 850000; i>0; i--) {
        publish(x); //replace x with the number you want to increment the progressbar each time pubish is called
        x = x + i; //or replace i with the increment you want
        System.out.println("i = " + i);
    }
  }

  @Override
  protected void done(){
    try{
      get();
    }catch(ExecutionException |InterruptedException e){
      ;
    }
  }

}

in your class, replace the loop by calling new class of the class i wrote above and pass it a new JProgressBar() and adding .execute(), like this:

new JProgressBarTest(new JProgressBar()).execute();
Balastrong
  • 4,336
  • 2
  • 12
  • 31
Abdane
  • 137
  • 1
  • 12
  • This is excellent. I have used Sergiy Medvynskyy's answer but I might use this sometime in the future as I like the fact that you can choose how much to increment the progress bar by each time. – David Gardener Nov 21 '17 at 10:20