デスクトップアプリケーションでの Beans とデータのバインド
このチュートリアルでは、NetBeans IDE 6.0 でサポートされている Java デスクトップアプリケーションでの Beans Binding 機能とデータのバインド機能の概要を示します。
目次
|
|
 |
このチュートリアルに必要なソフトウェアとファイル
このチュートリアルでは、コンピュータに次のソフトウェアをインストールしておく必要があります。
概要: NetBeans IDE 6.0 での Beans Binding
Beans Binding ライブラリがリリースされるまで、UI コンポーネントをデータベースに接続したり、コンポーネントのプロパティーの値の同期を保ったりするのは面倒でした。たとえば、標準データベースのデータを JTable に表示するには、データベースと JTable の接続を処理するユーティリティークラスを手作業で作成する必要がありました。また、異なる Bean のプロパティーの値 (たとえば JTextField の値とビジュアル Bean のレンダリング) の同期を保つには、リスナーやイベントハンドラを手作業でコーディングする必要がありました。
Beans Binding ライブラリによって、このすべての処理が簡単になり、また標準化されます。どのコンポーネントのどのプロパティーを同期する必要があるのかを指定する数行のコードを記述するだけで、残りの処理は Beans Binding ライブラリによって実行されます。NetBeans IDE では、Beans Binding 機能は GUI ビルダーに統合されているので、アプリケーションの視覚的なデザインが完成したらすぐに動作をコーディングできます。
このチュートリアルでは、IDE での Beans Binding の主な機能について説明します。これらの機能の具体的な例については、Java デスクトップデータベースアプリケーションの構築のチュートリアルを参照してください。
プロパティー間のバインド
Beans Binding は、基本的にイベントリスナーやイベントハンドラをコーディングせずに Bean のプロパティーを接続する方法です。
Beans Binding の概念と IDE に用意されている機能を示すために、ユーザーがスライダを調整してテキストフィールド内の数値を変更できる簡単な例を使用します。
例を設定する
- IDE で、「ファイル」>「新規プロジェクト」を選択します。
- 「Java」カテゴリを選択し、「Java Application」テンプレートを選択します。「次へ」をクリックします。
- ウィザードの「名前と場所」ページで、次の操作を行います。
- プロジェクト名に「NumberSlider」と入力します。
- 「主プロジェクトとして設定」チェックボックスがすでに選択されていることを確認します。
- 「主クラスを作成」チェックボックスを選択解除します。
- 「完了」をクリックしてウィザードを終了し、プロジェクトを設定します。
- 「プロジェクト」ウィンドウで「NumberSlider」プロジェクトノードを右クリックし、「新規」>「JFrame フォーム」を選択します。
「JFrame フォーム」が「新規」メニューにない場合は、「その他」を選択します。次に「新規ファイル」ウィザードで「Swing GUI フォーム」カテゴリを選択してから「JFrame フォーム」テンプレートを選択します。
- ウィザードの「名前と場所」ページで、次の操作を行います。
- クラス名に「NumberSliderFrame」と入力します。
- パッケージ名に「numberslider」と入力します。
- 「完了」をクリックしてウィザードを終了し、フォームを作成します。
NumberSliderForm.java が編集領域にデザインモードで開きます。
- パレットの「Swing コントロール」セクションからスライダコンポーネントをデザイン領域までドラッグします。「パレット」ウィンドウが開いていない場合は、「ウィンドウ」>「パレット」を選択します。
- パレットから、テキストフィールドコンポーネントをデザイン領域までドラッグします。
フォームは次のスクリーンショットのようになります。この例では、配置は重要ではありません。
ソースとターゲット
例を設定したので、バインドを作成します。ただし、その前にバインドのソースにするコンポーネントとターゲットにするコンポーネントを決定する必要があります。バインドのソースコンポーネントは、プロパティー値のバインド元です。
GUI エディタでバインドを行う場合は、ターゲットでバインドを開始してから、「バインド」ダイアログでソースを宣言します。
この例では、JSlider にデフォルトの値の範囲があるので、このコンポーネントをソースとして使用します。
注: バインドを 2 方向 (読み取り/書き込み) にして、ターゲットの変更内容がソースに自動的に反映されるようにできます。ただし、最初のバインドの方向は常にソースからターゲットになります。詳細は、バインドの詳細設定の更新モードに関する説明を参照してください。
スライダをテキストフィールドにバインドする
- テキストフィールドコンポーネントを右クリックし、「バインド」>「テキスト」を選択して「バインド」ダイアログを開きます。
- 「ソースをバインド」コンボボックスで「jSlider1」を選択します。
- 次のスクリーンショットに示すように、「式をバインド」コンボボックスで「value int」を選択します。
- 「閉じる」をクリックします。
これで、スライダの「value」Bean プロパティーがテキストフィールドの「text」の値にバインドされました。
デザイン領域で、テキストフィールドに値 50 が表示されます。この値は、スライダが中央の位置にあり、スライダのデフォルトの値の範囲が 0 ~ 100 であることを反映しています。
これでアプリケーションを実行し、バインドが機能するところを確認できます。
プロジェクトを実行する
- 「実行」>「主プロジェクトを実行」を選択します。
- 「プロジェクトの実行」ダイアログで、「了解」をクリックし、主クラスとして numberslider.NumberSliderForm を使用します。
アプリケーションが別のウィンドウで起動します。実行中のアプリケーションでスライダを調整し、テキストフィールド内の値が変わることを確認します。
カスタム Beans のバインド
自作の Bean がある場合、その Bean に IDE のバインド機能を使用するには、その前にいくつかの処理を行う必要があります。次のいずれかの方法が可能です。
- Bean をパレットに追加し、標準の Swing コンポーネントと同じようにフォームに追加できるようにします。
- Bean クラスをプロジェクトに追加し、Bean をコンパイルします。
「パレット」ウィンドウに Bean を追加する
- Bean がコンパイルされていることを確認します。
- 「ツール」>「パレットマネージャー」を選択します。
- Bean の新規パレットカテゴリを作成する場合は、Bean を追加する前に「新規カテゴリ」をクリックし、使用する名前を入力します。
- 「JAR から追加」、「ライブラリから追加」、または「プロジェクトから追加」をクリックし、ウィザードを完了して Bean を追加します。
プロジェクトから Bean を追加する
- プロジェクトのウィンドウで Bean のノードを右クリックし、「ファイルをコンパイル」を選択します。
- Bean をフォームまでドラッグします。
すると、Bean が「インスペクタ」ウィンドウに表示されます。Bean の任意のプロパティーの「バインド」ダイアログを開くことができます。
バインドの詳細設定
上の例では、一部にデフォルトの動作を使用した簡単なバインド方法を示しました。実際には、バインドの設定を変更する必要がある場合があります。その場合は、「バインド」ダイアログの「詳細」タブを使用できます。
このダイアログの「詳細」タブには、次のフィールドがあります。
- 名前。バインドの名前を作成できます。これにより、バインドをより柔軟に管理できます。名前はバインドのコンストラクタに追加され、バインドの getName() メソッドで参照できます。
- モードを更新。プロパティーの同期の維持方法を指定します。可能な値は次のとおりです。
- 常に同期 (読み取り/書き込み)。ソースまたはターゲットのいずれかに変更が行われると、もう一方が更新されます。
- ソースから読み取りのみ (読み取り専用)。最初にソースの値が設定されたときのみターゲットが更新されます。ソースに変更を行うと、ターゲットも更新されます。ターゲットに変更を行なっても、ソースは更新されません。
- ソースから一度読み取り (一度読み取り)。ターゲットとソースが最初にバインドされたときのみターゲットが更新されます。
- ソースの更新時期 (JTextField および JTextArea コンポーネントの text プロパティーでのみ使用可能)。プロパティーを同期する頻度を選択できます。
- 調整を無視 (JSlider の「value」プロパティー、JTable および JList の「selectedElement」プロパティー、JTable および JList の「selectedElements」プロパティーでのみ使用可能)。このチェックボックスを選択すると、あるプロパティーに対して行われた変更は、ユーザーが変更を完了するまで、もう一方のプロパティーに反映されません。たとえば、アプリケーションのユーザーがスライダを移動させた場合、スライダの「value」プロパティーがバインドされたプロパティーの値は、ユーザーがマウスのボタンを離すまで更新されません。
- コンバータ。バインドされたプロパティーに異なる型のデータが含まれる場合、それぞれの型の間で値を変換するコードを指定できます。Beans Binding ライブラリでは一般的な変換の多くを処理できますが、それ以外のプロパティーの型の組み合わせが存在する場合は、独自のコンバータが必要な場合もあります。このようなコンバータは、org.jdesktop.beansbinding.Converter クラスを拡張する必要があります。
「コンバータ」ドロップダウンリストには、フォームに Bean として追加されたコンバータが含まれています。また、省略符号ボタン (...) をクリックし、「コンバータプロパティーの使用方法を選択」ドロップダウンリストから「カスタムコード」を選択して、変換コードを直接追加することもできます。
- バリデータ。変更をソースプロパティーに反映させる前に、ターゲットプロパティー値の変更内容の妥当性検査を行うためのコードを指定できます。たとえば、整数のプロパティー値が特定の範囲内になるようにバリデータを使用できます。
バリデータは、org.jdesktop.beansbinding.Validator クラスを拡張する必要があります。
「バリデータ」ドロップダウンリストには、フォームにBean として追加されたバリデータが含まれています。また、省略符号ボタン (...) をクリックし、「バリデータプロパティーの使用方法を選択」ドロップダウンリストから「カスタムコード」を選択して、妥当性検査のコードを直接追加することもできます。
- ソースの値が NULL。バインドの試行時にソースプロパティーの値が Null の場合、異なる値を使用するよう指定できます。このフィールドは、org.jdesktop.beansbinding.Binding クラスの setSourceNullValue() メソッドに対応します。
- 読み取り不能なソース値。バインドの試行時にバインド式が解決できない場合、異なる値を使用するよう指定できます。このフィールドは、org.jdesktop.beansbinding.Binding クラスの setSourceUnreadableValue() メソッドに対応します。
注: 前述のクラスやメソッドについて詳しく理解するには、IDE から Beans Binding に関する Javadoc ドキュメントに直接アクセスしてください。「ヘルプ」>「Javadoc 参照」>「Beans Binding」を選択します。開かれたブラウザウィンドウで、「org.jdesktop.beansbinding」リンクをクリックし、これらのクラスのドキュメントにアクセスします。
コンポーネントへのデータのバインド
新しい Java フォームを作成し、コンポーネントをフォームに追加したら、それらのコンポーネントをデータにバインドするためのコードを生成できます。IDE では、Swing の JTable、JList、および JComboBox の各コンポーネントにデータを簡単にバインドできます。
コンポーネントをデータベース内のデータにバインドする前に、次の作業が行われている必要があります。
- IDE でデータベースに接続している。
- GUI ビルダーでフォームにコンポーネントを追加している。
- バインドするデータベース表を表すクラスを作成している。データをコンポーネントにバインドするためのエンティティークラスの作成手順は次のとおりです。
エンティティークラスの作成
JTable にバインドするデータベースを表すエンティティークラスを作成する
- 「プロジェクト」ウィンドウでプロジェクトを右クリックし、「新規」>「その他」を選択して「持続性」カテゴリを選択し、「データベース」テンプレートから「エンティティークラス」を選択します。
- ウィザードの「データベース表」ページで、データベース接続を選択します。
- 「使用可能な表」列に内容が表示されたら、アプリケーションで使用する表を選択し、「追加」をクリックして「選択した表」列に移動します。「次へ」をクリックします。
- ウィザードの「エンティティークラス」ページで、「持続フィールド用の NamedQuery 注釈を生成」ダイアログを選択します。
- 生成されたクラスの名前と場所をカスタマイズします。
- 「持続性ユニットの作成」をクリックします。
- 「持続性ユニットの作成」ダイアログで、次を確認します。
- 選択されている持続性ライブラリが「TopLink」であること。
- 選択されている表生成の方針が「なし」であること。
- 「完了」をクリックします。
「プロジェクト」ウィンドウにエンティティークラスのノードが表示されます。
データを表す Beans へのコンポーネントのバインド
データを JTable コンポーネントにバインドする
- GUI ビルダーでコンポーネントを右クリックし、「バインド」>「要素」を選択します。
- 「データをフォームにインポート」をクリックします。「データをフォームにインポート」ダイアログで、コンポーネントをバインドするデータベース表を選択します。「閉じる」をクリックします。
- 「ソースをバインド」コンボボックスで、エンティティークラスの結果リストを表す項目を選択します。たとえば、エンティティークラスの名前が Customer.java の場合、list オブジェクトは customerList として生成されます。
- 「式をバインド」の値は Null のままにしてください。
- JTable に表示するデータベース列がある場合は、「選択」リストでそれらの列を選択して「使用可能」リストに移動します。
- さらにバインドを設定するには、「詳細」タブを選択します。たとえば、バリデータやコンバータを指定したり、バインドソースが Null または読み取り不能な場合の動作を指定することができます。
- 「閉じる」をクリックします。
データを JList コンポーネントにバインドする
- GUI ビルダーでコンポーネントを右クリックし、「バインド」>「要素」を選択します。
- 「データをフォームにインポート」をクリックします。「データをフォームにインポート」ダイアログで、コンポーネントをバインドするデータベース表を選択します。「閉じる」をクリックします。
- 「ソースをバインド」コンボボックスで、エンティティークラスの結果リストを表す項目を選択します。たとえば、エンティティークラスの名前が Customer.java の場合、list オブジェクトは customerList として生成されます。
- 「式をバインド」の値は Null のままにしてください。
- 「式を表示」ドロップダウンリストで、リストに表示する値を含むデータベース列を表すプロパティーを選択します。
- さらにバインドを設定するには、「詳細」タブを選択します。
- 「閉じる」をクリックします。
JComboBox にデータをバインドすることもできます。ただし、Beans Binding 1.2.1 の時点では、JComboBox の display 値を得る方法を指定できる DetailBinding クラスがありません。このため、カスタムコードを記述する必要があります。1 つの方法として、次に示すようにカスタムのセルレンダリングを記述できます。
データを JComboBox コンポーネントにバインドする
- コンボボックスを選択します。
- 「プロパティー」ウィンドウの「プロパティー」タブで「renderer」プロパティーを選択します。
- 省略符号 (...) ボタンをクリックします。
- プロパティーエディタの上部にあるコンボボックスで「カスタムコード」を選択します。
- テキスト領域で、次のようなコードを入力します。ここで
jComboBox1 は JComboBox インスタンスの名前、MyEntityClass はエンティティークラス、getPropertyFromMyEntityClass() は、バインドするエンティティークラスのプロパティーの取得メソッドです。
jComboBox1.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof MyEntityClass) {
MyEntityClass mec = (MyEntityClass)value;
setText(mec.getPropertyFromMyEntityClass());
}
return this;
}
})
注: 「新規 Java デスクトップアプリケーション」ウィザードを使用すると、CRUD (作成、読み取り、更新、削除) 機能を持つ動作アプリケーション全体をすばやく作成できます。ただし、生成したクラスにエンティティー間の関係が正しくカバーされるように、すべてのエンティティークラスを前もって生成することをお勧めします。
特別なバインドプロパティー
Beans Binding ライブラリは一部の Swing コンポーネントに対し、必要に応じてコンポーネント自身に存在しない特別な合成プロパティーを提供します。これらのプロパティーは、表で選択されている行などの内容を表すもので、ほかのプロパティーにバインドするのに役立ちます。
Beans Binding ライブラリによって追加される合成プロパティーには、次のものがあります。
| コンポーネント |
プロパティ |
説明 |
| AbstractButton |
selected |
ボタンの選択状態。 |
| JComboBox |
selectedItem |
JComboBox の選択項目。 |
| JSlider |
value |
JSlider の値。すべての変更を通知します。 |
| value_IGNORE_ADJUSTING |
「value」と同じですが、スライダが値を調整している間は変更を通知しません。 |
| JList |
selectedElement |
JList で選択されている要素。すべての変更を通知します。ターゲットとして JList を持つ JListBinding が存在する場合は、選択されている要素はバインドのソースリストの要素として報告されます。そうでない場合は、選択されている要素は、リストのモデルのオブジェクトとして報告されます。何も選択されていない場合は、プロパティーは Null と評価されます。 |
| selectedElements |
JList で選択されている要素を含むリスト。すべての変更を通知します。ターゲットとして JList を持つ JListBinding が存在する場合は、選択されている要素はバインドのソースリストの要素として報告されます。そうでない場合は、選択されている要素は、リストのモデルのオブジェクトとして報告されます。何も選択されていない場合は、プロパティーは空のリストと評価されます。 |
| selectedElement_IGNORE_ADJUSTING |
「selectedElement」と同じですが、リストの選択内容が更新中の場合、変更は通知されません。 |
| selectedElements_IGNORE_ADJUSTING |
「selectedElements」と同じですが、リストの選択内容が更新中の場合、変更は通知されません。 |
| JTable |
selectedElement |
JTable で選択されている要素。すべての変更を通知します。ターゲットとして JTable を持つ JTableBinding が存在する場合は、選択されている要素はバインドのソースリストの要素として報告されます。そうでない場合、選択されている要素はマップとして報告されます。ここで、キーは文字列「column」と列のインデックスからなり、値はその列のモデル値となります。たとえば、{column0=column0value, column1=column1value, ...} などです。何も選択されていない場合は、プロパティーは Null と評価されます。 |
| selectedElements |
JTable で選択されている要素を含むリスト。すべての変更を通知します。ターゲットとして JTable を持つ JTableBinding が存在する場合は、選択されている要素はバインドのソースリストの要素として報告されます。そうでない場合、選択されている要素はマップとして報告されます。ここで、キーは文字列「column」と列のインデックスからなり、値はその列のモデル値となります。たとえば、{column0=column0value, column1=column1value, ...} などです。何も選択されていない場合は、プロパティーは空のリストと評価されます。
|
| selectedElement_IGNORE_ADJUSTING |
「selectedElement」と同じですが、表の選択内容が更新中の場合、変更は通知されません。 |
| selectedElements_IGNORE_ADJUSTING |
「selectedElements」と同じですが、表の選択内容が更新中の場合、変更は通知されません。 |
| JTextComponent (サブクラスの JTextField、JTextArea、および JEditorPane も含む) |
text |
JTextComponent のテキストプロパティー。すべての変更を通知します (入力中も含む)。 |
| text_ON_FOCUS_LOST |
JTextComponent のテキストプロパティー。コンポーネントのフォーカスが失われたときのみ変更を通知します。
|
| text_ON_ACTION_OR_FOCUS_LOST |
JTextComponent のテキストプロパティー。コンポーネントが actionPerformed を通知したとき、またはコンポーネントのフォーカスが失われたときのみ変更を通知します。
|
関連項目
IDE の GUI ビルダーの使用方法の概要については、NetBeans IDE における GUI 構築を参照してください。
「Java デスクトップアプリケーション」プロジェクトテンプレートを使用してマスター/詳細ビューを備えたデータベースアプリケーションを構築する方法については、Java デスクトップデータベースアプリケーションの構築を参照してください。
Beans Binding の詳細については、java.net にある Beans Binding プロジェクトのページを参照してください。
JavaBeans コンポーネントの概要については、Java Tutorial の Beans Trail を参照してください。
NetBeans IDE の GUI ビルダーを使用する際のヒントについては、GUI エディタの FAQ と Patrick Keegan のブログを参照してください。