2014-10-25

ProgressIndicator と Thread

JFace の ProgressIndicator を利用して、ファイルの読み込みなど時間が掛かる処理について、単に処理中であることを表示しようとしましたが、最初、なかなかうまくいきませんでした。試行錯誤して、当初予定していたサンプルが出来たので、備忘録として書留ます。

このサンプルは、ダミーの処理をしているスレッドから、UI スレッドにある ProgressIndicator のインスタンス indicator に非同期でアクセスして操作をしています。なお、このサンプルでは [2] のように別スレッドの処理中に「処理開始」ボタンがクリックされることを考慮していません。

List: ProgressIndicatorTest.java
package jfacesample;

import org.eclipse.jface.dialogs.ProgressIndicator;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class ProgressIndicatorTest extends ApplicationWindow {
    Display display;
    ProgressIndicator indicator;

    public ProgressIndicatorTest() {
        super(null);
    }

    @Override
    protected Control createContents(Composite parent) {
        Shell shell = parent.getShell();
        display = shell.getDisplay();
        shell.setText("ProgressIndicatorTest");

        GridLayout layout = new GridLayout();
        parent.setLayout(layout);

        GridData gd;

        // start button
        Button start = new Button(parent, SWT.PUSH);
        start.setText("処理開始");
        gd = new GridData(GridData.FILL_HORIZONTAL);
        start.setLayoutData(gd);
        start.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                startWork();
            }
        });

        // progress indicator
        indicator = new ProgressIndicator(parent);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        indicator.setLayoutData(gd);

        return parent;
    }

    private void startWork() {
        DummyTask task = new DummyTask(display, indicator);
        Thread th = new Thread(task);
        th.start();
    }

    public static void main(String[] args) {
        ProgressIndicatorTest w = new ProgressIndicatorTest();
        w.setBlockOnOpen(true);
        w.open();
        Display.getCurrent().dispose();
    }
}

class DummyTask implements Runnable {
    Display display;
    ProgressIndicator indicator;

    DummyTask(Display display, ProgressIndicator indicator) {
        this.display = display;
        this.indicator = indicator;        
    }

    public void run() {
        // start progress indicator
        display.asyncExec(new Runnable() {
            public void run() {
                indicator.beginAnimatedTask();
                indicator.showNormal();
            }
        });

        // dummy task
        long sleepTime = 3000; // milliseconds
        long endTime = System.currentTimeMillis() + sleepTime;
        while (System.currentTimeMillis() < endTime) {
        }

        // stop progress indicator
        display.asyncExec(new Runnable() {
            public void run() {
                indicator.done();
            }
        });

        System.out.println("completed!");
    }
}

実行例

参考サイト

  1. IBM Knowledge Center
  2. 基礎編 - スレッド

0 件のコメント: