Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JProgressBar does not update within the loop

I am currently self-studying Java. I've been trying different things like JRadioButtons, JcomboBoxes etc. Now, I'm trying to use JProgressBars but it doesn't seem to work properly.

Relevant piece of code:

JProgressBar progress;
JButton button;     //Fields of the class

progress=new JProgressBar(JProgressBar.HORIZONTAL,0,100);
button=new JButton("Done");    //Done from methods

progress.setValue(0);
progress.setStringPainted(true);
progress.setBorderPainted(true);  //Also done from methods

button.addActionListener(this);   //Also done from methods

When button is clicked, I want to show the JProgressBar go from 0% to 100%. Here is the relevant portion of the actionPerformed method:

public void actionPerformed(ActionEvent e)
{

        for(int i=0;i<=progress.getMaximum();i++)
        {
            progress.setValue(i);
            /*try{
                Thread.sleep(10);
            }catch(InterruptedException ex)
            {
                System.err.println("An error occured:"+ex);
                ex.printStackTrace();
            }*/
        }


        progress.setValue(progress.getMinimum());
}

I've added both progress and button into a JPanel and the panel into a JFrame on which I use setVisible(true);.

The problem here is, whenever I press the JButton button, the JProgressBar progress does not go from 0% to 100%. Instead, nothing happens. If I uncomment the try...catch block, and then press button, the program "freezes" for a moment and then continues. This time too, The JProgressBar stays at 0% and I never see it moving. I've also tried a repaint(); just after the try...catch block but the same thing happened.

I've tried adding

System.out.println(i+"");

inside the for loop in actionPerformed and this printed numbers 0 to 100 in the terminal. So, I'm sure that the loop runs.

How can I solve this problem?

like image 996
Spikatrix Avatar asked Jun 11 '26 06:06

Spikatrix


1 Answers

  • Swing is single threaded,

  • all updates must be done on EDT,

  • all events in current EDT are painted in GUI in one moment,

  • Thread.sleep to lock execution of event in EDT, repaint can be painted at the end of for_loop, after all lock(s) from Thread.sleep are executed, more in Oracle trail - Concurency in Swing and EventDispatchThread


output from AWT (Swing) Listener - ActionListener, should be done if all events inside actionPerformed are executed, then there is executed only progress.setValue(progress.getMinimum());, doesn't matter if is there Thread.sleep or not

public void actionPerformed(ActionEvent e) -> progress.setValue(progress.getMinimum());

  • use SwingWorker or Runnable#Thread with progress.setValue(i); wrapped into invokeLater

  • for better help sooner post an SSCCE/MCVE, short, runnable, compilable

like image 181
mKorbel Avatar answered Jun 12 '26 23:06

mKorbel