Java アプリケーションでの Beans とデータのバインド
このチュートリアルでは、NetBeans IDE でサポートされている Java アプリケーションでの Beans Binding 機能とデータのバインド機能の概要を示します。
目次
このチュートリアルを完了するには、次のソフトウェアとリソースが必要です。
概要: NetBeans IDE での Beans Binding
Beans Binding ライブラリがリリースされるまで、UI コンポーネントをデータベースに接続したり、コンポーネントのプロパティーの値の同期を保ったりするのは面倒でした。たとえば、標準データベースのデータを JTable に表示するには、データベースと JTable の接続を処理するユーティリティークラスを手作業で作成する必要がありました。また、異なる Bean のプロパティーの値 (たとえば JTextField の値とビジュアル Bean のレンダリング) の同期を保つには、リスナーやイベントハンドラを手作業でコーディングする必要がありました。
Beans Binding ライブラリによって、このすべての処理が簡単になり、また標準化されます。どのコンポーネントのどのプロパティーを同期する必要があるのかを指定する数行のコードを記述するだけで、残りの処理は Beans Binding ライブラリによって実行されます。NetBeans IDE では、Beans Binding 機能は GUI ビルダーに統合されているので、アプリケーションの視覚的なデザインが完成したらすぐに動作をコーディングできます。
このチュートリアルでは、IDE での Beans Binding の主な機能について説明します。
プロパティー間のバインド
Beans Binding は、基本的にイベントリスナーやイベントハンドラをコーディングせずに Bean のプロパティーを接続する方法です。
Beans Binding の概念と IDE に用意されている機能を示すために、ユーザーがスライダを調整してテキストフィールド内の数値を変更できる簡単な例を使用します。
例を設定する
- IDE で、「ファイル」>「新規プロジェクト」を選択します。
- 「Java」カテゴリを選択し、「Java Application」テンプレートを選択します。「次へ」をクリックします。
- ウィザードの「名前と場所」ページで、次の操作を行います。
- プロジェクト名に「NumberSlider」と入力します。
- 「ライブラリの格納用に専用フォルダを使用」チェックボックスは選択されていない状態のままにします。NetBeans IDE 6.0 にはこのオプションはありません。
- 「主プロジェクトとして設定」チェックボックスがすでに選択されていることを確認します。
- 「主クラスを作成」チェックボックスを選択解除します。

- 「完了」をクリックしてウィザードを終了し、プロジェクトを設定します。
- 「プロジェクト」ウィンドウで「NumberSlider」プロジェクトノードを右クリックし、「新規」>「JFrame フォーム」を選択します。
「JFrame フォーム」が「新規」メニューにない場合は、「その他」を選択します。次に「新規ファイル」ウィザードで「Swing GUI フォーム」カテゴリを選択してから「JFrame フォーム」テンプレートを選択します。
- ウィザードの「名前と場所」ページで、次の操作を行います。
- クラス名に「NumberSliderFrame」と入力します。
- パッケージ名に「numberslider」と入力します。

- 「完了」をクリックしてウィザードを終了し、フォームを作成します。
NumberSliderForm.java が編集領域にデザインモードで開きます。
- パレットの「Swing コントロール」セクションからスライダコンポーネントをデザイン領域までドラッグします。「パレット」ウィンドウが開いていない場合は、「ウィンドウ」>「パレット」を選択します。
- パレットから、テキストフィールドコンポーネントをデザイン領域までドラッグします。
フォームは次のスクリーンショットのようになります。この例では、配置は重要ではありません。

ソースとターゲット
例を設定したので、バインドを作成します。ただし、その前にバインドのソースにするコンポーネントとターゲットにするコンポーネントを決定する必要があります。バインドのソースコンポーネントは、プロパティー値のバインド元です。
GUI エディタでバインドを行う場合は、ターゲットでバインドを開始してから、「バインド」ダイアログでソースを宣言します。
この例では、JSlider にデフォルトの値の範囲があるので、このコンポーネントをソースとして使用します。
注: バインドを 2 方向 (読み取り/書き込み) にして、ターゲットの変更内容がソースに自動的に反映されるようにできます。ただし、最初のバインドの方向は常にソースからターゲットになります。詳細は、バインドの詳細設定の更新モードに関する説明を参照してください。
スライダをテキストフィールドにバインドする
- テキストフィールドコンポーネントを右クリックし、「バインド」>「テキスト」を選択して「バインド」ダイアログを開きます。
- 「ソースをバインド」コンボボックスで「jSlider1」を選択します。
- 次のスクリーンショットに示すように、「式をバインド」コンボボックスで「value int」を選択します。

