问题
I am currently self-studying Java. I've been trying different things like JRadioButton
s, JcomboBox
es etc. Now, I'm trying to use JProgressBar
s 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?
回答1:
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) fromThread.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
orRunnable#Thread
withprogress.setValue(i);
wrapped intoinvokeLater
for better help sooner post an
SSCCE
/MCVE
, short, runnable, compilable
回答2:
You have to put following piece of code to 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 this
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
instance should be final
maybe
回答3:
As far as your code goes, it all looks legit. Doesn't seem to give any issue regardless of not initiating a thread.
What I suggest you do is remove this:
//for testing purposes
progress.setValue(progress.getMinimum());
And then make the value of the progress bar 50. Remove the thread code, and use the for loop with the condition "< 50".
If all else fails, this will surely shed some light: JProgress Bar: Working!
Let me know of the outcome.
来源:https://stackoverflow.com/questions/29727991/jprogressbar-does-not-update-within-the-loop