テスト・エディター拡張性のマイグレーション

モデル・エレメント属性の処理方法として、より標準化された方法をサポートするため、Performance Test エディターの基本フレームワーク・パッケージでの変更点がこのリリースで提供されています。

「詳細」エリアの内容およびレイアウト (属性フィールドのサポート)

テスト・エディターの「詳細」エリア (スケジュールおよびテスト・エディター) のレイアウトおよび内容は、以前のバージョンでは開発者が管理する必要がありましたが、ユーザーが管理できるようになりました。 このバージョンでは、AttributeField という抽象クラスを使用することにより、内容を操作できます。 この構成体では、必要な動作の大半が開発者に対して非表示になっており、拡張性の大幅な向上が実現されています。AttributeField に更新した場合でも、小規模の調整をいくつか行うことを前提とすると、既存のエディターやプロトコル拡張機能のユーザー・インターフェースとの共存が可能です。モデル・エレメントからの属性を表示する場合には、そのたびに AttributeField から派生したクラスを使用する必要があります。 「詳細」エリアでユーザーに提供されるその他の情報に対しては、AttributeField は使用しないでください。代わりに、標準の Eclipse ウィジェットを使用してください。

動作

getXXXvalue()、setXXXValue()、getFieldName() の各クラスおよび API には、モデル・データをそのユーザー・インターフェース表示とリンクし、同時に、関連した低レベル保守作業を開発者に対して非表示にする方法が用意されています。

これらのクラスは、抽象クラスです。 開発者がいずれかのクラスを選択してそのモデル・データを表示する場合、属性フィールドのデフォルトの動作を定義するために実装が必要なメソッドは少数で済みます。よりカスタマイズした動作が必要な場合は、オーバーライドのために他のメソッドが用意されています。 詳細については、Javadoc HTML 資料を参照してください。

開発者が実装する必要があるメソッド一式の最小構成は、以下のとおりです。
  • getXXXValue(): モデル・エレメントから値を検索して返します。 XXX は、属性のタイプを表します。例えば、IntegerAttributeField を拡張する場合、このメソッドの名前は getIntegerValue() になります。
  • setXXXValue(): UI から取得した値をモデル・エレメントに送ります。 XXX の意味は、前述の内容と同じです。
  • getFieldName(): フィールドの名前を返します。 名前があると、ナビゲーションのためのアドレス参照がフィールドで可能になります。
    注: 7.0 より前のバージョンでは、フィールド名はオプションでしたが、このバージョンでは必須になっています。

クラス

以下の表は、編集者およびプロトコル開発者が利用できる AttributeField 関連クラスの階層です。 このリストでは、具体的な状況でどのクラスを使用するかを説明しています。
注: 以下のクラスは 7.0 より前のバージョンのクラスや API をサポートする必要があるため、機能が制限されています。
AttributeField クラス 説明
OptionsComboField このクラスは、オプション一式をユーザーに表示するときに使用します。オプションは、組み合わせボックスに表示されます。 このクラスを拡張する場合は、現在モデル・エレメントで選択されているオプションの索引を指定する必要があります。 ユーザーが組み合わせボックスから別の値を選択すると、モデルを更新するために、新しい索引が派生クラスに渡されます。 クラス開発者は、モデルのコンテキストでの索引の意味を理解することが必要です。
OptionsRadioField OptionsComboField の場合と同じ対処が OptionsRadioField に対しても適用されます。 ただし、以下の例外が存在します。オプションは、一連のラジオ・ボタンとして、まとめて表示されます。 ユーザーは、選択したオプションの索引を示すために、いずれかのラジオ・ボタンを選択する必要があります。
BooleanAttributeField このクラスは、モデル・エレメント属性がブール値である場合に使用します。 この値は、チェック・ボックスとして表示されます。 開発者は、モデル・エレメントのブール値を指定し、ユーザー・インターフェースの新しいブール値を確定して、モデル・エレメントを更新する必要があります。
IntegerAttributeField このクラスは、モデル・エレメント属性に整数値が保持されている場合に使用します。 このフィールドでは、整数値をいくつかの方式で表記できます。 表記には以下のコントロール・タイプを使用できます。
  • StyledText
  • Spinner
  • Slider
  • Scale
