如何在Eclipse向导中正确更新未知持续时间的操作的进度条? [英] How can I correctly update a progress bar for an operation of unknown duration within an Eclipse wizard?

查看:238
本文介绍了如何在Eclipse向导中正确更新未知持续时间的操作的进度条?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为我的Eclipse插件实现了一个向导,显示了几页。这些页面之一需要一些冗长的初始化,这意味着它由一个SWT表组成,需要由来自外部来源的信息填充。这个源需要首先被激活(一个单一的方法调用,在几秒钟后返回 - 我不能预先知道要准确地花费多长时间),然后才能用作表查看器的输入。这个初始化目前由表模型提供者在第一次需要访问外部源时完成。



因此,当我进入向导页面时,我想显示一个虚拟的进度条,只是一段时间。我的方法如下,但不幸的是根本不起作用:

  private void initViewer(){
IRunnableWithProgress runnable =新的IRunnableWithProgress(){//需要将长时间运行的操作嵌入到向导页面

@Override
public void run(IProgressMonitor monitor)throws InvocationTargetException,InterruptedException {
SubMonitor progress = SubMonitor.convert(monitor);

Thread thread = new Thread(){
@Override
public void run(){
Display.getDefault()。syncExec(new Runnable(){
public void run(){
viewer.setInput(ResourcesPlugin.getWorkspace()。getRoot()); //这将使表提供程序初始化外部源
}
});
}
};

thread.start();

while(thread.isAlive()){
progress.setWorkRemaining(10000);
progress.worked(1);
}

progress.done();
}

};

try {
getContainer()。run(false,false,runnable);
} catch(Exception e){
throw new Exception(Could not access data store,e);
}
}

当向导页面的setVisible( )方法被调用,并且应该在几秒钟后设置查看者的输入。然而,这不会发生,因为最内部的run() - 方法永远不会被执行。



任何提示如何处理长时间运行(确切地说估计不可用)Eclipse向导中的初始化将非常感谢!

解决方案

下面给出了一个关于如何使用的简单示例 IRunnableWithProgress 以及 ProgressMonitorDialog 执行未知数量的任务。首先,从实际执行任务的IRunnableWithProgress实现。这个实现可以是一个内部类。

  public class MyRunnableWithProgress实现IRunnableWithProgress {
private String _fileName;

public MyRunnableWithProgress(String fileName){
_fileName = fileName;
}

@Override
public void run(IProgressMonitor monitor)throws InvocationTargetException,InterruptedException {
int totalUnitsOfWork = IProgressMonitor.UNKNOWN;
monitor.beginTask(执行阅读,请稍候...,totalUnitsOfWork);
performRead(_fileName,monitor); //这只执行任务
monitor.done();
}
}

现在,一个通用的实现方法是将ProgressMonitorDialog 可以创建如下,可以用于需要进度监视对话框的其他地方。

  public class MyProgressMonitorDialog extends ProgressMonitorDialog {

private boolean cancelable;

public MyProgressMonitorDialog(Shell parent,boolean cancellable){
super(parent);
this.cancellable =可取消;
}

@Override
public Composite createDialogArea(Composite parent){
复合容器=(复合)super.createDialogArea(parent);
setCancelable(可取消);
返回容器;
}
}

获得所需的实现后,可以调用该任务如下所示,使用进度对话框进行处理。

  boolean cancellable = false; 
IRunnableWithProgress myRunnable = new MyRunnableWithProgress(receivedFileName);
ProgressMonitorDialog progressMonitorDialog = new MyProgressMonitorDialog(getShell(),可取消);

try {
progressMonitorDialog.run(true,true,myRunnable);
} catch(InvocationTargetException e){
//以最好的方式抓住
抛出新的RuntimeException(e);
} catch(InterruptedException e){
//以最好的方式捕获
Thread.currentThread()。
}

希望这有帮助!


I have implemented a wizard for my Eclipse plug-in, showing several pages. One of these pages needs some lengthy initialization, that means it consists of a SWT table, which needs to be populated by information coming from an external source. This source needs to be activated first (one single method call that returns after a couple of seconds - I can not know in advance how long it will take exactly), before it can be used as input for for the table viewer. This initialization is currently done by the table model provider when it needs to access the external source for the first time.

Therefore, when I enter the wizard page, I would like to show a dummy progress bar that just counts up for a while. My approach was the following, but unfortunately does not work at all:

private void initViewer() {
    IRunnableWithProgress runnable = new IRunnableWithProgress() { // needed to embed long running operation into the wizard page

        @Override
        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
            SubMonitor progress = SubMonitor.convert(monitor);

            Thread thread = new Thread() {
                @Override
                public void run() {
                    Display.getDefault().syncExec(new Runnable() {
                        public void run() {
                            viewer.setInput(ResourcesPlugin.getWorkspace().getRoot()); // this will make the table provider initialize the external source.
                        }
                    });
                }
            };

            thread.start();

            while(thread.isAlive()) {
                progress.setWorkRemaining(10000);
                progress.worked(1);
            }

            progress.done();
        }

    };

    try {
        getContainer().run(false, false, runnable);
    } catch(Exception e) {
        throw new Exception("Could not access data store", e);
    }
}

This method gets then invoked when the wizard page's setVisible()-method is called and should, after a couple of seconds, set the viewer's input. This, however, never happens, because the inner-most run()-method never gets executed.

Any hints on how to deal with long-running (where an exact estimate is not available) initializations in Eclipse wizards would be very appreciated!

解决方案

I have given below a simple example on how to use IRunnableWithProgress along with a ProgressMonitorDialog to perform a task of unknown quantity. To start with, have an implementation to IRunnableWithProgress from where the actual task is performed. This implementation could be an inner class.

public class MyRunnableWithProgress implements IRunnableWithProgress {
    private String _fileName;

    public MyRunnableWithProgress(String fileName) {
        _fileName = fileName;
    }

    @Override
    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
        int totalUnitsOfWork = IProgressMonitor.UNKNOWN;
        monitor.beginTask("Performing read. Please wait...", totalUnitsOfWork);
        performRead(_fileName, monitor); // This only performs the tasks
        monitor.done();
    }
}

Now, a generic implementation to ProgressMonitorDialog can be created as below which could be used for other places where a progress monitor dialog is required.

public class MyProgressMonitorDialog extends ProgressMonitorDialog {

    private boolean cancellable;

    public MyProgressMonitorDialog(Shell parent, boolean cancellable) {
        super(parent);
        this.cancellable = cancellable;
    }

    @Override
    public Composite createDialogArea(Composite parent) {
        Composite container = (Composite) super.createDialogArea(parent);
        setCancelable(cancellable);
        return container;
    }
}

Having got the required implementation, the task can be invoked as below to get it processed with a progress dialog.

boolean cancellable = false;
IRunnableWithProgress myRunnable  = new MyRunnableWithProgress(receivedFileName);
ProgressMonitorDialog progressMonitorDialog = new MyProgressMonitorDialog(getShell(), cancellable);

try {
    progressMonitorDialog.run(true, true, myRunnable);
} catch (InvocationTargetException e) {
    // Catch in your best way
    throw new RuntimeException(e);
} catch (InterruptedException e) {
    //Catch in your best way
    Thread.currentThread().interrupt();
}

Hope this helps!

这篇关于如何在Eclipse向导中正确更新未知持续时间的操作的进度条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