ここからは、いよいよSWTを使用した開発を実践的に解説していきます。
今回はSWTのアプリケーションとして、CSVファイルを表形式で表示するCSVViewerを作成します。CSVViewerの概観は、以下のようになります。
このアプリケーションの仕様は、以下のとおりです。
ここでは、以下の順番でアプリケーションの作成を行います。
(1) シェル(ウィンドウ)の生成
(2) シェルへのウィジェット(GUIコンポーネント)の配置
(3) CSV読み込み、表示処理の実装
(4) ウィジェットへのイベントリスナーの登録(処理の追加)
まずここでは、ウィンドウを表示できるところまで完成させます。
Eclipseのメニューから、[ファイル]->[新規]->[クラス]で新規Javaクラスダイアログを開きます。以下のとおり入力して、[終了]ボタンをクリックします。
ソース・フォルダ | swtPrj/src |
---|---|
パッケージ名 | csvviewer |
名前 | CSVViewer |
Eclipseが生成したコードを以下のように編集します。
package csvviewer; |
一般的なSWTアプリケーションの処理の流れは、次のようになります(番号はコード中の番号に対応しています)。
(1) SWTセッションを表すDisplayオブジェクトを生成
(2) アプリケーションのメイン・ウィンドウとなる1つ以上のShellを生成
(3) ウィンドウ内で必要となる他のウィジェットを生成
(4) ウィジェットのサイズや、その他の必要な状態を初期化
(5) 処理を実行する必要のあるウィジェットにリスナーを登録
(6) Shellを開く
(7) メイン・ウィンドウが破棄されるまで、DisplayオブジェクトのreadAndDispatchメソッドとsleepメソッドでループ
(8) メイン・ウィンドウが破棄されたら、Displayオブジェクトを破棄
ここまでのCSVViewerでは、上記のうち(1)、(2)、(6)、(7)、(8)を実装しています。上記のソースコードにコメントとして記述されている番号と見比べてください。
CSVViewerのソースが選択されている状態で、Eclipseのメニューから「実行」->「次を実行」->「Javaアプリケーション」を選択すると、プログラムを実行できます。以下のようなウィンドウが表示されます。
アプリケーションとしてはこれ以上何もできませんので、CSVViewerのタイトルバー上の「×」ボタンをクリックし、終了してください。
ここまでのソースは、ここからダウンロードしてください(ファイル名、クラス名を変えています)。
次に、「(3)ウィンドウ内で必要となるほかのウィジェットを生成」と「(4)ウィジェットのサイズや、そのほかの必要な状態を初期化」を実装します。
以下では、修正個所ごとに説明を行います。変更した行は強調表示してあります。
後で別のメソッドから操作されるウィジェットは、インスタンス変数に宣言しておきます。
private Shell shell; |
textBox、table、statusBar、mItemOpenを宣言しました。
CSVViewerのopenメソッド内で、ウィジェットを生成する前に、shellに対しGridLayoutを指定します。
this.display = display; |
GridLayoutのコンストラクタの引数numColumnsに1を指定したので、shellに追加されるウィジェットは、縦1列に並べられます。
shellの設定の次に、テキストボックスとテーブルを配置するためのCompositeを生成します。
// 部品を複数配置できるCompositeを生成 ); |
CompositeにはShell同様、GridLayoutを指定します。
また、GridDataを設定し、親ウィジェットとなるShellのGridLayoutに対して幅全体、高さ全体に広がった配置が行われるようにしています。
Compositeを生成した後、単一行のテキストボックスを作成します。親ウィジェットには先ほど作成したCompositeを指定します。
// 単一行テキストボックスを作成 |
単一行であるか、複数行であるかは、生成時にコンストラクタのstyleというフラグで指定します。さらに今回はボーダー(ふち)を付けるようにBORDERを指定しました。フラグは、ビット演算子「|」で複数指定することができます。
また、GridDataを設定し、親ウィジェットとなるCompositeのGridLayoutに対して幅全体に広がった配置が行われるようにしています。
テキストボックスに続いて、CSVファイルのデータを表示するためのテーブルを生成します。親ウィジェットには、Compositeを指定します。
複数列を扱うMULTI、テーブル内の行を選択した際、1行全体が選択されるようにするFULL_SELECTION、ボーダーを付けるようにBORDERを指定しています。
// テーブルの作成 |
また、GridDataを設定し、親ウィジェットとなるCompositeのGridLayoutに対して幅全体、高さ全体に広がった配置が行われるようにしています。
罫線を表示するためのsetLinesVisibleメソッド、列のヘッダを表示するためのsetHeaderVisibleメソッドを呼んでいます。
また、列のヘッダの設定を行います。ここで設定するのはCSVファイルを読み込んでいない状態で表示されるテーブルなので、取りあえず1列分だけ設定します。
SWTではステータスバーというウィジェットは存在しないので、文字を表示するラベルを設定します。親ウィジェットにShellを指定します。
// ステータスバーの作成 |
GridDataを設定し、親ウィジェットとなるShellのGridLayoutに対して幅全体に広がった配置が行われるようにしています。
MenuBarをShellに設定し、その子要素として以下の親子関係を持つメニューを作成します。
MenuBar + |
// メニューの作成 |
MenuItem([ファイル])には、子要素としてメニューを持たせるためのCASCADEを指定します。MenuItem([開く])、MenuItem([終了])は、選択したときにイベントを発生させるためのPUSHを指定します。
ここまでのソースファイルはここから入手できます(ファイル名、クラス名を変えています)。
Eclipse上のメニューから[実行]->」前回の起動を[実行]を選択(又はキーボードから[Ctrl + F11]を入力)すると、以下のようなウィンドウが表示されます。
必要なウィジェットが配置され、アプリケーションらしくなってきました。ウィンドウのサイズを変更し、GridDataが期待どおりのレイアウトを行うかどうか確認してください。
しかし、ここまでのCSVViewerでは[開く]や[終了]メニューを選択しても何も起こりません。CSVViewerのタイトルバー上の[×]ボタンをクリックし、終了してください。
次のCSVViewerでは、「(5)処理を実行する必要のあるウィジェットにリスナーを登録」を実装し、メニューを選択したときの処理を追加していきます。まずは処理の実装から行います。
引き続き、修正個所ごとに説明していきます。
// ファイルダイアログ用のフィルタ拡張子 |
CSVファイル名を代入するfileNameと、ファイルダイアログを使用する際のフィルタ拡張子のEXTENSIONS、読み込み時間測定のためのbeginTimeを宣言します。
メニューを呼び出したときにもテーブルを再作成する処理を行うため、テーブルの作成部をメソッドとして抽出し、コードの重複を防ぎます。
openメソッド内の該当個所をドラッグして選択し、Eclipseのメニューから[リファクタリング]->[メソッドの抽出]を選択します。メソッド名に「createTable」と入力し、[OK]をクリックします。
public Shell open(Display display) { |
ファイルダイアログを開き、ファイル名を入手する処理を実装します。
private void getOpenFileName() { |
ファイル名を取得後、実際に読み込み処理に入る前の処理を実装します。
private void loadBegin() { |
ファイル読み込み中は、新たにファイルの読み込みを始められないように、[開く]メニューを選択不可にします。
SWTのテーブルでは、一度設定したカラムは破棄することができません。そのため、テーブル自体を再作成しています。テーブルの再作成には、先ほど抽出したcreateTableメソッドを呼び出します。
テキストボックスとステータスバーの表示を変え、読み込み時間測定用に現在の時間をSystem.currentTimeMillisメソッドで取得します。
ファイル名が存在した場合、カンマ区切りでデータを読み込み、テーブルにセットしていきます。
private void loadFile() { i < datas.length; i++) { |
BufferedReaderを使用して1行ごとにファイルから読み込みます。カンマで区切る処理はJDK1.4から使用できるsplitメソッドを使用しています。
また、現在テーブルが持つ列数よりも読み込んだデータの列数の方が多かった場合、差分をカラムとして追加しています。
テーブルへのデータの追加は、TableItemオブジェクトを生成することで実現できます。TableItemオブジェクトのsetTextメソッドを使用し、読み込んだ値を設定します。
最後にfinally句で、BufferedReaderをcloseします。
ファイル読み込み後の処理を実装します。
private void loadEnd() { |
前処理で実施した、[開く]メニューの無効化を解除します。また、ステータスバーに、読み込み処理にかかった時間をミリ秒で表示します。
[終了]メニュー実行時に呼び出される終了処理を実装します。
private void close() { |
テーブル内の行を選択した際に、行番号をステータスバーに表示するための処理を実装します。
private void setTableSelectedIndex() { |
以上で必要な処理が実装できました。
Copyright © ITmedia, Inc. All Rights Reserved.