eclipse.orgが打ち出すRIAプラットフォーム「Eclipse RAP」(Java Traveler 第2回補足)

本記事は、WEB+DB PRESS Vol.45の連載『Java Traveler 第2回 Java FXとEclipse RAP』の補足記事です。 ここでは、Eclipse RAPアプリケーションの開発方法について説明します。Eclipse RAPの構成などについては連載記事をご覧ください。また、誌面ではRIA(Rich Internet Application)の解説やJavaFXアプリケーション開発に関する解説もご覧いただけます。

Eclipse RAPアプリケーションの開発

Eclipseの準備

Eclipse RAPのアプリケーション開発には、もちろんEclipseを使います。開発を行うには、Eclipseのプラグインを開発するための環境となるPDE ⁠Plugin Development Environment)がインストールされている必要があります。PDEは次のパッケージに含まれています。

  • Eclipse IDE for Java EE Developers
  • Eclipse for RCP/Plug-in Developers
  • Eclipse Classic 3.4

今回はEclipse 3.4を対象とし、上記のいずれかのパッケージを使用することにします。

Eclipse RAPの入手と設定

ダウンロード

先ほどのEclipseのパッケージに加え、別途Eclipse RAPのアーカイブを入手します。

にWebブラウザでアクセスし、⁠Target Platform」という欄にある「1.1 Release」のアーカイブファイルをダウンロードします。任意の場所に解凍・展開すると、eclipseというディレクトリができます。くれぐれも、すでにインストールされているEclipse IDEに上書きしないでください。

プラグインのインストール

Eclipse 3.4を起動したら、Eclipse RAPアプリケーションを開発するためのプラグインをインストールします。このプラグインはUpdate Siteによる配布が行われていますので、インストールは次の手順で簡単に行えます図1⁠。

①[Help]メニューから[Software Updates]メニューを選択し、Software Updates and Add-onsダイアログを表示させる
②[Available Software]を選択にして[Add Site]ボタンを押下する
③[Location]フィールドに次のURLを入力する
図1 Update Siteの追加
図1 Update Siteの追加

