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.
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?
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With