1

Here is a little a example:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        int x = 0;
        while (jProgressBar1.getValue() < 100) {
            try {
                Thread.sleep(50);
                x++;
                jProgressBar1.setValue(x);
                jProgressBar1.repaint();
            } catch (InterruptedException ex) {
                Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(jProgressBar1.getValue());
        }
    }

System.out.println(jProgressBar1.getValue()); returns digits to IDE output, but jProgressBar1 doesn't draw this value. What's wrong with this code? Please help.

3

2 Answers 2

3

Never use Thread.sleep() in Swing thread. Use javax.swing.Timer instead.

Example:

private void jButton1ActionPerformed(ActionEvent evt) {                                         
    final Timer t = new Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            jProgressBar1.setValue(jProgressBar1.getValue() + 1);
            if (jProgressBar1.getValue() == 100) {
              ((Timer) e.getSource()).stop();
            }
        }
    });
    t.start();
}
Sign up to request clarification or add additional context in comments.

3 Comments

Yes it works, but it fills progressbar very-very fast. How can i change a dalay?
@alexkowalski It's the first parameter for the constructor of the Timer. Change the second line to: final Timer t = new Timer(250, new ActionListener() {
it doesn't help! Not 1000 not 10 000... Nothing happens, just fills very fast and that's all.
-1

The problem is that you're calling .repaint() in the same thread you're doing your "work" (Thread.sleep). "repaint() does not invoke paint() directly. It schedules a call to an intermediate method, update(). Finally, update() calls paint()...". This means you're scheduling a bunch of repaint() calls, but they aren't being processed. I would also bet that once the value does reach 100 the progress bar jumps to being full, which is because the main thread has ended and all of the repaint() calls are finally being processed.

In order to make jProgressBars work, you have to have their repainting occur in a different thread than the one in which you are doing work (which notably should also be in a different thread - This is also true for most Swing updating). Try starting this Runnable in a new thread before you invoke your code:

public class ProgressBarPainter implements Runnable{
    public JProgressBar jProgressBar1;
    public void run(){
        while(true){
            try {
                Thread.sleep(50);
                jProgressBar1.repaint();
            } catch (InterruptedException ex) {
               break;
            }
        }
    }
}

Example functioning code to use the above:

public class Frame extends JFrame {

    private static final long serialVersionUID = 1L;
    private JProgressBar bar;

    public Frame(){
        JPanel contentPanel = (JPanel) getContentPane();

        JButton b = new JButton("Do Process");
        b.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                ProgressBarPainter p = new ProgressBarPainter();
                p.jProgressBar1 = bar; //Fill in with the bar you want painted
                Thread t = new Thread(p);
                t.start();

                Worker w = new Worker();
                w.jProgressBar1 = bar;
                Thread t2 = new Thread(w);
                t2.start();
            }

        });
        contentPanel.add(b, BorderLayout.SOUTH);

        bar = new JProgressBar();
        contentPanel.add(bar, BorderLayout.CENTER);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Frame();
    }

}

class Worker implements Runnable{
    public JProgressBar jProgressBar1;
    public void run(){
        int x = 0;
        while(jProgressBar1.getValue() != jProgressBar1.getMaximum()){
            try {
                //Do some work
                Thread.sleep(50);
                //Update bar
                jProgressBar1.setValue(x++);
            } catch (InterruptedException ex) {
               break;
            }
        }
    }
}

class ProgressBarPainter implements Runnable{
    public JProgressBar jProgressBar1;
    public void run(){
        while(true){
            try {
                Thread.sleep(50);
                jProgressBar1.repaint();
            } catch (InterruptedException ex) {
               break;
            }
        }
    }
}

2 Comments

It doesn't work without it anyway... I think there is a problem with thread. I have tested it with another code: int values[] = {1,5,9,20,22,25,45,50,55,70,80,90,99,100}; for (int value : values) { try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(MainWindow.class.getName()).... }` jProgressBar1.setValue(value); } }
Do not use Thread.sleep() as it will freeze your Swing application. Instead you should use a javax.swing.Timer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.