0

Hello I want to update my JProgress Bar with the help of a Swing Worker class. I searched the other questions on this topic in this forum and took some code of a solution but in my case i does not work:( I have two classes: In the first class i create an object of the Swing Worker class BitmapFilterParralelGrey with this code:

Greyscale.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent evt) {



                int numThreads = Runtime.getRuntime().availableProcessors();
                int HeightPerThread = image.getHeight() / numThreads;
                BitmapFilterParallelGrey[] bitmapFilter = new BitmapFilterParallelGrey[numThreads];
                int startRow = 0, endRow = 0;
                for (int i = 0; i < numThreads; ++i) {
                    startRow = i * HeightPerThread;
                    endRow = startRow + HeightPerThread;
                    bitmapFilter[i] = new BitmapFilterParallelGrey(image,
                            startRow, endRow);

                    bitmapFilter[i].addPropertyChangeListener(new PropertyChangeListener() {

                          @Override
                            public void propertyChange(PropertyChangeEvent e) {
                                if ("progress".equals(e.getPropertyName())) {
                                    BitmapViewer.ProgressBar.setIndeterminate(false);
                                    BitmapViewer.ProgressBar.setValue((Integer) e.getNewValue());

                                }
                            }
                        });
                    bitmapFilter[i].execute();

                }


                for (int i = 0; i < numThreads; i++) {
                    try {
                        bitmapFilter[i].get();
                    } catch (ExecutionException | InterruptedException e) {
                        e.printStackTrace();
                }
                    }


                showImage();

        }
    });

as the execution in the SwingWorker class shall be threaded i create several objects in the loop. In my second class BitmapFilterParallelGrey i filter an image in the doInBackground() and set the ProgressValue. The code:

public class BitmapFilterParallelGrey extends SwingWorker<Void, Void> {
BufferedImage image;
private int startRow, endRow;


public BitmapFilterParallelGrey(BufferedImage image, int startRow, int endRow){
    this.image = image;
    this.startRow= startRow;
    this.endRow= endRow;

    }
@Override
public Void doInBackground() throws Exception {

    int width = image.getWidth();

    for(int i=startRow; i<endRow; i++)
    {
        for(int j=0; j<width; j++)
        {

        //Filter image

}
        setProgress(i/100);

        Thread.sleep(10);

    }
    return null;
}


}

the Problem ist that the Progress Bar updated when the filtering is done (100%). Why doesnt it update while it filters in the background? Thanks!

Jan_K.
  • 1
  • 2

1 Answers1

0

I can think of a couple of reasons that might give you funny results. One reason could have to do with your throws Exception {. Have you tried checking to see if any exceptions are thrown that you haven't caught? I am still quite new to Java, I have only been programming my own work for the last couple of weeks, so I am still not familiar with what Java can fix on its own and what it can't. A couple of other things that could do it.

setProgress(int value);

Assuming your progress bar is for values between 0 and 100, perhaps solve for the percentage in the setProgress method. So something like:

setProgress((int)((100*(i - startRow))/(endRow - startRow)));

Or perhaps you should just try casting an int like this setProgress((int)(i/100));

Maybe, the only reason it works at 100% is that that is the point that i/100 equals an integer.

Also, this may be trivial, but when I set my progress bar's new value, I did it like so: BitmapViewer.ProgressBar.setValue(bitmapFiller[i].getProgress());

One final reason I can think of is does your code execute so fast that it only catches the PropertyChange on the last occasion that PropertyChange is fired.

From the Manual:

Because PropertyChangeListeners are notified asynchronously on the Event Dispatch Thread multiple invocations to the setProgress method might occur before any PropertyChangeListeners are invoked. For performance purposes all these invocations are coalesced into one invocation with the last invocation argument only.

I hope I have understood your code enough to be helpful.

SimpleProgrammer
  • 323
  • 3
  • 25