Top / Eclipse / プラグイン開発のTIPS集 / プロパティシートを使う

プロパティシートって

プロパティシートとは、ビューで選択されているオブジェクトや、エディタの内容などを表示するためのビューです。具体的にはたとえばビューの場合は「ビューが外部にSelectionProvider?として公開しているviewerにsetInputされたオブジェクト」の情報を表示することができます。

pic.png

プロパティシートの例。パッケージ・エクスプローラで選択されているオブジェクトの内容が表示されている。

実装方法

まずはビューでの実装方法をまとめていきます。

モデルとなるオブジェクト

モデルオブジェクトを

public interface Model {
   String getId();
   String getName();
   String getMail();
}

としました。実装クラスは

public class ModelImpl implements Model {
  private String id;
  private String name;
  private String mail;
  public ModelImpl(String id, String name, String mail) {
    this.id = id;
    this.name = name;
    this.mail = mail;
  }
  public String getId() {return id;}
  public String getMail() {return mail;}
  public String getName() {return name;}
}

こんな感じです。これをビュー上のビューワに複数インスタンス表示し、選択したらプロパティシートに内容を表示させることを考えます。

pic02.png

モデルの内容がプロパティシートに表示されている。


getSite().setSelectionProvider?(viewer)させる

さて、実装の手順ですが、先のとおりSelectionProvider?として公開されているビューの情報を表示するので、そのviewerが

getSite().setSelectionProvider(viewer);

されていることがまず必要です*1

getAdapterを実装する

次に、そのビュー(クラス名はModelView?としました)がプロパティシートを使えるの?という質問に対して、使えるよーというのを答える記述を追加します。だんだん慣れてきましたが、IAdaptableを使うわけですね。ビューの実装クラスViewPart?はIAdaptableなので、getAdapterをOverrideします。

ModelViewe?に以下を実装:

public Object getAdapter(Class adapter) {
  logger.debug("getAdapter(Class) - start");

  if (adapter.equals(IPropertySheetPage.class)) {
    logger.debug("getAdapter(Class) - end");
    return new PropertySheetPage(); 
            ↑これはEclipseで提供されているモノ。自前ではない。
  }
  logger.debug("getAdapter(Class) - end");
  return super.getAdapter(adapter);
}

これで、EclipseプラットフォームがModelView?に「IPropertySheetPage?サポートしてる?」と問い合わせたときに「もってるよ。はいPropertySheetPage?。」と返答することになります。

モデルを修正する

実はプロパティシートに表示するには、以下の条件のどれかが必要です。

  • モデルのオブジェクトがIPropertySource?を実装していること
  • モデルのオブジェクトがIAdaptableを実装していて、IPropertySource?を返すこと

これって実は厳しい条件ですよね。というのはモデルとなるオブジェクトは他人が作ったモノとか、修正できないモノとか、Eclipse以外でも使いたいモノである可能性が高く、その場合はおいそれとEclipseのインタフェースを実装なんてできないわけです。

実はソースを見てたら上記2以外の条件もあったのですが、とりあえずここではIAdaptableの方式でやってみようと思います。

ModelインタフェースでIAdaptableを拡張します。

public interface Model extends IAdaptable {
   String getId();
   String getName();
   String getMail();
}

実装クラスでは以下のようにします。

public class ModelImpl implements Model {
  private String id;
  private String name;
  private String mail;
  public ModelImpl(String id, String name, String mail) {
    this.id = id;
    this.name = name;
    this.mail = mail;
  }
  public String getId() {return id;}
  public String getMail() {return mail;}
  public String getName() {return name;}
  
  // IPropertySourceを返すように実装
  public Object getAdapter(Class adapter) {
    if (adapter.equals(IPropertySource.class)) {
      return source;
    }
    return null;
  }
  
  private IPropertySource source = new IPropertySource() {
    ....長いので、後述。
  };
}

以上で、モデル側は準備ができました。ちなみにModelView?は以下の通り実装されました。

public class ModelView extends ViewPart {
  private List models;

