Oracle® Fusion Middleware Oracle Application Development Framework Swingアプリケーションの開発 12c (12.1.2) E48100-01 |
|
![]() 前 |
![]() 次 |
この章では、ADFビジネス・コンポーネントのデータ・オブジェクトにバインドされたSwingコンテナおよびコンポーネントを作成する方法について説明します。ここでは、ADF Swingのウィザードを使用してデータバインドされたコンテナを作成する最も簡単な方法について説明します。
この章の構成は、次のとおりです。
ADF Swingにおけるデータ・バインディングとは、バックエンド・ビジネス・サービスのデータにバインドするSwingコンテナおよびコンポーネントを作成する機能です。データ・バインディングを有効化するために、ADF Swingには、Oracle ADFモデル・レイヤーと連携する小さなAPIがあります。このAPIは、アプリケーション・ソース・コードでADF Swingブートストラップ・コードとの組合せにより公開されます。
loadCpx()
のコール: アプリケーション・メタデータ(DataBindings.cpx
ファイルで指定されている)をロードします。これにより、インスタンスに対するADFデータ・コントロールおよびADFバインディング・コンテキストを使用するビジネス・サービス実装インスタンス(例: ADFビジネス・コンポーネントのアプリケーション・モジュール・インスタンス)への接続が指定されます。
setBindingContext()
のコール: フレームまたはパネルからADFバインディング・コンテキストを使用できるようにします。
createPanelBinding()
のコール: Swingコンポーネント・モデルを介してビジネス・サービスに含まれているデータ・コレクションにアクセスするオブジェクトを作成します。
ADF Swingフォームまたはパネルの個々のコンポーネントに対してADFモデルを設定するためのパネル・バインディングに対するbindUIControl()
のコール。
Swingアプリケーションでのデータ・バインディングと連動させるために、各コンテナ(フレームまたはパネル)は、パネル・バインディング・オブジェクトを作成するか、その元のソースからそれを取得する必要があります。最初のパネル・バインディングを作成するフレームには、ADF Swingブートストラップ・コードも含まれており、そこで、ビジネス・サービスへの接続が作成されます。アプリケーションによって作成される後続のコンテナは、元のパネル・バインディングから連鎖しているか、関係のないデータを表示するためにそれら自体によってパネル・バインディングが作成されます。アプリケーションのデータ・ビューをどのようにパーティション化するのかによって、コンテナで新しいパネル・バインディングが設定されるのか、既存のものが取得されるのかが決まります。
ビジネス・サービス・ビューの独立したブランチを作成する場合、アプリケーションで新しいパネル・バインディングを設定するフレームを開く必要があります。
アプリケーションの連続したブランチに沿った同じビューを保持する場合(たとえば、マスターおよびディテール・ブランチ)、セカンダリ・コンテナはすべて、最初のフレームによって作成されたパネル・バインディング・オブジェクトを共有します。
データバインドされたコンテナを作成する最も簡単な方法は、ADF Swingウィザードを使用することです(「新規ギャラリ」の「ADF Swing」フォルダを参照してください)。特に、ADF Swingのこれらの2つのウィザードを使用すると、ソース・コードに、パネル・バインディングの作成に必要なブートストラップ・コードおよびコンストラクタが含まれるようになります。
「ADF Swingの空のフォームの作成」ダイアログを使用して、アプリケーションによって使用されるビジネス・サービス(たとえば、ADFビジネス・コンポーネント)への接続が含まれているADF Swingパネル・バインディングを作成する空のフレームを生成します。
「ADF Swingの空のパネルを作成」ダイアログを使用して、新しいパネル・バインディングを作成するか、その親フレームから1つを共有するコンストラクタが含まれている空のパネルを生成します。
これらの2つのウィザードを使用するもう1つの利点は、JDeveloper内でUIデザインを簡単にドラッグアンドドロップするためのサポートです。それらは、特定のデータ・コントロール・オブジェクト(これには、ビジネス・サービスのコレクション、構造化されたオブジェクト、属性およびメソッドが含まれます)のためのブートストラップ・コードで生成されているため、JDeveloperの「データ・コントロール」パネルから挿入するSwingコンポーネントがすべて、そのデータ・コントロール・オブジェクトに含まれているどのビジネス・サービスにもアクセスできるようになります。
ADF Swingデータ・バインディングを有効化する対象となる標準フレームまたはパネル(ADF Swingのウィザードを使用せずに生成されたもの)から開始する場合、適切なADF Swingブートストラップ・コードをメイン・フレームに追加し、次のようにセカンダリ・ウィンドウでのパネル・バインディングを処理できます。
親フレームとパネル・バインディングを共有する場合:
BusinessCompViewName(getPanelBinding()); frame.setVisible(true);
新しいフレームでそれ自体のパネル・バインディングを定義する場合:
BusinessCompViewName(new JUPanelBinding(getPanelBinding().getApplicationName(),null));frame.setVisible(true);
最初のものは、フレーム・オブジェクトを作成し、パネル・バインディングを設定します。2番目のコールは、フレームを可視にします。
ADF Swingを使用してデフォルトのマスター/ディテール・フォームを作成する場合、マスターとディテールの両方のパネルにナビゲーション・バーが作成されて配置され、それによって、ユーザーは各パネルのデータを個別にスクロールできます。または、現在フォーカスがあるパネルに反応する1つのナビゲーション・バーを作成できます。
ADF Swingフォームで、個別のパネルからレイアウト・パネル(ここでは、ナビゲーション・イベントがすべての子パネルに影響を与える)にナビゲーション・バーのコードを移動する必要があります。たとえば、部門および従業員のデータ・パネルからレイアウト・パネルにコードを移動できます。
移動する必要があるコードは、例4-1に似たものになります。
例4-1 ナビゲーション・バー・コード
// The declaration of the navigation bar private JUNavigationBar navBar = new JUNavigationBar(); // The code that binds the navigation bar to the individual panel. navBar.setModel(JUNavigationBar.getModelInstance(getPanelBinding(), "DepartmentsView", null, "DepartmentsViewIter")); //Add the navigation bar to the panel add(navBar, BorderLayout.NORTH);
ナビゲーション・バー・コードを移動したら、コントロール・バインディングを、マスターとディテールの両方のパネルが含まれるレイアウト・パネルに追加する必要があります。例4-2は、ナビゲーション・バーのモデルをバインドするためにレイアウト・パネルに追加するコードを示しています。
例4-2 パネルへのナビゲーション・バーのモデルのバインディング
//The declaration of the navigation bar private JUNavigationBar navBar = new JUNavigationBar(); //Bind the model for the navigation bar to the panel navBar.setModel(JUNavigationBar.getModelInstance(getPanelBinding(),navBar)); //Add the navigation bar to the panel add(navBar, BorderLayout.SOUTH); add(masterScroller, BorderLayout.NORTH); add(detailViewPanel, BorderLayout.CENTER);
ツリー・コントロールをパネルに追加する場合、ADF Swingノード・モデルのプロパティ・エディタを使用して、ノード移入ルールを作成します。プロパティ・エディタでは、ノードの選択を処理できません。パネル内のコントロールに移入するためにノード選択イベントを処理する場合、JUTreeDefaultMouseListener
を使用して、選択したノード上のマスター・パネルとディテール・パネルを同期できます。例4-3は、リスナーをツリー・コントロールに追加する方法を示しています。
ADF SwingFrame
またはJPanel
によって実装されるADF SwingPanel
インタフェースにより、ADF Swingアプリケーションで次のことを実行できます。
データバインドされたパネル間(データ・パネル間のチェーン化とも呼ばれる)で、一貫したデータ・コンテキストを保持する
データバインドされたSwingコントロールを介してデータにアクセスする
設計時、ADF Swingアプリケーションに追加する各データ参照パネルには、UIコントロールとビジネス・サービスの行セット・イテレータ間の相互作用をマーシャリングするためのコンテキストが、フレームまたはそれを含んでいるパネル(マスター/ディテール・レイアウト・パネルなど)に作成されたパネル・バインディング・オブジェクトから渡されます。ADF Swingにおけるデータ参照パネルをチェーニングする機能は、追加のコードを記述する必要がない状態で提供されています。たとえば、ウィザードによって生成されるデータ参照パネルPanelDeptView
およびPanelEmpView1
は、各JPanel
がADF SwingPanel
インタフェースのsetPanelBinding()
およびgetPanelBinding()
メソッドを実装している場合、パネル・バインディング(JUPanelBinding
)のインスタンスを介して同じデータ・コンテキストを共有します。
このパネル・バインディングを作成するフレームまたはパネルがある場合、ADF Swingによって、既存のパネル・バインディング・オブジェクトを共有するか、新しいものを作成する新しいデータ参照パネルを追加することで、アプリケーションを作成できます。
その後、JDeveloperの「データ・コントロール」パネルを使用して、データバインドされたコントロールを1つずつデータ・パネルに追加できます。Swingコンポーネントのレベルで、これにより、そのコントロールのdocument
またはmodel
プロパティにADF Swingコントロール・モデルが指定されることによって、データ・バインディングが設定されます。実行時に、データ・パネルの各コントロールは、そのコントロールのsetModel()
またはsetDocument()
メソツドの引数としてのパネル・バインディング・オブジェクトを介してデータバインドされます。
データバインドされたパネルによってパネル・バインディングがどのように作成され、使用されるのかを理解するために、アプリケーションを実行したときに何が行われるのかを、ADF Swingフレームから開始し、次のADF Swingコードが実行されたとして考えてみましょう。
main()
メソッドは、アプリケーションをブートストラップします。これにより、バインディング・コンテキストが開始され、ADFデータ・コントロールが、DataBindings.cpx
ファイルのエントリに基づいてロードされます。次に、初期化されたADFモデル・オブジェクトが含まれるバインディング・コンテキストが、パネル・バインディングに渡され、ADFデータ・バインディングが作成されます。
詳細は、第4.5項「ADF Swingブートストラップ・コードに関する必知事項」を参照してください。
フレームは、アプリケーション・オブジェクトを取るコンストラクタを介して初期化されます(前述の例では、FrameDeptViewEmpView1
)。フレームを初期化すると、複数のデータ・コントロールのデータにバインドされているコンポーネントが含まれている可能性があるADFモデル定義に基づいて、パネル・バインディング・オブジェクト(JUPanelBinding
)が生成されます。パネル・バインディングの作成は、Swingコンポーネントに対するデータ・バインディングおよびデータ・パネルのチェーニングを可能にするADF Swingの重要な機能です。
フレームまたはアプレット・クラスによって、レイアウト・パネル(前述の例では、MDPanelDeptViewEmpView1
)が初期化され、setBindingContext()
メソッドを使用して、新しいレイアウト・パネルにパネル・バインディングが設定されます。
詳細は、第2.3項「ADF Swingフォーム作成時の処理内容」を参照してください。
レイアウト・パネルのjbInit()
メソッドで、データ参照(子)パネルが作成されます。この場合、ADF Swingによって、子データ・パネル(前述の例では、PanelDeptView
およびPanelEmpView1
)をバインドするために共有バインディング・コンテキストが使用されます。
コントロールの指定されたADF Swingモデルを使用して、コントロールから属性へのデータ・バインディングが行われます。(このバインディング情報は、バインディング・コンテナXMLメタデータに格納されます。)
コントロール・バインディングによって、イベントが処理され、UIコントロールのデータが移入され、更新されます。
詳細は、第4.9項「実行時の処理: コントロール・バインディングの機能のしかた」を参照してください。
ナビゲータでフレーム・クラスを選択し、「実行」を選択すると、main()
メソッドによって、アプリケーションがブートストラップされます。これにより、バインディング・コンテキストが開始され、データ・コントロールが、DataBindings.cpx
ファイルのエントリに基づいてロードされます。次に、初期化されたデータ・コントロールが含まれるバインディング・コンテキストが、パネル・バインディングに渡され、ADFデータ・バインディングが作成されます。
例4-4は、HRスキーマからのEmployeesおよびDepartmentsの各表から選択された例を使用して、ADF Swingフォームの作成ウィザードによって作成されたブートストラップ・コードを示しています。
例4-4 フォームの作成ウィザードによって作成されたブートストラップ・コード
// bootstrap application JUMetaObjectManager.setBaseErrorHandler(new JUErrorHandlerDlg()); // Lookup the *.cpx file and create all data controls listed in this file. JUMetaObjectManager mgr = JUMetaObjectManager.getJUMom(); // Use the definition classes provided by ADF Swing. Change only if you do not want to use custom DefClasses. mgr.setJClientDefFactory(null); // Create a new binding context that extends java.util.Hashtable. BindingContext ctx = new BindingContext(); // Get user connection information if available. If not, display logon dialog. ctx.put(DataControlFactory.APP_PARAM_ENV_INFO, new JUEnvInfoProvider()); // Set locale to the default locale of the JVM. ctx.setLocaleContext(new DefLocaleContext(null)); // Load data binding container data binding file. HashMap map = new HashMap(4); map.put(DataControlFactory.APP_PARAMS_BINDING_CONTEXT, ctx); mgr.loadCpx("mypackage.DataBindings.cpx", map); // Get handle to the ADF Business Components application module. The code lines // below are added only when using the ADF Swing Form wizard. Declaratively creating // the frame, starting with an empty form wizard does not add the following lines. DCDataControl app = (DCDataControl)ctx.get("model_AppModuleDataControl"); app.setClientApp(DCDataControl.JCLIENT); // Despite the following line of code, attribute sets and fetches are normally // performed in one batch operation. This requires only one network round // trip. Attributes that aren't needed are not loaded to the client. The code // line below is added only when using the ADF Swing Form wizard. Declaratively creating // the frame, starting with an empty form wizard does not add the following lines. app.getApplicationModule().fetchAttributeProperties(new String[] {"DepartmentsView1", "EmployeesView3"}, new String[][] {{"DepartmentId", "DepartmentName" }, {"EmployeeId", "FirstName", "LastName" "DepartmentId" }}, null); // Initialize application root class. FormDepartmentsView1EmployeesView3 frame = new FormDepartmentsView1EmployeesView3(); // Set binding context to the frame. frame.setBindingContext(ctx); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize();
フレームは、デフォルトでは引数を想定していない、そのコンストラクタによって初期化されます。アプリケーションのバインディング・コンテキストは、フレームのsetBindingContext()
メソッドに渡されます。
フレームを初期化すると、複数のデータ・コントロールのデータにバインドされるコンポーネントが含まれている可能性があるOracle ADFモデル定義に基づいて、パネル・バインディング・オブジェクト(JUPanelBinding
)が生成されます。パネル・バインディングの作成は、Swingコンポーネントに対するデータ・バインディングおよびデータ・パネルのチェーニングを可能にするADF Swingの重要な機能です。
データ・パネルまたはフォームをレイアウトした後、フォーム内でAttributeProperties()
メソッドを定義することで、ADF Swingアプリケーションのパフォーマンスを向上させることができます。これにより、フォームはバッチ・モードで動作し、属性値をフェッチするようになります。詳細は、第10.4項「ADF SwingでのADFビジネス・コンポーネント属性のフェッチを制限する方法」を参照してください。
データバインドされたテキスト・フィールドを使用してオブジェクトの属性値(アドレス・オブジェクトによって定義されるものなど)を表示する場合、フィールドに属性値は表示されません(かわりに静的テキストが表示されます)。
オブジェクト属性にテキスト・フィールドをバインドすると、バインドされたオブジェクトのイテレータ・バインディングに対して問合せが強制的に再実行されることで、「ADF Swing」パネルに値を適切に表示できます。
オブジェクトのイテレータ・バインディングに対してexecuteQuery()
を強制するには、このメソッド・コールを、パネルでjbInit()
が実行された後に追加します。ここで、Streetは、オブジェクト属性バインディングの名前に置き換えられます。
panelBinding.findControlBinding("Street").getIteratorBinding().
executeQuery();
同じオブジェクトのすべての属性値を再フェッチするようにイテレータ・バインディングを強制するには、オブジェクト・ドメイン属性(Streetなど)の1つに対してexecuteQuery()
をコールすることのみが必要です。
ビジネス・サービスがデータ・コレクションに対する作成操作をサポートしている場合、ADF Swingパネルでこの操作を使用して、データバインドされた表またはツリー・コントロールに新規行を表示できます。作成および挿入アクション・バインディングにバインドされている「作成」ボタンをユーザーがクリックすると、新しい行が表示されます。この操作によって、1つのステップで行が作成および挿入されるため、この操作は、ユーザーによるコンポーネントのインプレース編集に理想的です。
注意: 「データ・コントロール」パネルには、この操作が「作成」として表示されますが、アクション・バインディング・エディタが |
作成操作を使用して行を挿入するADF Swingのバインドされたコントロールを作成する手順は次のとおりです。
データ・パネルをJavaビジュアル・エディタで開きます。
詳細は、第2.10項「空のADF Swingパネルの作成方法」を参照してください。
「データ・コントロール」パネルで、UIコンポーネントが表示する属性が含まれているコレクション・ノードを選択します。これは、コントロールによってその行が追加されるコレクションです。ドロップダウン・リストで、新しい行を表示する目的のUIコンポーネントを選択します。
注意: そのデータ・コレクションとして、ディテール・コレクション(別のコレクション・ノードの子としてデータ・コントロール階層に表示される)を選択することはできません。これにより、イテレータ・バインディングによるナビゲーションの実行が防止されます。 |
コレクションを、開いているADF Swingパネルにドラッグします。
詳細は、第3.3項「ADF SwingパネルへのUIコンポーネントの挿入方法」を参照してください。
ヒント: 必要に応じて、パネルに、ナビゲーション・ボタンを表示し、ユーザーがコレクションを参照できるようにすることができます。詳細は、第7.8項「JUNavigationBarコントロールの使用方法」を参照してください。 |
行を作成する操作を挿入するには、前に選択したコレクションの操作フォルダで「作成」を選択し、ドロップダウン・リストから「ボタン」を選択します。
ボタンを、開いているADF Swingパネルに挿入します。
注意: 「データ・コントロール」パネルから「作成」をドラッグすると、ボタンのアクション・バインディングが |
ADFイテレータ・バインディングを使用して、データバインドされたSwing表を作成する場合、表の列のデータを表示するソート基準(昇順または降順)を指定できます。1つ以上の列をソート基準として使用し、これらの列ごとにソートの優先度を指定できます。たとえば、従業員表をソートする場合、姓を第1ソート基準、名を第2ソート基準として選択できます。この例では、2人以上の従業員が同じ姓を持っているために、指定された順序で名前でソートする必要がある場合に、2番目のソート基準が役立ちます。
データバインド表の列をソートする場合、表に対するイテレータ・バインディングを使用します。
ADFイテレータ・バインディングにバインドされた表の列をソートする手順は次のとおりです。
Javaビジュアル・エディタで、ソートする表が含まれるフォームまたはパネルを右クリックし、「ページ定義に移動」を選択します。
ページ定義エディタの概要の「実行可能ファイル」リストでイテレータ・バインディングをダブルクリックします。
「イテレータ・バインディングの編集」ダイアログで、「ソート基準」タブをクリックします。
属性を選択し、ソートを昇順で実行するのか降順で実行するのかを選択します。
属性が表に対するソート基準でない場合は、「ソートなし」が選択されたままにします。
上矢印または下矢印ボタンを使用して、属性のソート優先度を変更します。
リスト内のソート基準属性を上に移動すると、ソート優先度が高くなります。これは、その属性が、リストの下方に表示されているソート基準属性より前にソートされることを意味します。
データ参照パネルが初期化された後、レイアウト・パネルによって、パネル・バインディングに対してexecuteIfNeeded()
がコールされ、ADFビジネス・コンポーネント・データ・ソースに対する問合せが実行されます。
executeIfNeeded()
メソッドによって、問合せがビュー・オブジェクトに対して実行されたかどうかが判別されます。されていない場合、このメソッドによって、それに対してexecuteQuery()
がコールされます。この実行された問合せによって、データベースのデータがキャッシュに送られ、ADFビジネス・コンポーネント行セット・リスナー・イベントが起動されます。これらのうちの最初のものがRowSetListener.rangeRefreshed
イベントです。このイベントは、イテレータ・バインディングによって取得されます(それよって、RowSetListener
が実装され、それ自体がリスナーとして登録されたため)。これにより、その範囲の行が取得され、コントロール・バインディングに対してupdateValuesFromRows()
がコールされます。コントロール・バインディングは、それらの行からデータを取り出し、Swing APIを使用してそれらをコントロールに割り当てます。その結果、Swing APIによって、パネルUIがそのデータで更新されます。