注: このクラスは、将来変更される場合があります。
TextAttributeField モデル・エレメントにテキスト・データがある場合は、このフィールドを使用します。
FilteredTextAttibuteField このクラスは、条件検査を使用可能にして、代替テキスト (メッセージ) をユーザーに表示することにより、TextAttributeField の動作を拡張します。 例えば、開発者がバイナリー・データをフィルター操作したり、長すぎるテキストをフィルターに掛けて表示を見やすくする場合などが考えられます。
DataCorrelatingTextAttrField テキスト・データのデータプール処理、データ相関処理、参照としての使用、あるいはこれらの処理の任意の組み合わせによる構成を行う場合は、このクラスを使用します。

layoutProvider からのコードの移植

以下に、既存のコードを新しい関数に移植する方法を簡単に説明します。layoutProvider クラスの場合が一般的です。

以前の実装
class MyLayoutProvider extends ExtlayoutProvider
{
	layoutControls( CBActionElement element )
	{
			super.layoutControls( element ); // 最初に super を呼び出す。
			createWidgets(); // 表示するすべての UI を作成する。
			refreshWidgets(); // refreshLayout を呼び出して UI にデータを取り込む。
			return true; // true が戻れば正常。
	}

	createWidgets()
	{
			new StyledText();
			new Button();
	}

	refreshControls( CBActionElement element )
	{
			super.refreshControls( element ); // 最初に super を呼び出す。
			// モデル・エレメントからデータを取り込み、それを UI ウィジェットに適用する。
			applyModelDataToWidgets();
			return true; // 正常な場合は true が戻る。
	}

	/* ExtLayoutProvider は SelectionListener であるため、
	このメソッドは、ボタンやコンボ・ボックスなどを変更すると
	呼び出される。 */
	widgetSelected( SelectionEvent event )
	{
			// ウィジェットを検索してその値を取得し、モデルに適用する。
			applyUiDataToModelElement();
			// super を呼び出してエディターを更新する。
			super.widgetSelected();
	}

	/* ExtLayoutProvider は ModifyListener であるため、
	このメソッドは、StyledText を変更すると呼び出される。 */
	modifyText( ModifyEvent event )
	{
			// 関連の StyledText コントロールを検索して、
			// その値をモデル・エレメントに適用する。
			applyTextUiDataToModelElement();
			super.modifyText();
			}

}
Current®現在の実装:
class MyLayoutProvider extends ExtlayoutProvider
{
			// 内部クラスと宣言されたクラス。
			class MyTextField extends TextFieldAttribute
			{
					String getTextValue(){
							return ((MyModelElement)getSelection()).getTextAttr();
					}
					setTextValue( String newVal ){
							((MyModelElement)getSelection()).setTextAttr( newVal );
					}
					String getFieldName(){
							return MY_FIELD_NAME; // 他の行で定義済み
					}
			};
	
			MyTextField m_fldText;
			MyDataCorrelationField m_DcField; // 外部で宣言済み。

			layoutControls( CBActionElement element )
			{
					createWidgetsAndFields(); // 表示するすべての UI を作成する。
					updateNonFieldWidgets(); // モデル以外のウィジェットを更新
					// 必ず super を最後に呼び出す。
					return super.layoutControls( element ); 
			}

			createWidgetsAndFields()
			{
					// モデル以外の情報を表示するために UI ウィジェットを作成する
					…
					// フィールドを作成する
					m_fldText = new MyTextField( this );
					m_fldText.createLabel( … );
					m_fldText.createControl( …. );

					// モデル以外の情報を表示するために UI ウィジェットをさらに作成する

					m_DcField = new MyDataCorrelationField( this );
					m_DcField.createLabel( … );
					m_DcField.createControl( …. );

			}

			refreshControls( CBActionElement element )
			{
					// UI 以外のウィジェットのみを更新する。
					applyModelDataToWidgets();
					// 必ず super を最後に呼び出す。
					return super.refreshControls( element ); 
}

			/* モデル以外のウィジェット/データを更新しない限り、
			このメソッドは必要ない。 */
			widgetSelected( SelectionEvent event )
			{
					// ウィジェットを検索して必要な操作を行うが、
					// モデルは更新できない。
					applyUiDataTo_NON_ModelElement();
					// エディターを更新する場合、super は呼び出さない。
			}

			/* モデル以外のウィジェット/データを更新しない限り、
			このメソッドは必要ない。 */
			modifyText( ModifyEvent event )
			{
					// ウィジェットを検索して必要な操作を行うが、
					// モデルは更新できない。
					applyTextUiDataToModelElement();
					// エディターを更新する場合、super は呼び出さない。

			}

}

フィードバック