Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progress Bar does not update Immediately

I am attempting to use both a Progress Bar and a Label to show the progress of a discreet number of operations. Every time I update both, the label updates immediately, while the progress bar has a noticeable delay before it changes.

I have a test dialog where, when I press a button, I update both the label and the progress bar to reflect an increase of 1. This happens immediately in the code without any loops or threads being called (eliminating any threading-related issues as being the cause) - just a simple changing of values. When this happens, the Label updates immediately, while the Progress Bar waits for about half a second before updating visually. This leads to instances where it will say, for instance, "2 out of 3" when it briefly but noticably shows 1/3 of the bar filled.

enter image description here

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

public class ProgressBarTest extends Shell {

    private ProgressBar progressBar;
    private Label lblXOfX;
    private Button btnGo;

    public static void main(String args[]) {
        try {
            Display display = Display.getDefault();
            ProgressBarTest shell = new ProgressBarTest(display);
            shell.open();
            shell.layout();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public ProgressBarTest(Display display) {
        super(display, SWT.SHELL_TRIM);
        createContents();
    }

    protected void createContents() {
        setText("SWT Application");
        setSize(450, 300);
        setLayout(new GridLayout());

        progressBar = new ProgressBar(this, SWT.NONE);
        progressBar.setMaximum(3);
        progressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        lblXOfX = new Label(this, SWT.NONE);
        lblXOfX.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
        lblXOfX.setText("x of x");

        btnGo = new Button(this, SWT.NONE);
        btnGo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent arg0) {
                go();
            }
        });
        btnGo.setText("Go");
    }

    @Override
    protected void checkSubclass() {
        // Disable the check that prevents subclassing of SWT components
    }

    protected void go() {

        int iCur = progressBar.getSelection();
        iCur++;
        if (iCur > progressBar.getMaximum())
            iCur = 0;

        progressBar.setSelection(iCur);
        lblXOfX.setText(String.format("%s of %s", iCur, progressBar.getMaximum()));
    }

}

This occurs despite using the Progress Bar's internal variable to keep track of the value, and using that value to update the label.

Notably, changing the progress bar's "State" property to "ERROR" or "PAUSED" eliminates the issue.

Is this some sort of bug with animation? Is this just an issue with a specific version of Windows, such as the Windows 7 that I am using? Or is it something else?

like image 220
Southpaw Hare Avatar asked Sep 11 '13 14:09

Southpaw Hare


1 Answers

It looks like this may be a bug in the Windows version of ProgressBar as the code works on Linux and Mac OS X.

The Windows version of ProgressBar.setSelection does have some code that says it is trying to deal with an issue that sounds like this but it is only done if the state is not Normal - which may be be why it works on the Error and Paused state. Their fix just does the selection again so maybe calling setSelection twice would work!

like image 151
greg-449 Avatar answered Oct 21 '22 22:10

greg-449