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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With