- 「了解」をクリックします。
これで、スライダの「value」Bean プロパティーがテキストフィールドの「text」の値にバインドされました。
デザイン領域で、テキストフィールドに値 50 が表示されます。この値は、スライダが中央の位置にあり、スライダのデフォルトの値の範囲が 0 ~ 100 であることを反映しています。
これでアプリケーションを実行し、バインドが機能するところを確認できます。
「実行」>「ファイルを実行」を選択してファイルを実行します。
アプリケーションが別のウィンドウで起動します。実行中のアプリケーションでスライダを調整し、テキストフィールド内の値が変わることを確認します。

カスタム Beans のバインド
前の節では、パレットからフォームに追加した 2 つの標準の Swing コンポーネントのプロパティーをバインドしました。ほかの Beans のプロパティーもバインドできます。ただし、これを行うには、いくつかの手順を実行して Bean のバインドコードを生成する IDE の機能を使用可能にする必要があります。次の方法のいずれかを行い、Bean 用に IDE のバインド機能を使用可能にできます。
- Bean をパレットに追加し、標準の Swing コンポーネントと同じようにフォームに追加できるようにします。
- Bean クラスをプロジェクトに追加し、Bean をコンパイルします。
「パレット」ウィンドウに Bean を追加する
- Bean がコンパイルされていることを確認します。
- 「ツール」>「パレット」>「Swing/AWT コンポーネント」を順に選択します。
- 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 として追加されたコンバータが含まれています。また、省略符号ボタン (...) をクリックし、「コンバータプロパティーの使用方法を選択」ドロップダウンリストから「カスタムコード」を選択して、変換コードを直接追加することもできます。
次の変換では、コンバータを用意する必要はありません。
- BigDecimal から String へ、String から BigDecimal へ
- BigInteger から String へ、String から BigInteger へ
- Boolean から String へ、String から Boolean へ
- Byte から String へ、String から Byte へ
- Char から String へ、String から Char へ
- Double から String へ、String から Double へ
- Float から String へ、String から Float へ
- Int から String へ、String から Int へ
- Long から String へ、String から BigDecimal へ
- Short から String へ、String から Short へ
- Int から Boolean へ、Boolean から Int へ
- バリデータ。変更をソースプロパティーに反映させる前に、ターゲットプロパティー値の変更内容の妥当性検査を行うためのコードを指定できます。たとえば、整数のプロパティー値が特定の範囲内になるようにバリデータを使用できます。
バリデータは、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」リンクをクリックし、これらのクラスのドキュメントにアクセスします。
コンポーネントへのデータのバインド
ビジュアル Swing コンポーネントとその他のカスタム Beans のプロパティーを同期するほか、ビジュアルコンポーネントを使用してデータベースと対話するために Beans Binding を使用できます。新しい Java フォームを作成し、コンポーネントをフォームに追加したら、それらのコンポーネントをデータにバインドするためのコードを生成できます。この節では、Swing JTable、JList、および JComboBox の各コンポーネントにデータをバインドする方法を示します。
コンポーネントをデータベース内のデータにバインドする前に、次の作業が行われている必要があります。
- IDE でデータベースに接続している。
- バインドするデータベース表を表すクラスを作成している。データをコンポーネントにバインドするためのエンティティークラスの作成手順は次のとおりです。
エンティティークラスの作成
JTable にバインドするデータベースを表すエンティティークラスを作成する
- 「プロジェクト」ウィンドウでプロジェクトを右クリックし、「新規」>「その他」を選択して「持続性」カテゴリを選択し、「データベース」テンプレートから「エンティティークラス」を選択します。
- ウィザードの「データベース表」ページで、データベース接続を選択します。
- 「使用可能な表」列に内容が表示されたら、アプリケーションで使用する表を選択し、「追加」をクリックして「選択した表」列に移動します。「次へ」をクリックします。

- ウィザードの「エンティティークラス」ページで、「持続フィールド用の NamedQuery 注釈を生成」および「持続性ユニットを作成」チェックボックスが選択されていることを確認します。