[OK]ボタンを押下するとUpdate Siteにアクセスし、検索結果として[Rich Ajax Platform SDK (RAP)]が選択できるようになります(執筆時点のバージョンは1.1.0.20080613-1119⁠⁠。これにチェックを入れ、[Install]ボタンで進みます。あとはライセンスの同意とインストール内容の確認をし、プラグインのインストールを完了します図2⁠。

図2 RAP SDKの選択
図2 RAP SDKの選択

Eclipseの再起動後、Eclipse RAPアプリケーションを開発するために、展開しておいたEclipse RAPのTarget Platformを使えるようにします。

①Eclipseのメニューから[Eclipse] -> [Preferences]を選択し、設定ダイアログを開く
②左の欄にある[Plug-in Development]項目中の[Target Platform]を選択する
③右上にある[Browse]ボタンを押下して、先ほど展開したeclipseディレクトリを選択する

すると、Plug-insのリストでEclipse RAPアプリケーションの開発や実行に必要となるプラグインが一覧表示されます。この中にはjavax.servletなども含まれていますので、Ajaxに対応した環境となっていることがわかります。すべてのプラグインにチェックが入っていることを確認し、[OK]ボタンを押下します図3⁠。

図3 Target Platformの設定
図3 Target Platformの設定

Eclipse RAPプロジェクトの作成

開発環境が整ったところで、いよいよサンプルアプリケーションの開発を行いましょう。

まずはプロジェクトを作成します。先ほどインストールしたRAP SDKプラグインによって、Eclipse RAPアプリケーションのひな形がいくつかインストールされています。今回はその中から「RAP Application with a View」というひな形を元にプロジェクトを作成します。

①Eclipseの[File] -> [New] -> [Project]を選択し、新規プロジェクト作成ウィザードを開く
②「Plug-in Project」を選択し、[Next]ボタンを押下する
③「Project name」欄にプロジェクト名を入力して[Next]ボタンを押下する。ここではプロジェクト名を「rap-sample」としておく
④「Rich Client Application」のYes/Noの選択が「No」であることを確認し、[Next]ボタンを押下する。ここでプロジェクトのテンプレートが選べ、その中には先ほど紹介した「RAP Application with a View」が出てきているのでそれを選択して[Finish]ボタンを押下する

Eclipse RAPアプリケーションの実行

テンプレートをもとにして作成したプロジェクトは、そのまますぐに実行できます。作成したプロジェクトに含まれるplugin.xmlファイルをPackage Explorerビューからダブルクリックすると、プラグインマニフェストエディタで開かれます。その中の右下にある「Launch a RAP Application」というリンクをクリックすると、自動的にJettyが起動し、さらにWebブラウザが開いて図4のようにアプリケーションが表示されます。

Webブラウザ内に表示されたウィンドウは、タイトルバーをドラッグして移動することや、ウィンドウの大きさを変更したり最大化したりといった基本的な動作が可能になっています。さらには[File]メニューやクライアント領域にあるリストなど、まるでEclipseがWebブラウザ内で動作しているように見えます。

WebブラウザとしてFirefoxをご利用の方は、ぜひfirebug拡張プラグインをFirefoxにインストールしてAjax通信を覗いてみてください。ウィンドウの最大化や[File]メニューの選択、リスト内の項目選択などの際に、毎回しっかりサーバに非同期通信が行われているのが見て取れると思います。一切JavaScriptのコードを書かずにここまで実現できるのは非常に魅力的です。

図4 Eclipse RAPの実行
図4 Eclipse RAPの実行

サンプルアプリケーションのコード

では、今回のサンプルを紹介しましょう。⁠左のビューで名前と年齢を入力して[追加]ボタンを押すと、右の一覧にそれが追加される」というシンプルなアプリケーション図5で、先ほど作成したプロジェクトにコードを追加して作成します。

プロジェクトを作成した際に選択した「RAP Application with a View」テンプレートは、ビューを1つ持っているアプリケーションとなっています。これにもう1つビューを追加して、情報入力ビューと情報一覧ビューという構成を作っていきます。

図5 Eclipse RAPのサンプルアプリケーション
図5 Eclipse RAPのサンプルアプリケーション

情報入力ビューの追加

まず、新規にInputViewという名前のクラスを作成します。コードの内容はリスト1のようにします。

リスト1 InputView
package rap_sample;

import org.eclipse.jface.dialogs.*;  ---①
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.part.*;

public class InputView extends ViewPart {
    public static final String ID = "rap_sample.view.input";
    private Text text;
    private Spinner spinner;

    public void createPartControl(Composite parent) {
        GridLayout layout = new GridLayout();  ---②
        layout.numColumns = 2; 
        parent.setLayout(layout); 
        Label label = new Label(parent, SWT.NONE); 
        label.setText("名前"); 
        text = new Text(parent, SWT.SINGLE | SWT.BORDER); 
        label = new Label(parent, SWT.NONE); 
        label.setText("年齢"); 
        spinner = new Spinner(parent, SWT.BORDER); 
        spinner.setMinimum(0); 
        spinner.setMaximum(120); 
        spinner.setSelection(33); 
        Button button = new Button(parent, SWT.PUSH); 
        button.setText("追加"); } 
        button.addSelectionListener(new SelectionListener() {  ---③
            public void widgetDefaultSelected(SelectionEvent e) {
            }
            public void widgetSelected(SelectionEvent e) {
                String name = text.getText();
                if (name == null || name.length() == 0) {  ----④
                    MessageDialog.openError(getSite().getShell(), "エラー", "名前を入力してください");
                } else {
                    String person = name + "(" + spinner.getSelection() + ")";
                    Activator activator = Activator.getDefault();
                    activator.addPerson(person);  ---⑤
                }
            }
        });
    }

    public void setFocus() {
        text.setFocus();
    }
}

①のimport文を見ると、Eclipseプラグインを作る際に使用するSWTおよびJFaceのパッケージのみが記述されています。つまり、このリストはこのままデスクトップアプリケーションとして利用できます。JavaScriptが出てくるわけでもなく、特別なAPIを使うわけでもなく、RIAアプリケーションが開発できることがわかります。

②はラベルやテキストフィールド、年齢を選択するスピナーなどのUI部品を生成し登録しているコードです。GridLayoutクラスを使ってUIの配置を調整しています。

登録された[追加]ボタンが押されたときの処理は、そのbuttonインスタンスにSelectionListenerインタフェースのオブジェクトを生成して登録します。それが③の部分です。実際にWebブラウザ上でボタンが押された際には、widgetSelected( )メソッドが「サーバ上で」呼び出されます。Webブラウザ上でwidgetSelected( )メソッドの内容が実行されるわけではありません。

Webブラウザ上のテキストフィールドに入力された値は、Ajaxによる非同期通信を経て、SWTコンポーネントのインスタンスに反映されます。widgetSelected( )メソッド内では、getText( )メソッドによって入力文字列を取得し、入力されたかどうかを判断しています。④の部分で、もし入力されていなかった場合にMessageDialogクラスのopenError( )メソッドによってエラーダイアログを表示しています。これに関しても、普通に考えればOSのGUI上にダイアログが表示されるのですが、Eclipse RAPではWebブラウザ上でダイアログが表示されます図6⁠。

図6 MessageDialog.openError( )の結果
図6 MessageDialog.openError( )の結果

ちゃんと入力されていれば、⑤でActivatorクラスのaddPerson( )メソッドに入力された文字列と選択された年齢をもとに作成した文字列を渡し、隣の情報一覧ビューに追加を依頼します。

このInputViewビュークラスを実際に利用するためには、plugin.xmlファイルにリスト2の内容を追記します。追記個所は、org.eclipse.ui.views拡張の定義が書かれているextensionタグの中です。

