JProgressBar is not updated in a loop

I am currently learning Java. I've tried different things like JRadioButton

s, JcomboBox

es, etc. Now I am trying to use JProgressBar

, but it doesn't work as expected.

Relevant code snippet:

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

      

On click, button

I want to show that the JProgressBar goes from 0% to 100%. Here's the relevant part of the method actionPerformed

:

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 added the two progress

and button

to a JPanel and a panel JFrame, which I use setVisible(true);

.

The problem here is that whenever I click on the JButton the button

JProgressBar progress

does not go from 0% to 100%. Instead, nothing happens. If I uncomment the block try...catch

and then press button

, the program freezes for a moment and then continues. This time the JProgressBar stays at 0% and I never see it moving. I also tried repaint();

right after the block try...catch

, but the same thing happened.

I tried adding

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

      

inside the loop for

in actionPerformed

, and these are printed numbers from 0 to 100 in the terminal. So I'm pretty sure the loop works.

How can I solve this problem?

+3


source to share


3 answers


  • Swing single-threaded,

  • all updates must be done on EDT,

  • all events in the current EDT are colored in the GUI in one moment,

  • Thread.sleep

    to block the execution of an event in the EDT, redraw can be painted at the end of for_loop, after all the locks (s) from have been Thread.sleep

    completed, more in Oracle trail - Compatibility in Swing and EventDispatchThread


output from AWT (Swing) Listener - ActionListener

, should be executed if all events inside actionPerformed

are executed, then only is executed progress.setValue(progress.getMinimum());

, it doesn't matter if it exists Thread.sleep

or not



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

      


  • use SwingWorker

    or Runnable#Thread

    with progress.setValue(i);

    enclosed ininvokeLater

  • for better help post soon SSCCE

    / MCVE

    , short, runnable, compilable

+4


source


You have to put the following piece of code in a new thread

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());
}

      

Something like that



public void actionPerformed(ActionEvent e)
{
    new Thread(){
        public void run(){
            for(int i=0;i<=progress.getMaximum();i++)
            {
                progress.setValue(i);
                try{
                    sleep(10);
                }catch(InterruptedException ex)
                {
                    System.err.println("An error occured:"+ex);
                    ex.printStackTrace();
                }
            }
        }
    }.start();
    progress.setValue(progress.getMinimum());
}

      

Not tested, progress

copy should be final

possible

+1


source


As far as your code is concerned, everything looks legal. Doesn't seem to give any problem regardless of whether or not the thread initiates.

I suggest you do this:

//for testing purposes
progress.setValue(progress.getMinimum());

      

And then make the progress bar value 50. Remove the thread code and use a for loop with the "<50" condition.

If all else fails, this will surely shed some light: JProgress Bar: Working!

Let me know about the results.

+1


source







All Articles