  public void createPartControl(Composite parent) {
    Composite container = new Composite(parent, SWT.NONE);
    container.setLayout(new FillLayout());
 
    initializeModel();
    final TableViewer tableViewer = new TableViewer(container, SWT.BORDER);
    tableViewer.setContentProvider(new ArrayContentProvider());
    tableViewer.setInput(models);

    getSite().setSelectionProvider(tableViewer);
    ....省略
  }

  private void initializeModel() {
    models = new ArrayList();
    models.add(new ModelImpl("000", "Root", "root@localhost"));
    models.add(new ModelImpl("001", "masatomi", "masatomi@localhost"));
  }

  public Object getAdapter(Class adapter) {
    if (adapter.equals(IPropertySheetPage.class)) {
      return new PropertySheetPage();
    }
    return super.getAdapter(adapter);
  }
  ....省略

}

さて表示させてみると、

pic02.png

確かに表示されました。

IPropertySource? の実装

さっき長いので省略とした、IPropertySource? の実装についてです。

private IPropertySource source = new IPropertySource() {
  public IPropertyDescriptor[] getPropertyDescriptors() {
    IPropertyDescriptor[] descriptor = new IPropertyDescriptor[] {
        new TextPropertyDescriptor("id", "コード"),
        new TextPropertyDescriptor("name", "名前"),
        new TextPropertyDescriptor("mail", "メール") };
    return descriptor;
  }

  public Object getPropertyValue(Object id) {
    if (id.equals("id")) {
      return getId();
    }
    if (id.equals("name")) {
      return getName();
    }
    if (id.equals("mail")) {
      return getMail();
    }
    return null;
  }

  public boolean isPropertySet(Object id) {return false;}
  public void resetPropertyValue(Object id) {}
  public void setPropertyValue(Object id, Object value) {}
  public Object getEditableValue() {return null;}
};

重要なのは

  • IPropertyDescriptor?[] getPropertyDescriptors?()で、表示したいモノのキー値(とその表示名)の一覧を作成すること
  • Object getPropertyValue?(Object id)でキー値が渡されるので、そのキー値に対するValueを返すように実装すること

です。その他いろいろメソッドがありますが、とりあえずこんな感じでよいでしょう。

まとめ

まとめると、だいたい以下の感じです。

  • viewerをSelectionProvider?として外部に公開しておく

getSite().setSelectionProvider?(viewer)を使って、公開しておくのでした。

  • ViewPart?でgetAdapterを実装する

IPropertySheetPage?に対してPropertySheetPage?を返すよう実装するんでしたね。

  • モデルオブジェクトをIAdaptableかIPropertySource? を実装する

なんらかの方法でIPropertySource? を返すようモデルを修正する必要がありました。

モデルをEclipseなクラスから分離したい

ちょっと書きましたが、モデルオブジェクトはいじりたくないし、Eclipseのクラスを拡張とかもしたくないわけです。IAdaptableなどを勉強して、どうも別のやり方があることがわかってきました。次はそれをまとめたいと思います。

IAdaptableなどをimplementsしていないモデルオブジェクトのプロパティシートへの表示

関連リンク


この記事は

選択肢 投票
おもしろかった 3  
そうでもない 2  
  • すでに存在するモデルや、他のヒトが作ったモデルを表示しているビューワの場合、どうやるのかなぁ? -- きの? 2005-03-03 (木) 01:16:30
  • やっぱDelegateするラッパを作るのかなぁ -- きの? 2005-03-17 19:56:37 (木)
  • やり方がわかりました。IPropertySource?を作って返すように実装するんですね。詳細は上のリンク先にまとめました。 -- きの? 2006-03-29 11:12:07 (水)
  • そもそもプロパティ・シートのビューはどうやって追加できるのでしょうか? -- koi? 2010-07-10 (土) 05:44:14

Top / Eclipse / プラグイン開発のTIPS集 / プロパティシートを使う

現在のアクセス:12664


*1 これでプロパティシートとviewerが関連づけられます

添付ファイル: filepic02.png 698件 [詳細] filepic.png 613件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-07-10 (土) 05:44:15 (3362d)