-2

I have written code using swing libs, that when added an actionlistener, won't update a progressBar.

Without a button and action listener, it works great. How to force a progressBar update as simply and cleanly as possible? Appended code is an easy to understand example that sums up my problem. If you comment out an ActionPerformed method and execute the program from main, it works just fine.

Do not just paste code whithout explaining.

ps.: I have seen this: swing progressBar threading

public class Okno {

    private JProgressBar progressBar = new JProgressBar(0,306);
    JFrame f = new JFrame("JProgressBar Sample");
    JButton b = new JButton("start");
    ActionListener a = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            barupdate();
        }
    };


    private void barupdate(){
        for(int p = 1; p<308;p=p+2){
            System.out.println(p);

            progressBar.setValue(p);

                try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
       }
 }

private Okno(){

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    progressBar.setStringPainted(true);

    f.add(progressBar, BorderLayout.SOUTH);
    f.add(b, BorderLayout.NORTH);
    b.addActionListener(a);
    f.setSize(300, 300);
    f.setVisible(true);

}

public static void main(String[] args) {
    Okno  okno = new Okno();
}
}
Community
  • 1
  • 1
jib fashr
  • 315
  • 2
  • 15
  • This is a very common problem which generally solved the same way, the best solution in this case is normally using a `SwingWorker`, [for example](http://stackoverflow.com/questions/12020949/jprogressbar-isnt-progressing/12021971#12021971). You could also have a look at [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details about the issue. In most cases, using another `Thread` isn't the best choice in of itself, as Swing is not thread safe and you have to take extra precautions to update the UI, which `SwingWorker` provides for you for free ;) – MadProgrammer Feb 19 '17 at 02:07
  • @MadProgrammer, `the best solution in this case is normally using a SwingWorker... wyou should have a look at Concurrency in Swing,` - wish I thought of that. – camickr Feb 19 '17 at 02:14
  • @camickr The question should be closed, but I know you have issues with people doing that, so I left my comment (supporting you answered) and left – MadProgrammer Feb 19 '17 at 03:39
  • *"How to force a progressBar update as simply as possible?"* **Hire someone** that knows how to deal with updating a GUI while a long running task is being performed. If you want to complete the task yourself, prepare to learn this (not simple) technique. – Andrew Thompson Feb 19 '17 at 05:53

2 Answers2

1

The problem is you have a loop where you are adjusting the progress bar setting that is being called from an action listener. The problem is, the bar won't update until after the listener is finished. And so you will get no updates. Not only that but you will bog down the gui because the window can't react to mouseclicks etc while you are in that action listener.

So the best way to handle this is instead to create a swing timer, in the action listener, and put the code for updating the button there, and start the timer in the action listener.

The timer should only update the bar once. and you should allow the fact that the swing timer will be called multiple times, to play the part of the repetitiveness. So you don't want to have any loops in your code.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
0
Thread.sleep(50);

Don't use Thread.sleep(...). This will prevent the GUI from repainting itself until the loop has finished executing.

Instead you can use a SwingWorker.

Read the section from the Swing tutorial on Concurrency in Swing which has more information and contains a working example with a SwingWorker.

Also, look at the tutorial table of contents. There is a section on How to Use ProgressBars that also contains a working example. The tutorial is the first place to look for examples.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • code is an example that sums up my problem, and sleep() method is there just to make progress on a prograss bar slower. If you remove actionlistening code and start progressbar code from main it works fine. – jib fashr Feb 19 '17 at 01:57
  • I know. When you start the progress bar from the main() the code executes in a different Thread. When you start the progress bar in the ActionListener the code executes on the `Event Dispatch Thread (EDT)` which is the Thread that paint the GUI. So you need to start your progress bar in a separate Thread which is why you need to read the tutorial to better understand how Swing works. `The tutorial has working examples`. – camickr Feb 19 '17 at 02:03