// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents

**概要 [#z69fd4c1]
さて前回はGoogleの検索機能を呼び出したり、スペルミスを変更するダイアログだったりを作成しました。今回はその検索結果を表示するためのビューを作成していきたいと思います。プロジェクトは引き続き「nu.mine.kino.plugin.google.ui」を使用します。

**plugin.xml、MANIFEST.MFを記述する [#wc09e01d]

「META-INF/MANIFEST.MF」をマニフェストエディタで開き、[拡張]タブを選択して[追加]をクリックします。すると、拡張ポイントを選択するダイアログが開くので、「org.eclipse.ui.views」を選択し[終了]をクリックします。

#ref(view.gif)

次に、この「org.eclipse.ui.views」を右クリックして[新規]−[view]を選択します。下に要素が追加されました。右側にはidやクラス名を指定する画面が表示されているので、以下のように指定します。

|LEFT:id|LEFT:nu.mine.kino.plugin.google.ui.views.GoogleResultView|
|LEFT:name|LEFT:Google検索結果|
|LEFT:class|LEFT:nu.mine.kino.plugin.google.ui.views.GoogleResultView|
|LEFT:category|LEFT:nu.mine.kino.plugin.google|
|LEFT:icon|LEFT:icons/icon.png|



カテゴリーなども追加して結局plugin.xmlには以下のコードが追加されました。

   <extension
         point="org.eclipse.ui.views">
      <view
            category="nu.mine.kino.plugin.google"
            class="nu.mine.kino.plugin.google.ui.views.GoogleResultView"
            icon="icons/icon.png"
            id="nu.mine.kino.plugin.google.ui.views.GoogleResultView"
            name="Google検索結果"/>
      <category
            id="nu.mine.kino.plugin.google"
            name="Googleプラグイン"/>
   </extension>

**ビューのクラスを追加する [#w2233d70]
先のマニフェストエディタでidやクラス名を指定しましたが、classのラベルはクリックできるようになっています。

#ref(label.gif)


これをクリックするとビューのクラスを作成するウィザードが起動します。そのまま終了をクリックすると「GoogleResultView」のソースコードが作成されます。


では、そのソースコードに色々追加していこうと思います。

**ビューの本体にテーブルビューワを配置する [#jd8459ae]
まずはビューの本体を構築していきます。ビューの構築は
 public void createPartControl(Composite parent);
をOverrideすることで行います。引数のCompositeに色々ウィジェットを配置していくわけですね。


さて今回は下記のとおりビュー全体にTableViewerを配置することにしました。ここで出てくるTableViewerとはEclipseの「問題ビュー」のようにヘッダとデータ部分を持った表形式のビューワーです。
 public void createPartControl(Composite parent) {
     // ビューワを追加。
     Composite container = new Composite(parent, SWT.NONE);
     container.setLayout(new FillLayout());
 
     viewer = new TableViewer(container, SWT.FULL_SELECTION | SWT.BORDER);
     viewer.setContentProvider(new ArrayContentProvider());
     viewer.setInput(getViewSite());
     initTable(viewer);
 
     createActions();
     initializeToolBar();
     initializeMenu();
 }

TableViewerにカラムを追加する処理は initTable(viewer); で行っています。具体的なソースは以下の通りです。

 private void initTable(final TableViewer viewer) {
     table = viewer.getTable();
     TableLayout layout = new TableLayout();
     table.setLayout(layout);
     table.setHeaderVisible(true); //ヘッダを表示する 
     table.setLinesVisible(true);  //ラインを表示する
 
     ColumnLayoutData[] columnLayouts = getColumnLayouts();
 
     for (int i = 0; i < columnLayouts.length; i++) {
         layout.addColumnData(columnLayouts[i]);
         TableColumn tc = new TableColumn(table, SWT.NONE, i);
         tc.setText(VISIBLE_FIELDS[i].getColumnHeaderText());
         tc.setImage(VISIBLE_FIELDS[i].getColumnHeaderImage());
     }
 }

ColumnLayoutDataはフィールドの幅などレイアウト情報を管理するクラスです((Eclipseでテーブルビューワを使うときはカラムの制御は[[ColumnLayoutData:http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/api/org/eclipse/jface/viewers/ColumnLayoutData.html]]でやるのがよいみたいです((とりあえずEclipseのMarkerViewなどの実装はそうなってた))。[[ColumnLayoutData:http://www.eclipse.org/documentation/html/plugins/org.eclipse.platform.doc.isv/doc/reference/api/org/eclipse/jface/viewers/ColumnLayoutData.html]]はフィールドの幅などの情報を表現するクラスです。))。

このColumnLayoutDataクラスは
 table = viewer.getTable();
 TableLayout layout = new TableLayout();
 table.setLayout(layout);
というようにTableViewerとTableLayoutが関連づけられており、TableLayoutに
 layout.addColumnData(columnLayouts[i]);
とすることでTableViewerに関連づいています。


さて
 ColumnLayoutData[] columnLayouts = getColumnLayouts();
で、各カラムのレイアウト情報を配列で取得していますが、現段階ではgetColumnLayouts();は
 private ColumnLayoutData[] getColumnLayouts() {
   return DEFAULT_COLUMN_LAYOUTS;
 }
とフィールドに定義されている配列をそのまま返すようになっています。ここはあとで「すでに前回の情報が保存されていたらその情報を復元する」という処理に変更します。たとえば前回使用していたときにフィールドの幅などを変更していたとして、その幅を次回に復元する、といったことをできるようにするわけですね。


**実際にカラムを追加する [#j593a6c7]
実際にカラムを追加する処理は
 for (int i = 0; i < columnLayouts.length; i++) {
   layout.addColumnData(columnLayouts[i]);
   TableColumn tc = new TableColumn(table, SWT.NONE, i);
   tc.setText(VISIBLE_FIELDS[i].getColumnHeaderText());
   tc.setImage(VISIBLE_FIELDS[i].getColumnHeaderImage());
 }
の箇所です。先のレイアウト情報をセットするのと、ヘッダの文言やイメージデータをカラムごとにセットしています。ここで出てくる VISIBLE_FIELDS[] のインスタンスはあらかじめ
 private final IField[] VISIBLE_FIELDS = 
    { new TitleField(),new SummaryField(), new URLField() };
とフィールドに定義されているインスタンスです。


***IFieldの役割 [#k634961f]
IFieldとは
 public interface IField {
     String getColumnHeaderText();
     Image getColumnHeaderImage();
     String getValue(Object obj);
     Image getImage(Object obj);
     int compare(Object obj1, Object obj2);
 }
というように、ヘッダ名やヘッダに表示するアイコンの情報、またビューワの各カラムにオブジェクトが渡されたときにオブジェクトを文字列に変換する変換処理、などを備えたインタフェースです。実装しているクラスTitleField, SummaryField, URLField はそれぞれ

 public class TitleField implements IField {
   public String getColumnHeaderText() {return "Title";}
   -- 以下省略 --
 }

 public class SummaryField implements IField {
   public String getColumnHeaderText() {return "Summary";}
   -- 以下省略 --
 }

 public class URLField implements IField {
   public String getColumnHeaderText() {return "URL";}
   -- 以下省略 --
 }

というようにヘッダ部分の文言が定義されています。


さて上記のIFieldとその実装クラスですが、先のソースで
 for (int i = 0; i < columnLayouts.length; i++) {
   layout.addColumnData(columnLayouts[i]);
   TableColumn tc = new TableColumn(table, SWT.NONE, i);
   tc.setText(VISIBLE_FIELDS[i].getColumnHeaderText());
   tc.setImage(VISIBLE_FIELDS[i].getColumnHeaderImage());
 }
とTableColumnのsetTextを呼び出して、各カラムにヘッダ名をセットしているわけです。IFieldはこのようにヘッダ名をセットするだけではなくTableViewerへのデータ表示時にも使用されるのですが、それについては後述します。

**検索メソッドを定義する [#qdf36c45]
続いてこのメソッドに検索メソッドを定義します。メソッド名は
 public void search(String text);
というメソッドにしました。ただ、中身については後に実装しますので、とりあえず以下のようなテスト実装としておきました。
 public void search(String text) {
     logger.debug("search(String) - start");
     try {
         String key = GooglePlugin.getDefault().getPreferenceStore()
                 .getString(PreferenceConstants.GOOGLE_KEY);
         GoogleSearchResult result = GoogleCorePlugin.getDefault().search(key, text);
         ResultElement[] resultElements = result.getResultElements();
         logger.debug("search(String)の検索結果件数は "
                       + resultElements.length + " 件でした。");
         viewer.setInput(resultElements);
     } catch (CoreException e) {
         logger.error("search(String)", e);
     }
     logger.debug("search(String) - end");
 }

ここまででビューにはTableViewerが配置されていて、そのTableViewerにはTitle,Summary,URLという3つのカラムがあり、検索メソッドがテスト実装されている、ということになりました。


**スクリーンショット [#e6fb2426]
実際にビューを表示してみると、こんな感じです。

#ref(result.gif)

まだTitleのカラムにオブジェクトのハッシュコードが表示されるのみですが、これは後に修正していきます。



さて実際にビューを生成して検索メソッドを呼び出す方法ですが、例によってJUnitを用いることができます。


**JUnitを使ってビューを生成する [#p7b01ebc]
テスト用のプロジェクトは前回の「nu.mine.kino.plugin.google.ui.test」を用います。今回も外部のテストプラグインからクラスを呼び出すので、「nu.mine.kino.plugin.google.ui」プラグインの外部に公開するパッケージに
- nu.mine.kino.plugin.google.ui.views

を追加しました。

#ref(export.gif)

前回と同様、nu.mine.kino.plugin.google.ui.views.GoogleResultView クラスを選択してJUnitのテストクラスを「nu.mine.kino.plugin.google.ui.test」プロジェクトに生成します。JUnitのテストクラスはnu.mine.kino.plugin.google.ui.views.GoogleResultViewTest です。テストクラスには以下のメソッドを実装しました。

 public void testGoogleResultView() {
   try {
     GooglePlugin.getDefault().getPreferenceStore().setValue(
         PreferenceConstants.GOOGLE_KEY, "xxxxxxxxxx");
     IWorkbenchPage page = PlatformUI.getWorkbench()
         .getActiveWorkbenchWindow().getActivePage();
     GoogleResultView view = (GoogleResultView) page
         .showView(GoogleResultView.ID);
     view.search("eclipse");
   } catch (PartInitException e) {
     e.printStackTrace();
   }
 }

パッケージ・エクスプローラで[GoogleResultViewTest]を選択し、Eclipseのツールバーから[実行]−[JUnitプラグイン・テスト]を選択します。Eclipseが起動して上のメソッドが実行され、一瞬で消えてしまうのですがビューが表示され、検索結果が一覧されます。





さて引き続き、[[前回の状態を復元する処理>Eclipse/プラグイン開発のTIPS集/GooglePlugin/前回の状態を復元する処理]]を追加したいと思います。

----
この記事は
#vote(おもしろかった[2],そうでもない[0])
#vote(おもしろかった[3],そうでもない[0])

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS