 | レベル: 中級 Sam Lo (locl@tw.ibm.com), Software Engineer, IBM Eric Hsu (mfhsu@tw.ibm.com), Software Engineer, IBM
2007年 9月 11日 今後数年間はモバイル機器用アプリケーションの需要が増えると考えて間違いないでしょう。そんな今こそ、オープン・スタンダードの組み込み JFace ライブラリー、eJFace を学ぶにはちょうどいい時期です。組み込みアプリケーションの新しいビルド技術として登場した eJFace (embedded JFace) は eRCP (embedded Rich Client Platform) のコンポーネントの 1 つで、組み込みアプリケーションのユーザー・インターフェースを構成するための組み込み環境を開発者に提供します。この記事では eJFace を JFace と比較し、eJFace を使用してアプリケーションを開発する方法を紹介します。
eJFace は、複雑な eSWT プログラミングを行わずにアプリケーションをビルドできるようにする複数のライブラリーで構成されています。また、eJFace には強力な API が用意されており、組み込みアプリケーションを難なく実装および管理できるモデル・ビュー・コントローラー (MVC) アーキテクチャーを取り入れています。この記事では eJFace を使用してアプリケーションを開発する方法を説明するとともに、eJFace と JFace との比較も行います。JFace に馴染みのある開発者にとっては eJFace と JFace との違いを理解し、eJFace アプリケーションの開発時間を短縮するのに役立つはずです。
この記事で説明する内容は以下のとおりです。
- eJFace ライブラリーの構造と API、およびそれぞれの用途
- JFace と eJFace との違い
- eRCP 環境で eJFace、eSWT、eWorkbench アプリケーションを開発する方法
- eJFace の機能をアプリケーションに追加する方法
要点
まずは、開発者が初めて eJFace に出会ったときに出てくる質問のなかで、特に重要な 3 つの項目について手短に説明します。
1. eJFace とは何か
- eJFace はハンドヘルド機器向けに設計された、デスクトップ JFace ライブラリーの純粋なサブセットです。
- プラットフォームに依存しないユーザー・インターフェース API で、eSWT を拡張して相互運用します。
- eSWT ウィジェットを組み込んで多くの便利な機能 (MVC ベースのビューアーなど) を提供し、開発および保守作業を楽にします。
- JFace ライブラリーから、ハンドヘルド機器に組み込んで使用するにはサイズが大きすぎるものを除外しています。
2. eJFace の用途とは
- このライブラリーは、組み込み機器で役に立つ高度な UI 機能を提供します。
- eWorkbench と統合する eRCP アプリケーションを作成します。
- eSWT を拡張する一連のクラスを提供して eRCP アプリケーションを eRCP ワークベンチに統合できるようにするとともに、より複雑なウィジェット (MVC 指向のビューアーなど) を実現します。
3. eJFace にはどんな特徴があるのか
- eSWT と eJFace との関係は、SWT と JFace との関係と同じです。
- eJFace は、eSWT の Core および Expanded パーティション、そして J2ME (Java 2, Micro Edition) CDC (Connected Device Configuration) プロファイルに依存します。
- ビューアーで MVC パラダイムのコンテキストに eSWT ウィジェットをラップします。実装詳細の多くを隠すため、コードの行数が減ります。
- eSWT をベースにビルドされているため、ネイティブ・ライブラリーを追加で実行する必要がありません。
- 効率的にリソースを操作できるリソース処理クラスを提供し、メモリーを節約し、パフォーマンスを向上させます。
eJFace パッケージとその詳細
表 1. eJFace でサポートされるパッケージ
| パッケージ |
|---|
| org.eclipse.jface.action | メニュー、ツール・バー、ステータス行などの共有 UI リソースのサポート |
|---|
| org.eclipse.jface.operation | 長時間の操作に対する JFace サポート |
|---|
| org.eclipse.jface.preference | 設定用フレームワーク |
|---|
| org.eclipse.jface.resource | SWT のフォントや画像などのリソースの管理サポート |
|---|
| org.eclipse.jface.util | JFace 全体で使用されるビルディング・ブロック。プロパティー変更イベント、リスナー・リストの実装、ランタイムのアサーション・チェックなどが含まれます。 |
|---|
| org.eclipse.jface.viewers | ビューアー用フレームワーク。SWT ウィジェットのためのモデル・ベースのコンテンツ・アダプターです。 |
|---|
前述したように、eJFace ではデスクトップ指向であるためハンドヘルド機器には適していない JFace の大きなパッケージとライブラリーは削除しています。小フットプリントを考慮し、実装の複雑さを軽減することを念頭に置いた eJFace が提供するパッケージは上記のとおりです。各パッケージの API についての詳細は、「参考文献」に記載されている eJFace の Javadoc を参照してください。
表 1 に記載したパッケージについて以下に要約します。
- org.eclipse.jface.action
- org.eclipse.jface.action パッケージは、ユーザー操作に応答するという方法でユーザーと対話動作するために使用します。このパッケージがサポートするのはステータス行に対する項目追加のみです。ただし、コマンド・ウィジェットのほうが使いやすいため、Action パッケージは eSWT コマンド・ウィジェットとともに使用することをお勧めします。この場合、追加されたウィジェットにフォーカスがある間に、どの動的メニューを表示するかを選択します。詳しくは、サンプル・アプリケーションに記載したコマンド・ウィジェットのサンプルを参照してください。
- org.eclipse.jface.operation
- eJface では JFace org.eclipse.jface.operation パッケージの機能をほとんどすべて削除してありますが、
IRunnableWithProgress インターフェースについては例外です。IRunnableWithProgress インターフェースは、長時間の操作を実行するクラスが実装するよう意図されています。長時間の操作は通常、Cancel ボタンまたはプログレス・バーと併せて進行状況を表示するモーダル・ダイアログによって表示されます。
- org.eclipse.jface.preference
- org.eclipse.jface.preference が提供するのは
PreferencePage および PreferenceStore ライブラリーのみです。PreferencePage は、メッセージを表したり、限られた情報を要求する一時ダイアログ用の使い切りのリソースです。PreferencePage が閉じられるまで他の eRCP アプリケーションはブロックされるため、メイン・プログラムの実行前に確実に情報が収集されます。もう一方の PreferenceStore はアプリケーションでの情報保持用です。PreferenceStore はプロパティー・ファイルを生成し、アプリケーションが有益な情報を保管できるようにします。PreferencePage は多くの場合、ユーザー入力から収集した永続的情報を保持するために PreferenceStore と一緒に使用されます。ユーザー情報を収集してコンテンツの保管を促すプロンプトを実装する方法については、PreferencePage のサンプル・アプリケーションを参照してください。
- org.eclipse.jface.resource
- その名前からわかるように、org.eclipse.jface.resource パッケージは画像、色、フォント情報などのリソースを管理します。このパッケージは特定のリソースを簡単に検索できるようにするだけでなく、以下の機能も提供します。
-
ImageRegistry および ImageDescriptor ライブラリーで、シンボリック・カラー名と SWT カラーのマッピングを維持します。サポートされる画像形式はプラットフォームに依存します。
-
JFaceColors を使用して、機器のデフォルト・カラーを取得および保管します。
-
FontRegistry および FontDescriptor を使用して、シンボリック・フォント名と SWT フォントのマッピングを維持します。
-
CompositeImageDescriptor は、カスタム描画の効果をシミュレートするために画像を他の画像から合成する画像記述子の抽象クラスです。
-
JFaceResources は、eJFace 固有のリソースにアクセスするためのユーティリティー・メソッドです。
-
StringConverter では各種データ型とストリング型の間での変換を簡単に行います。
- org.eclipse.jface.util
- org.eclipse.jface.util は、プロパティー変更イベント、イベント・リスナー収集メカニズム、ランタイムのアサーション・チェックなど、eSWT を一層有効に使用できるようにする便利なメソッドを提供します。
- org.eclipse.jface.viewers
- org.eclipse.jface.viewers には
TreeViewer と TableViewer しか含まれていません。この 2 つのビューアーは MVC アーキテクチャーをベースとして、内部機能をルック・アンド・フィールから分離しています。この分離により、eJFace ビューアーは一層容易に管理および拡張できるようになっています。さらに、これらのビューアーには以下の特徴があります。
eSWT ツリー・ウィジェットによって実装される TreeViewer は、ユーザーがノードと子ノードを展開/縮小できる階層データを表示します
-
TreeViewerを構成した後、ITreeContentProvider インターフェースを実装してこのビューアーのコンテンツを決定する必要があります。
- コンテンツの表示方法は、
ILabelProvider インターフェースを実装して決定します。
- このビューアーをデータのルート・ノードに渡すには、指定したコンテンツ・プロバイダーとラベル・プロバイダーを使用します。
-
TableViewer は eSWT テーブル・ウィジェットによって実装され、データを列と行に表示します。TableViewer の機能を実行するには、Table および TableItem を使用します。
-
TreeViewer と同じく、TableViewer を作成してからコンテンツ・プロバイダーを必要に応じて設定します。
- ラベル・プロバイダーを設定します。
- 入力を設定します。
TreeViewer および TableViewer の実装方法は、「ダウンロード」に記載した eJFace org.eclipse.jface.viewers のデモ・アプリケーションに示されています。

 |
