我正在尝试使用进度条和标签来显示谨慎操作次数的进度。每当我更新两者时,标签立即更新,而进度条在更改前有明显的延迟。
我有一个测试对话框,当我按下按钮时,我更新标签和进度条以反映增加1.这在代码中立即发生,没有任何循环或线程被调用(消除任何与线程相关的问题都是原因) - 只是简单地更改值。发生这种情况时,Label会立即更新,而Progress Bar会在视觉更新之前等待大约半秒钟。这导致例如,当它短暂但明显地显示填充的1/3时,它会说“2中3”。
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()));
}
}
尽管使用进度条的内部变量来跟踪值,并使用该值更新标签,但仍会出现这种情况。
值得注意的是,将进度条的“状态”属性更改为“ERROR”或“PAUSED”消除了此问题。
这是动画的某种错误吗? 这只是Windows 的特定版本的问题,例如我正在使用的Windows 7?还是别的什么?
答案 0 :(得分:4)
看起来这可能是Windows版ProgressBar
中的错误,因为该代码适用于Linux和Mac OS X.
Windows版ProgressBar.setSelection
确实有一些代码表明它正试图处理一个听起来像这样的问题,但只有当状态不正常时才会这样做 - 这可能就是为什么它可以工作的原因错误和暂停状态。他们的修复只是再次选择,所以可能两次调用setSelection
会起作用!
答案 1 :(得分:1)
您可以关注this tutorial,它描述了如何创建Eclipse作业以执行除EDT之外的长作业,并且只更新组件的状态。 希望这有帮助,干杯!
答案 2 :(得分:1)
我已经使用Windows 7 SP 1和Windows XP SP3下的持续版SWT(4.3 Final Release - 2013年6月5日)测试了您提供的代码。在这两种情况下,进度条都会立即更新。也许更新SWT库会有所帮助。
答案 3 :(得分:1)
几周前我遇到了这个问题,当时使用条形图来显示连续完成约500次操作的进度。我发现这些过程在条形图中途完成之前已经完成了很多。我使用下面的代码作为解决方法:
bargraph.value = (Target + 1)
bargraph.value = (Target)
其中bargraph是对象的名称,目标是您希望它移动到的位置。
因为条形图具有图形方面,即字形效果,所以需要时间来追赶。 即使图形方面显示的值为50,实际的bargraph.value也可能是60!通过将值设置为某个级别,然后将其减1,条形图立即(ish)更新图形方。
修改
如下面的评论所示,当您尝试将值设置为最大值时,上述答案可能无效。
现在,我还没试过这个,但我认为下面的内容可行:
if (bargraph.value <> Target) then
if (Target = bargraph.maximumvalue) then
bargraph.maximumvalue = Target + 1
bargraph.value = (Target + 1)
bargraph.value = (Target)
bargraph.maximumvalue = Target
else
bargraph.value = (Target + 1)
bargraph.value = (Target)
end if
else
end if
正如我所说,未经测试,但原则应该有效。