-Outlineの同期

Outlineビューですが、0.6.6ではDiconファイルと同期できてませんでした。ファイル編集+保存 → バックグラウンドでのビルド → Outlineに反映なので、エディタ更新のタイミング取りではOutlineの表示更新してもダメだったからです。ビルドはいつ終わるかわかりません(笑。そこで、ビルダーのプロセス終了時にイベントハンドラを発火するように仕込んで、Outlineをイベントハンドラとしました。後々、Diconツリービューも作るつもりなので、ここは般化してあります。
Outlineで発火されたイベントハンドラでビルドし終わったモデルを取得して表示してます。その際に、以下のようなコードを書かないとIllegal Thread Accessになってしまいます。

public void finishChanged() {
  final Control control = viewer.getTree();
  Display display = control.getDisplay();
  display.syncExec(new Runnable() {
    public void run() {
      if(control.isDisposed()) {
        return;
      } else {
        viewer.setInput(new DiconContent(input.getFile()));
      }
    }
  });
}

Eclipseの中では結構よく見るタイプのコードです。イベント発火のほう、スレッド化しないといけません。

public void fireRecordChanged() {
  for(Iterator it = listeners.iterator(); it.hasNext();) {
    final IProjectRecordChangeListener listener =
        (IProjectRecordChangeListener)it.next();
    IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
      public void run(IProgressMonitor monitor) throws CoreException {
        listener.finishChanged();
      }
    };
    try {
      getProject().getWorkspace().run(runnable, null);
    } catch (CoreException e) {
      Kijimuna.reportException(e);
    }
  }
}

以下はダメな例。昨晩こう書いてはまってました。

public void finishChanged() {
  viewer.setInput(new DiconContent(input.getFile()));
}

public void fireRecordChanged() {
  for(Iterator it = listeners.iterator(); it.hasNext();) {
    ( (IProjectRecordChangeListener)it.next() ).finishChanged();
  }
}

。。。ということで、CVSバージョンではOutlineビューの動きがサクサクしていて気持ちいいです。やったね!