eJFace と JFace との違い
すでに述べたように、eJFace は完全な JFace のサブセットです。組み込み機器で使われそうもないライブラリーは削除されているか、あるいは大幅に縮小されています。表 2 に、eJFace と JFace との主な違いを要約します。
表 2. eJFace と JFace との相違
| eJFace と JFace の比較 |
|---|
| 削除された JFace のパッケージ | org.eclipse.jface.dialogs
org.eclipse.jface.operation (eJFace provides the IRunnableWithProgress interface only)
org.eclipse.jface.window
org.eclipse.jface.wizard |
|---|
| 縮小された JFace のパッケージ | org.eclipse.jface.action
org.eclipse.jface.preference (eJFace provides the PreferencePage class only)
org.eclipse.jface.viewers (eJFace provides TreeViewer and TableViewer only) |
|---|
| 変更されていないパッケージ | org.eclipse.jface.resource
org.eclipse.jface.util |
|---|
JFace からなぜ jface.wizard、jface.dialogs、そして jface.window が削除されているのか疑問に思う方もいることでしょう。これには 2 つの理由があります。まず、既存のダイアログ、ウィザード、ウィンドウのコードはデスクトップ指向なので、大幅な改訂を加えない限りモバイル用には適していません。例えば、携帯電話にカーソルとマウスが備わっていることはまずないので、一般的に携帯電話のダイアログにはプッシュボタンを使用できないといった具合です。2 つ目の理由として、選択されたパッケージは難解なコードや極めてありふれたコードではなく、アプリケーションでより簡単に実装できる便利な機能であるということです。
また、eJFace コードが eSWT の Mobile Extensions 内でコマンド・クラスを使用しないことについても疑問を感じるかもしれません。eJFace が Mobile Extensions に依存しないようにしている理由は、eRCP内では Mobile Extensions はオプション・コンポーネントとして考えられるためです。さらに、Mobile Extensions は QueryDialog と TimedMessageBox を提供しますが、これによって一部の JFace ダイアログがモバイルに適したバージョンに置き換えられます。
org.eclipse.jface.action での変更には説明が必要です。JFace は、ステータス行に対する項目追加しかサポートしません。eWorkbench には共通メニュー・バー機能がないため、ほとんどのアクション・クラスは eJFace から削除されていますが、それでも eSWT の Mobile Extensions ではアクション項目がコマンド・クラスに置き換えられているため、このような変更が必要だったわけです。
eJFace org. eclipse.jface.viewersのデモ・アプリケーション
eJFace が提供するのは TreeViewer と TableViewer だけです。eWorkbench アプリケーションの開発方法については、「参考文献」を参照してください。
TreeViewer
TreeViewer のデモ・アプリケーションを設計するには、ノード・クラスをデータ・モデルとして作成しなければなりません。ここでは、NBATeamNode および NBAPlayer という名前の 2 つのノード・クラスを作成します。次に必要となるのは、この 2 つのノードの関係を定義することです。例えば、NBATeamNode は別の NBATeamNode インスタンスまたは NBAPlayer インスタンスを追加することができます。これらのインスタンスを追加するには、NBATeamNode に 2 つの別個の ArrayList を定義する必要があります。
リスト 1. ノード・クラスおよびその親と子の関係の定義
public class NBATeamNode {
private String name;
private ArrayList teams = new ArrayList();
private ArrayList players = new ArrayList();
private NBATeamNode parent;
public NBATeamNode(String n){
name = n;
}
protected Object getParent(){
return parent;
}
public NBATeamNode addTeam(NBATeamNode child){
teams.add(child);
child.parent = this;
return this;
}
public NBATeamNode addPlayer(NBAPlayer child){
players.add(child);
child.parent = this;
return this;
}
public ArrayList getteams(){
return teams;
}
public ArrayList getplayers(){
return players;
}
public String toString(){
return name;
}
public class NBAPlayer {
private String name;
NBATeamNode parent;
public NBAPlayer(String n){
name = n;
}
protected Object getParent(){
return parent;
}
public String toString(){
return name;
} |
org.eclipse.ercp.eworkbench.applications を拡張したら、TreeViewer インスタンスを作成し、生成された SampleView クラスの createPartControl メソッドにある現行の composite に関連付けます。次にこのツリーを望ましいレイアウトにして、ツリーのコンテンツ・プロバイダーとラベル・プロバイダーそれぞれのインスタンスを TreeViewer に追加します。コンテンツ・プロバイダーが提供するのはツリー全体の親と子の関係で、一方のラベル・プロバイダーが提供するのは各要素によって表される画像とテキストです。最後に、この TreeViewer に入力ノードを設定します。この入力はデータ・モデルのルート・ノードでなくてはならないことに注意してください。この例では、まずルート・ノードを作成して 3 つの NBATeamNode を別々のチーム名として追加し、各チームには変数 NBAPlayer を使って 5 人の先発 NBA プレイヤーを追加します。ご覧のように、ここでは「root」と名付けたルート NBATeamNode を TreeViewer に入力しています。
リスト 2. SampleView クラス
public void createPartControl(Composite parent){
composite= new Composite(parent,SWT.NONE);
composite.setLayout(new GridLayout(1,false));
treeviewer = new TreeViewer(composite);
treeviewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
treeviewer.setContentProvider(new SampleTreeContentProvider());
treeviewer.setLabelProvider(new SampleTreeLabelProvider());
treeviewer.setInput(getInput());
treeviewer.expandAll();
}
private NBATeamNode getInput(){
NBATeamNode root = new NBATeamNode("root");
NBATeamNode team1= new NBATeamNode("Houston Rockets");
NBATeamNode team2= new NBATeamNode("LA Lakers");
...
root.addTeam(team1);
root.addTeam(team2);
...
team1.addPlayer(new NBAPlayer("Yao Ming"));
team1.addPlayer(new NBAPlayer("Tracy McGrady"));
...
return root;
} |
ツリーのコンテンツ・プロバイダーが実装するのは、ITreeContentProvider です。このツリーの親と子の関係は、getParent および getChildren メソッドを使って定義します。そして最後に、getElements メソッドを使って各要素のサブ要素を取得します。
リスト 3. TreeViewerContentProvider
public class SampleTreeContentProvider implements ITreeContentProvider {
//other methods are not mentioned here are unchanged
public Object[] getChildren(Object arg0) {
if(arg0 instanceof NBATeamNode) {
NBATeamNode node = (NBATeamNode)arg0;
return concat(node.getteams().toArray(),node.getplayers().toArray());
}
return EMPTY_ARRAY;
}
protected Object[] concat(Object[] object, Object[] more) {
Object[] both = new Object[object.length + more.length];
System.arraycopy(object, 0, both, 0, object.length);
System.arraycopy(more, 0, both, object.length, more.length);
return both;
}
public Object getParent(Object arg0) {
return ((NBATeamNode) arg0).getParent();
}
public Object[] getElements(Object arg0) {
return getChildren(arg0);
}
|
ツリーのラベル・プロバイダーは、ILabelProvider を実装します。以下のリストを見るとわかるように、各ノードが表す画像とテキストは、getImage メソッドと getText メソッドを使って定義します。
リスト 4. TreeViewerLabelProvider
public class SampleTreeLabelProvider implements ILabelProvider {
//other methods are not mentioned here are unchanged
private ArrayList listeners;
private Image Team, Player;
public SampleTreeLabelProvider(){
listeners = new ArrayList();
Team = new Image(null, getClass().getResourceAsStream("/res/file.png"));
Player= new Image(null, getClass().getResourceAsStream("/res/folder.png"));
}
public Image getImage(Object arg0) {
if(arg0 instanceof NBATeamNode){
return Team;
}else{
return Player;
}
}
public String getText(Object arg0) {
if(arg0 instanceof NBATeamNode) {
return ((NBATeamNode)arg0).toString();
}else{
return ((NBAPlayer)arg0).toString();
}
}
public void dispose() {
if(Team != null) Team .dispose();
if(Player != null) Player.dispose();
}
} |
このデモ・アプリケーションを機器上の eWorkbench にデプロイすると、アプリケーション・リストに Test TreeViewer Sample という名前のアイコンが表示されます。コマンド・ウィンドウで Open をクリックして、このアプリケーションを起動してください。すると、上記の手順で作成したツリーが表示されます。各チームを展開すると、チームの名簿に該当するプレイヤーが表示されるはずです。
図 1. 機器上の eWorkbench での TreeViewer デモ・アプリケーション
TableViewer
TableViewer のデモ・アプリケーションを設計する場合に作成しなければならないのは、データ・モデル・クラスです。ここでは Book.java を作成します。以下のように、表の列に出力されるプロパティーは 5 つです。後で使用できるように、それぞれのプロパティーには getter-setter メソッドを使う必要があります。
リスト 5. データ・モデル・クラスの定義
public class Book {
String name;
String isbn;
String publisheddate;
String price;
String available;
public String getAvailable() {
return available;
}
public void setAvailable(String available) {
this.available = available;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getPublisheddate() {
return publisheddate;
}
public void setPublisheddate(String publisheddate) {
this.publisheddate = publisheddate;
}
} |
org.eclipse.ercp.eworkbench.applications を拡張した後、TableViewer インスタンスを作成し、SampleView クラスの createPartControl メソッドにある現行の composite に関連付けます。次に望ましいレイアウトを設定しますが、テーブル・ビューアーにコンテンツ・プロバイダーとラベル・プロバイダーのインスタンスを追加する前に、まずテーブルを作成してください。テーブルには適切な数の列とそれぞれの列に対応する名前を含め、各列をテーブルに配置して見えるようにします。最後にテーブルのコンテンツ・プロバイダーとラベル・プロバイダーを設定し、この TableViewer に入力を設定します (つまり、データをフィードします)。この入力はデータ・モデルの ArrayList でなくてはならないことに注意してください。ここでは、まず ArrayList を作成してから 3 つのブック・インスタンスを追加しています。テーブルに含まれるフィールドの値は、コンテンツ・プロバイダーとラベル・プロバイダーのクラスに応じて設定されます。
リスト 6. SampleView クラス
public void createPartControl(Composite parent) {
composite= new Composite(parent,SWT.NONE);
composite.setLayout(new GridLayout(1,false));
tableviewer = new TableViewer(composite);
Table table = tableviewer.getTable();
table.setLayoutData(new GridData(GridData.FILL_BOTH));
column0 = new TableColumn(table,SWT.LEFT,0);
column0.setText("Books Name");
column1 = new TableColumn(table,SWT.LEFT,1);
column1.setText("ISBN");
column2 = new TableColumn(table,SWT.LEFT,2);
column2.setText("Published Date");
column3 = new TableColumn(table,SWT.LEFT,3);
column3.setText("Price");
column4 = new TableColumn(table,SWT.LEFT,4);
column4.setText("Available Now?");
for(int i =0, n=table.getColumnCount();i<n;i++){
table.getColumn(i).pack();
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
tableviewer.setContentProvider(new SampleTableContentProvider());
tableviewer.setLabelProvider( new SampleTableLabelProvider());
tableviewer.setInput(getInput());
}
private ArrayList getInput() {
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Book();
b1.setName("Red Book");
b1.setIsbn("U2w3e4r5t6y");
b1.setPublisheddate("1980-08-28");
b1.setPrice("$1000");
b1.setAvailable("Yes");
b2.setName("Blue Book");
b2.setIsbn("U1q2w3e4r");
...
return Books;
} |
TableViewerContentProvider は IStructuredContentProvider インターフェースを実装しなければなりません。TableViewerContentProvider が定義するのは、このテーブルの表示関係です。このクラスを見るとわかるように、特定の配列の各データ (ブック名や価格を表すデータ) は getElements メソッドを使って取得できます。
リスト 7. TableViewerContentProvider
public class SampleTableContentProvider implements IStructuredContentProvider {
//other methods are not mentioned here are unchanged
public Object[] getElements(Object arg0) {
return ((ArrayList)arg0).toArray();
}
} |
TableViewerLabelProvider は ITableLabelProvider インターフェースを実装します。TableViewerLabelProvider が定義するのは、このテーブルに含まれる各列のテキストまたは画像です。各要素のテキストは、getColumnText メソッドで取得することができます (この例では getColumnImage メソッドは実装しませんでした)。
リスト 8. TableViewerLabelProvider
public class SampleTableLabelProvider implements ITableLabelProvider {
//other methods are not mentioned here are unchanged
public Image getColumnImage(Object arg0, int arg1) {
return null;
}
public String getColumnText(Object arg0, int arg1) {
String result = "";
Book book = (Book) arg0;
switch(arg1){
case 0:
result = book.getName();
break;
case 1:
result = book.getIsbn();
break;
case 2:
result = book.getPublisheddate();
break;
case 3:
result = book.getPrice();
break;
case 4:
result = book.getAvailable();
break;
}
return result;
}
public boolean isLabelProperty(Object arg0, String arg1) {
return false;
}
} |
このデモ・アプリケーションを機器上の eWorkbench にデプロイすると、アプリケーション・リストに Test TableViewer Sample という名前のアイコンが表示されるはずです。コマンド・ウィンドウで Open をクリックしてアプリケーションを起動すると、上記で作成したテーブルを確認できます。
図 2. 機器上の eWorkbench での TableViewer デモ・アプリケーション
eJFace org.eclipse. jface.preference のデモ・アプリケーション
PreferencePage
必要な設定データ (サーバー情報、ユーザー名、パスワードなど) の保管用に唯一 eJFace が提供している PreferencePage は、eWorkbench を対象としている間しか動作しません。eWorkbench アプリケーションを開発し、このアプリケーションに拡張ポイントを追加することで設定アプリケーションを組み込む方法については、「参考文献」を参照してください。図 3 には、OK、Cancel、Restore to Default value ボタンを組み込んだ単純な設定アプリケーションを開発する過程を示してあります。
リスト 9. plugin.xml への追加
<extension point="org.eclipse.ui.preferencePages">
<page
class="preferencesample.PrefPageOne"
id="preferenceSample.page1"
name="Server authentication"/>
</extension>
|
設定ページが eWorkbench に表示されるようにするには、設定ページ・クラスが PreferencePage を拡張して IWorkbenchPreferencePage を実装する必要があります。最初に宣言するのは、String、Text、Label、Button、および PreferenceStore を含めた必須の変数です。PreferenceStore は入力された名前と値のペアを保管します。ユーザーの設定を表示するために使用するのは、createContents メソッドです。
まず始めにコンポジット (composite) 設定ページを作成し、GridLayout を使ってレイアウトを設定します。次に、固有の名前を持つ PreferenceStore を作成し、この PreferenceStore からデータをロードします。そして、ユーザーが値を入力する 3 つのテキスト・フィールドを作成します。この 3 つのフィールドの値は、サーバー・アドレス、ユーザー名、パスワードです。フィールドのデフォルト値を設定するには、SetDefaultValue() を使用します。ユーザーが設定ページを開くと、これらのデフォルト値が表示されます。
デフォルト値をリセットするのに使用するのは、performDefaults です。performOK は、値を入力して OK をクリックしたときに値を保管するために使用し、performCancel は Cancel をクリックしたときに値を保管しないで設定ページを終了するために使用します。init(IWorkbench arg0) は、設定ページが IWorkbenchPreferencePage を実装する場合に実装しなければならない必須のメソッドです。
リスト 10. 設定ページのサンプル・コード
public class PrefPageOne extends PreferencePage implements IWorkbenchPreferencePage{
private static final String SERVERADDR = "SERVERADDR";
private static final String USERNAME = "USERNAME";
private static final String USERPASSWORD = "USERPASSWORD";
private Text fieldOne;
private Text fieldTwo;
private Text fieldThree;
Label label1, label2, label3;
Composite composite;
Button defaultbutton;
PreferenceStore preferenceStore;
protected Control createContents(Composite parent){
composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2,false));
preferenceStore = new PreferenceStore("com.ibm.test.ejface.preference");
try {
preferenceStore.load();
}catch (IOException e) {}
label1 = new Label(composite, SWT.LEFT);
label1.setText("Server address:");
label1.setground(new Color(composite.getDisplay(),0x66, 0xCC, 0xFF));
fieldOne = new Text(composite, SWT.SINGLE | SWT.BORDER);
fieldOne.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
label2 = new Label(composite, SWT.LEFT);
label2.setText("Username:");
fieldTwo = new Text(composite, SWT.SINGLE | SWT.BORDER);
fieldTwo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
label3 = new Label(composite, SWT.LEFT);
label3.setText("Password:");
fieldThree = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
fieldThree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
SetDefaultValue();
fieldOne.setText(preferenceStore.getString(SERVERADDR));
fieldTwo.setText(preferenceStore.getString(USERNAME));
fieldThree.setText(preferenceStore.getString(USERPASSWORD));
defaultbutton = new Button(composite,SWT.PUSH | SWT.LEFT);
defaultbutton.setText("Restore to Default value");
defaultbutton.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
performDefaults();
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
return composite;
}
protected void performDefaults(){
fieldOne .setText(preferenceStore.getDefaultString(SERVERADDR));
fieldTwo .setText(preferenceStore.getDefaultString(USERNAME));
fieldThree.setText(preferenceStore.getDefaultString(USERPASSWORD));
}
public boolean performOk(){
if(fieldOne != null && fieldOne .getCharCount() != 0)
preferenceStore.setValue(SERVERADDR, fieldOne .getText());
if(fieldTwo != null && fieldTwo .getCharCount() != 0)
preferenceStore.setValue(USERNAME, fieldTwo .getText());
if(fieldThree != null && fieldThree.getCharCount() != 0)
preferenceStore.setValue(USERPASSWORD, fieldThree.getText());
try{
preferenceStore.save();
} catch (IOException e) {
return false;
}
return true;
}
private void SetDefaultValue() {
if (fieldOne != null && fieldOne.getCharCount() == 0) {
preferenceStore.setDefault(SERVERADDR, "www.ibm.com");
}
if (fieldTwo != null && fieldTwo.getCharCount() == 0) {
preferenceStore.setDefault(USERNAME, "Administrator");
}
if (fieldThree != null && fieldThree.getCharCount()== 0) {
preferenceStore.setDefault(USERPASSWORD, "admin");
}
}
public boolean performCancel() {
composite.dispose();
this.dispose();
return true;
}
public void init(IWorkbench arg0) {
}
} |
このデモ・アプリケーションを機器の eWorkbench にデプロイすると、Preference Demo Application のリストにアイコンが表示されます。入力した内容を保管するには OK を、設定ページを終了するには Cancel をクリックしてください。Restore to Default value をクリックすると、各テキスト・フィールドの値がデフォルトに戻ります。
図 3. 機器上の eWorkbench での設定ページ・デモ・アプリケーション
eJFaceorg.eclipse. jface.resource のデモ・アプリケーション
eJFace は org.eclipse.jface.resource パッケージの重要なライブラリーのみを提供します。このデモ・アプリケーションで実演するのは、ImageRegistry と fontRegistry を使って画像およびフォント・オブジェクトを効率的に管理する方法です。このデモでは、該当するウィジェットの色を管理しやすくするために JFaceColors も導入しています。さらに、コマンド・ウィジェットを使用して org.eclipse.jface.action の機能を実行する方法も説明します。
リスト 11 に記載するデモ・コードは、レジストリーを使用して該当するウィジェットにフォント、色、そして画像を設定するコードです。このコードには eSWT コマンド・ウィジェットを構成する方法も示しています。eSWT コマンド・ウィジェットは、eWorkbench のアプリケーションを対象にしている間しか動作しません。eWorkbench アプリケーションの開発方法について学びたい場合は、「参考文献」を参照してください。
ImageRegistry は、さまざまな画像を保管し、ロードするために使用します。put() および get() メソッドによって、簡単に画像に名前を割り当て、多数の画像を管理することが可能です。FontRegistry は ImageRegistry と似通っていて、各種 fontData の保管およびロードに使用されます。ユーザーは put および get メソッドを使用して効率的にフォントを管理できます。ImageRegistry およびFontRegistry をプログラム全体で管理するには、JFaceResources を使用します。
JFaceColors では、ウィジェットの前景と背景に特定の色を動的に割り当てることができます。Java ストリング操作の機能を提供するのは StringConverter です。このデモでは、StringConverter を使ってストリング・オブジェクトを StringArray にします。
コマンド・ウィジェットは eSWT に含まれる重宝な API で、コマンドは追加されたウィジェットにフォーカスが置かれている間だけ現れます。このサンプルでは RecoverCommand が composite オブジェクトに対して追加されるので、composite オブジェクトにフォーカスがある間は RecoverCommand が表示され、フォーカスが外れると RecoverCommand の表示は消えます。RecoverCommand には SelectionListener を追加します。RecoverCommand が選択されると、widgetSelected が呼び出されます。
以下は、機器上のリソース・デモのサンプルです (ソース・コードについては「ダウンロード」を参照)。
リスト 11. リソースのサンプル・コード
//ImageRegistry demo
ImageRegistry ir = new ImageRegistry();
ir.put("img1",new Image(display,getClass().getResourceAsStream("/icons/ibm1.png")));
ir.put("img2",new Image(display,getClass().getResourceAsStream("/icons/ibm2.png")));
Label Imagelabel = new Label (composite, SWT.LEFT);
Imagelabel.setImage(ir.get("img1"));
//FontRegistry demo
FontRegistry fr = new FontRegistry(composite.getDisplay());
FontData[] fd = new FontData[2];
fd[0]= new FontData("Tacoma",20, SWT.NORMAL);
fd[1]= new FontData("Times New Roman",12, SWT.NORMAL);
fr.put("SysFont", fd);
Label Fontlabel = new Label (composite, SWT.LEFT);
Fontlabel.setText("FontRegistry");
Font normalfont = new Font(composite.getDisplay(),fr.getFontData("SysFont")[0]);
Fontlabel.setFont(normalfont);
JFaceResources.setFontRegistry(fr);
Font font = new Font(display, JFaceResources.getFontRegistry().getFontData
("SysFont")[1]);
//JFaceColors demo
Label JFaceColorslabel = new Label (composite, SWT.LEFT);
JFaceColorslabel.setText("JFaceColors");
JFaceColors.setColors(JFaceColorslabel, composite.getDisplay().getSystemColor
(SWT.COLOR_DARK_YELLOW), composite.getDisplay().getSystemColor(SWT.COLOR_BLUE));
String[] stringArray = StringConverter.asArray("eJface Developer Works");
Command RecoverCommand = new Command(composite, Command.OK, 0);
RecoverCommand.setText("Default Setting");
RecoverCommand.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Imagelabel.setImage(ir.get("image1"));
Imagelabel.redraw();
Fontlabel.setFont(font);
Fontlabel.redraw();
stringButton.setText("eJface Developer Works");
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}); |
図 4. eJFace リソースのサンプル (変更前)
図 5. eJFace リソースのサンプル (変更後)
eWorkbench での eJFace 統合デモ・アプリケーション
今度は上記で説明したすべてのサブ機能を 1 つのサンプルに統合する番です。まず始めに、ユーザーの選択に応じて NBA または MLB プレイヤーを表示できる 1 つの TreeViewer を作成します。設定ページには、NBA ページと MLB ページのどちらがアクティブになっているかによって該当するデフォルト値が表示されます。次に、ウィンドウで特定のチームまたはプレイヤーを強調表示し、コマンド・ウィンドウで 2005~2006 record をクリックします。すると、機器がこのレコードを記録するテーブルを作成します。このテーブルは、TableViewer で作成されています。ソース・コードは大き過ぎるため、ここには記載しきれません。また、この統合サンプルに新しい機能は追加されていないので、詳細については「ダウンロード」のソース・コードを調べてください。図 6、図 7、図 8 に、機器上で統合された様子を示します。
図 6. eWorkbench に表示された eJFace 統合のサンプル
図 7. NBA 設定ページ (NBA のデフォルト値)
図 8. プレイヤーの記録をリストしたテーブル
まとめ
eJFace アプリケーションを開発するために必要なステップを紹介したこの記事では、JFace と eJFace の違いを見極め、eJFace 開発の背景にある動機を探りました。さらに eJFace ライブラリーの構造とその API およびそれぞれの用途を検討した上で、eRCP 環境内で eJFace、eSWT、eWorkbench アプリケーションを開発する方法を説明し、最後に eJFace の機能をアプリケーションに追加しました。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Source code | eJFaceSample_1.0.zip | 515KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Sam Lo は IBM China Software Development Lab のソフトウェア開発者であると同時に、Lotus クライアント技術にも取り組んでいます。旅行、音楽、そしてスポーツを趣味とする彼は、ヒューストン・ロケッツとデトロイト・タイガースのファンです。この記事でスポーツ関連のサンプルが使われている訳もこれで納得できます。 |
 | 
|  | Eric Hsu は、台北にある IBM China Software Development Lab のソフトウェア開発者で、Lotus Expediter クライアント技術および Eclipse eRCP プロジェクト開発に取り組んでいます。彼は Eclipse eRCP プロジェクトのコミッターでもあります。 |
記事の評価
|  |