My JProgressBar is not Updating Until it is 100%
java, jprogressbar, runnable, swing, swingworker
Solution
You thread executes `SwingUtilities.invokeLater`. You're effectively running on Swing's `Event Dispatch Thread`. Not sure what are you trying to achieve. But it looks like you are blocking `EDT` and your `while` loop is not updated as `MySetValue` is not executed.
Consider using `SwingWorker` for lengthy operations. How to Use Progress Bars demonstrates use of `SwingWorker` with `JProgressBar`.
Make sure you call `setValue` method from the `Event Dispatch Thread`. You can use `SwingUtilities.invokeLater` for that. Read more about Threads and Swing.
Consider this simplified sample:
public static void main(String[] arguments) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
final JProgressBar bar = new JProgressBar(0, 100);
Thread t = new Thread(){
public void run(){
for(int i = 0 ; i < 100 ; i++){
final int percent = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(percent);
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
};
frame.add(bar);
frame.pack();
frame.setVisible(true);
t.start();
}
Problem
Ok, I have the following code. ``` public class MyProgressBar extends JPanel implements MyData, Serializable { /** * */ public static final int MAX = 10000; public static final int WIDTH = 400; public static final int HEIGHT = 75; private JProgressBar MyBar = new JProgressBar( SwingConstants.HORIZONTAL, 0, MAX ); private JFrame MyFrame = new JFrame(); private int MyValue = 0; private Thread MyThread = new Thread( new ProgressThread() ); public MyProgressBar() { add(MyBar); int x = ( MyData.SCREEN.width / 2 ) - ( WIDTH / 2); int y = ( MyData.SCREEN.height / 2 ) - ( HEIGHT / 2); this.setBounds( x, y, WIDTH, HEIGHT ); MyFrame.setBounds( x, y, WIDTH, HEIGHT ); MyFrame.setUndecorated(true); MyFrame.getContentPane().setSize( new Dimension( WIDTH, HEIGHT ) ); MyFrame.setMinimumSize( new Dimension( WIDTH, HEIGHT ) ); MyFrame.setPreferredSize( new Dimension( WIDTH, HEIGHT ) ); MyFrame.setSize( new Dimension( WIDTH, HEIGHT ) ); MyFrame.setVisible(false); MyFrame.getContentPane().setLayout(null); MyBar.setStringPainted( true ); MyBar.setBorderPainted( true ); MyBar.setValue( 0 ); MyBar.setBounds( 0, 0, WIDTH, HEIGHT ); MyFrame.add( MyBar ); MyFrame.pack(); MyFrame.repaint(); } public void MyUpdateBar() { MyBar.setValue( MyValue ); MyBar.repaint(); MyFrame.repaint(); this.repaint(); //dbug.Message( "MYPROGRESSBAR", "MyUpdateBar", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue ); } public void MySetValue( int percent ) { MyValue = (int)( MAX * ( (double)percent / 100.0 ) ); MyUpdateBar(); //dbug.Message( "MYPROGRESSBAR", "MySetValue", "Value is %3.2f %d percent was %d", MyBar.getPercentComplete(), MyValue, percent ); } public void CreateAndShow () { MyFrame.setVisible(true); MyThread.start(); } public void HideAndClear () { MyThread.stop(); //frame.setVisible(false); } class ProgressThread implements Runnable { public void run() { EventQueue.invokeLater(new Runnable() { public void run() { while( MyValue < MyBar.getMaximum() ) { MyBar.setValue( MyValue ); MyBar.repaint(); MyFrame.repaint(); dbug.Message( "MYPROGRESSBAR", "THREAD", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue ); } } }); } } } ``` As you can see, I have created a class that I want to have show the progress. What happens is I instantiate the class. Load my XML file, then as I am parsing data, I am calling to update the MyValue which I see when I let my dbug messages come out. However, the bar itself does not even show until it is 100% complete. I have read about threading and following someone else's example and if I left it as his example it worked. If I made a few tweaks (changing a loop in the thread to populate the setvalue of the progress bar to read a value) it does not even show until it is 100. What did I do wrong? Thanks!