- 生成されたクラスの名前と場所をカスタマイズします。
- 「完了」をクリックします。
「プロジェクト」ウィンドウにエンティティークラスのノードが表示されます。
データを表す Beans へのコンポーネントのバインド
この節では、JTable、JList、および JComboBox の各コンポーネントにデータをバインドする方法を示します。
フォームにデータベース表を追加し、JTable を自動的に生成してデータベース表の内容を表示する
- 「サービス」ウィンドウを開きます。
- フォームに追加する表を含むデータベースに接続します。データベース接続のノードを右クリックし、「接続」を選択することでデータベースに接続できます。
- 接続のノードを展開し、「表」ノードを展開します。
- 表のノードをフォームにドラッグし、Ctrl キーを押しながら表にドロップします。
JTable が作成され、その列はデータベース表の列にバインドされます。
データベース表を既存の JTable コンポーネントにバインドする
- GUI ビルダーでコンポーネントを右クリックし、「バインド」>「要素」を選択します。

- 「データをフォームにインポート」をクリックします。「データをフォームにインポート」ダイアログで、コンポーネントをバインドするデータベース表を選択します。「閉じる」をクリックします。
- 「ソースをバインド」コンボボックスで、エンティティークラスの結果リストを表す項目を選択します。たとえば、エンティティークラスの名前が Customer.java の場合、list オブジェクトは customerList として生成されます。

- 「式をバインド」の値は Null のままにしてください。
- JTable に表示しないデータベース列がある場合は、「選択」リストでそれらの列を選択して「使用可能」リストに移動します。
- さらにバインドを設定するには、「詳細」タブを選択します。たとえば、バリデータやコンバータを指定したり、バインドソースが Null または読み取り不能な場合の動作を指定することができます。
- 「閉じる」をクリックします。
データを JList コンポーネントにバインドする
- GUI ビルダーでコンポーネントを右クリックし、「バインド」>「要素」を選択します。
- 「データをフォームにインポート」をクリックします。「データをフォームにインポート」ダイアログで、コンポーネントをバインドするデータベース表を選択します。「閉じる」をクリックします。
- 「ソースをバインド」コンボボックスで、エンティティークラスの結果リストを表す項目を選択します。たとえば、エンティティークラスの名前が Customer.java の場合、list オブジェクトは customerList として生成されます。

- 「式をバインド」の値は Null のままにしてください。
- 「式を表示」ドロップダウンリストで、リストに表示する値を含むデータベース列を表すプロパティーを選択します。
- さらにバインドを設定するには、「詳細」タブを選択します。
- 「閉じる」をクリックします。
データを JComboBox コンポーネントにバインドする
- コンボボックスを右クリックし、「バインド」>「elements」を選択します。
- 「データをフォームにインポート」をクリックします。「データをフォームにインポート」ダイアログで、コンポーネントをバインドするデータベース表を選択します。「閉じる」をクリックします。
- 「ソースをバインド」コンボボックスで、エンティティークラスの結果リストを表す項目を選択します。たとえば、エンティティークラスの名前が Customer.java の場合、list オブジェクトは customerList として生成されます。

- 「式をバインド」の値を「Null」のままにして、「了解」をクリックします。
- コンボボックスをもう一度右クリックし、「バインド」>「selectedItem」を選択します。
- ユーザーの選択によって影響の出るプロパティーにバインドします。

- 「了解」をクリックして編集を保存します。
JComboBox の display 値を取得する方法を指定できる DetailBinding クラスは、version 1.2.1 時点では Beans Binding ライブラリにありません。このため、カスタムコードを記述する必要があります。1 つの方法として、次に示すようにカスタムのセルレンダリングを記述できます。
コンボボックスのプロパティーを描画する
- コンボボックスを選択します。
- 「プロパティー」ウィンドウの「プロパティー」タブで「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;
}
})

注: 独自のソースファイルでのカスタムレンダラを作成、ファイルをコンパイル、レンダラをフォームにドラッグ、およびこの Bean を使用するようにコンボボックスのレンダラプロパティーを設定できます。
特別なバインドプロパティー
Beans Binding ライブラリは一部の Swing コンポーネントに対し、必要に応じてコンポーネント自身に存在しない特別な合成プロパティーを提供します。これらのプロパティーは、表で選択されている行などの内容を表すもので、ほかのプロパティーにバインドするのに役立ちます。
Beans のバインドライブラリによって追加される合成プロパティーには、次のものがあります。
| コンポーネント |
プロパティ |
説明 |
| 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 での Beans Binding の使用方法の詳細については、JPA と Beans Binding のベストプラクティスを参照してください。
IDE の GUI ビルダーの一般的な使用方法については、GUI 構築入門を参照してください。
Beans Binding の詳細については、java.net にある Beans Binding プロジェクトのページを参照してください。
JavaBeans コンポーネントの概要については、Java Tutorial の Beans Trail を参照してください。
NetBeans IDE の GUI ビルダーを使用する際のヒントについては、GUI エディタの FAQ を参照してください。