この記述により、自作したビューがEclipseに登録されます。

リスト2 plugin.xmlへの追記内容
<view
      name="InputView"
      class="sample.InputView"
      id="rap_sample.view.input">
</view>

Eclipseに登録されたビューはパースペクティブに追加して表示します。パースペクティブ内をどのようなビューで構成するかはPerspectiveクラスで指定します。今回のサンプルでは2つのビューを登録しますので、PerspectiveクラスのcreateInitialLayout( )メソッド内をリスト3のように修正します。

リスト3 Perspectiveクラスの修正
・修正前
layout.addStandaloneView(View.ID, false, IPageLayout.LEFT, 1.0f, editorArea);
・修正後
layout.addView(InputView.ID, IPageLayout.LEFT, 0.5f, editorArea);
layout.addView(View.ID, IPageLayout.LEFT, 0.5f, editorArea);

先ほど作成したInputViewビューとテンプレートに含まれているViewビューを横に均等に並べて、パースペクティブとしています。StandaloneViewではなくなるので、それぞれのビューにタブが表示されるようになります。

Activatorクラスの修正

情報入力ビューで入力された情報(つまり名前と年齢)をActivatorクラスのインスタンス内で保持し、それが情報一覧ビューに反映されるようにします。

Activatorクラスは、Eclipseのプラグインの中で中心的な位置づけのクラスです。Eclipseが起動して該当プラグインが必要となったとき(提供しているビューが使われるときなど)に、インスタンスがEclipseのコアプラグインによって自動的に生成され、管理されます。ほとんどの場合、プラグイン1つに対してActivatorクラスやそのインスタンスが1つ存在します。つまり、あるプラグイン内で情報を一元管理したい場合は、Activatorクラスのインスタンスに持たせると都合がよくなります。

今回の題材では、Activatorクラスにリスト4の内容を追記します。文字列を格納するコレクションを用意し、addPerson( )メソッドの呼び出し時に、Viewビューの参照をgetView( )メソッドで獲得し、後述するrefresh( )メソッドを呼び出して一覧を更新しています。

リスト4 Activatorクラスへの追加
private List people = new ArrayList();

public String[] getPeople() {
    return people.toArray(new String[0]);
}

public void addPerson(String person) {
    people.add(person);
    getView().refresh();
}

private View getView() {
    IViewReference[] viewReferences =
        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences();
    for (IViewReference viewReference : viewReferences) {
        if (viewReference.getId().equals(View.ID)) {
            return (View)viewReference.getView(true);
        }
    }
    throw new RuntimeException();
}

Viewクラスの修正

最後に、情報一覧ビューのコンテンツとして、Activatorクラスに定義した文字列のコレクションが反映されるように修正します。これは、refresh( )メソッドの追加と、プロジェクトの作成時にすでに作られているViewクラスの35行目付近にあるgetElements( )メソッドの内容を変更するだけですリスト5⁠。

リスト5 Viewクラスの変更
・変更前
public Object[] getElements(Object parent) {
    return new String[] { "One", "Two", "Three" };
}
リスト5 Viewクラスの変更
・変更後
public Object[] getElements(Object parent) {
    return Activator.getDefault().getPeople();
}
リスト5 Viewクラスの変更
・追加
public void refresh() {
    viewer.refresh();
}

Activatorクラスのインスタンスを取得し、先ほど追加したgetPeople( )メソッドを呼び出して情報一覧を得ています。これにより、JFaceのTableViewerコンポーネントに情報一覧が反映されるようになります。自動的には反映されないので、refresh( )メソッドの中でTableViewerコンポーネントのrefresh( )メソッドを呼び出してコンテンツの更新を明示的に行っています。

このrefresh( )メソッドは、ActivatorクラスのaddPerson( )メソッドで呼んでいるものでしたね。つまり、Webブラウザ上で[追加]ボタンが押されたときには、最終的にこのrefresh( )メソッドが呼び出されて、自動的に一覧が更新されます。

まとめ

Eclipse RAPを使えば、JavaScriptやHTMLなどでのWebアプリケーションに関するコーディングなしにRIAアプリケーションを開発できることがわかっていただけたと思います。SWTやJFaceが提供してくれるコンポーネントは、業務アプリケーションを作る上で非常に強力です。Eclipseプラグインを開発したことのある方はもちろん、そうでない方にとってもSWTやJFaceはシンプルなAPIとなっているので、手軽にUIを構築するコードを書けます。

なお、RAP SDKをインストールすると、Eclipse RAPに関するより詳しい情報がヘルプに追加されます図7⁠。ここには、Googleマップを表示するカスタムコンポーネントの作り方や、作成したEclipse RAPアプリケーションをWARファイルとしてデプロイするための手順などが説明されています。よりリッチでRIAらしいアプリケーションを開発する際には、非常に参考になる情報です。

図7 Eclipse RAPのヘルプ
図7 Eclipse RAPのヘルプ

おすすめ記事

記事・ニュース一覧