java - 带有 SWT 的进度条

标签 java eclipse multithreading swt progress-bar

我试图在窗口的状态行中添加进度条,其中状态行上已经有很多文本项(例如当前时间)。我想在将数据加载到窗口的一个框架(称为数据)时在进度条中取得进展。我对此几乎没有问题。 (我对 SWT 很陌生,所以请多多包涵。)

在 makeProgress 方法中,我尝试在进度条中取得进展。以下是我的代码

public class Progress extends ContributionItem {

    private static org.eclipse.swt.widgets.ProgressBar progressBar;

    public Progress(final String id) {
        super(id);
    }

    @Override
    public void fill(final Composite parent) {
        if (progressBar == null) {
            progressBar = new ProgressBar(parent, SWT.None);
        }
        progressBar.setVisible(false);
    }

    public void makeProgress(final int loaded_data, final int total_data) {
        logger.log("progressitem do progress", new String [] {""});
        Display.getDefault().asyncExec(new Runnable() {
            public void run() {
                Progress.progressBar.setVisible(true);
                Progress.progressBar.setMaximum(total_data);
                Progress.progressBar.setSelection(loaded_data);
            }});
        if (loaded_data == total_data) {
            //When all of the data are loaded, make progress bar disappear
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    Progress.progressBar.setVisible(false);
                }});
        }
    }
}

其中 makeProgress 由处理状态栏的类调用,如下所示: change 是一种
if (change.getChange() == hasChanged.UPDATE_PROGRESS) {
            progress.makeProgress(change.getLoaded_data(), change.getTotal_data);

问题:

1)我的进度条进展非常缓慢。可能需要正确使用线程吗?

2)虽然我试过了,但我不太清楚Display.getDefault.asyncExec和syncExec之间的区别。

3) 另一个问题是,当进度条在进行时,整个 GUI 没有响应。如何使进度条独立于 GUI 上的其他 View ?

我非常感谢任何有关此的指示或建议。

最佳答案

好的,这是一个带有 ProgressBar 的简单示例这是从另一个线程不断更新的。 GUI 始终保持响应:

private static Shell        shell;
private static ProgressBar  progressBar;

public static void main(String[] args)
{
    Display display = new Display();
    shell = new Shell(SWT.SHELL_TRIM);
    shell.setText("StackOverflow");
    shell.setLayout(new GridLayout(1, false));

    setUpContent();
    setUpStatusBar();

    updateProgressBar();

    shell.pack();
    shell.setSize(400, 200);
    shell.open();

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
        {
            display.sleep();
        }
    }
    display.dispose();
}

private static void updateProgressBar()
{
    new Thread(new Runnable()
    {
        private int                 progress    = 0;
        private static final int    INCREMENT   = 10;

        @Override
        public void run()
        {
            while (!progressBar.isDisposed())
            {
                Display.getDefault().asyncExec(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        if (!progressBar.isDisposed())
                            progressBar.setSelection((progress += INCREMENT) % (progressBar.getMaximum() + INCREMENT));
                    }
                });

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

private static void setUpStatusBar()
{
    Composite statusBar = new Composite(shell, SWT.BORDER);
    statusBar.setLayout(new GridLayout(2, false));
    statusBar.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));

    progressBar = new ProgressBar(statusBar, SWT.SMOOTH);
    progressBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false));
    progressBar.setMaximum(100);

    Label status = new Label(statusBar, SWT.NONE);
    status.setText("Some status message");
    status.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false));
}

private static void setUpContent()
{
    Composite content = new Composite(shell, SWT.NONE);
    content.setLayout(new GridLayout(2, false));
    content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    Text text = new Text(content, SWT.BORDER | SWT.MULTI);
    text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}

我猜为什么您的应用程序卡住并且进度没有顺利更新是因为它在主线程而不是单独的线程上执行繁重的计算/长时间运行的任务。

关于java - 带有 SWT 的进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25432418/

相关文章:

java - 如何在数组中查找大于、小于或等于某个值的数字?

java - ( Activity (上下文))。getIntent()。getExtras()返回null

java - android setAdapter 不触发 getView 或不构建 ListView

java - Eclipse 未检测到 servlet 库

java - 创建和杀死线程与使用 .notify () 和 .wait ()

java - tcp 服务器的奇怪行为(使用winsock)

c# - 获取和设置简单的静态属性线程安全吗?

java - 文件写入器和文件读取器错误

java - 在Eclipse中仅调试一个线程

java - 设置类路径,但Java程序(使用Apache外部jar)未在CMD行上运行