Migrazione dell'estensibilità dell'editor di test

Le modifiche nel package della struttura di base dell'editor di test delle prestazioni sono fornite in questa release per supportare modalità standard di gestione degli attributi degli elementi di modello.

Contenuto e layout dell'area Dettagli (supporto per il campo degli attributi)

È possibile adesso gestire il layout e il contenuto dell'area Dettagli nell'editor di test (editor di pianificazione e di test) che gli sviluppatori dovevano gestire nelle versioni precedenti. In questa versione, è possibile modificare il contenuto utilizzando l'astrazione denominata AttributeField. Questo costrutto nasconde buona parte del funzionamento agli sviluppatori e consente una maggiore estensibilità. Gli aggiornamenti a AttributeField possono coesistere con le interfacce utente degli editor esistenti o delle estensioni dei protocolli, sempre che vengano effettuate delle ottimizzazioni minime. Le classi derivate da AttributeField devono essere utilizzate ogni volta che viene visualizzato un attributo da un elemento di modello. Non utilizzare AttributeField per qualsiasi altra informazione riportata nell'area Dettagli. Utilizzare invece widget Eclipse regolari.

Funzionamento

Le classi getXXXvalue(), setXXXValue() egetFieldName() e le API forniscono un modo per collegare i dati del modello alla relativa rappresentazione dell'interfaccia utente e allo stesso tempo nascondono le operazioni di manutenzione di livello inferiore allo sviluppatore.

Tali classi sono astratte. Quando uno sviluppatore sceglie una di queste classi per visualizzare i dati del proprio modello, sarà necessario implementare soltanto un numero minimo di metodi per definire il funzionamento predefinito del campo di attributi. Se è necessario un'ulteriore personalizzazione, sono disponibili altri metodi. Per ulteriori informazioni, fare riferimento alla documentazione HTML Javadoc.

Il numero minimo di metodi che uno sviluppatore deve implementare è:
  • getXXXValue(): richiama e restituisce un valore dall'elemento di modello. XXX indica un tipo di attributo. Ad esempio, quando si estende IntegerAttributeField, il nome del metodo è getIntegerValue().
  • setXXXValue(): invia un valore ottenuto dall'interfaccia utente all'elemento di modello. Il significato di XXX è uguale a quello precedente.
  • getFieldName(): restituisce il nome del campo. I nomi rendono un campo indirizzabile per la navigazione.
    Nota: prima della versione 7.0, i nomi dei campi erano facoltativi, mentre in questa versione sono obbligatori.

Classi

Nella seguente tabella è riportata una gerarchia delle classi relative a AttributeField disponibili per gli sviluppatori di editor e protocolli. L'elenco include le descrizioni sulle classi da utilizzare in determinate situazioni.
Nota: tali classi hanno una funzionalità limitata in quanto devono supportare le classi e le API dalle versioni precedenti alla 7.0.
Classe AttributeField Descrizione
OptionsComboField Questa classe è utilizzata per visualizzare una serie di opzioni per un utente. Le opzioni sono presentate in una casella di combinazione. Quando si estende questa classe, è necessario fornire un indice dell'opzione selezionata nell'elemento di modello. Quando un utente sceglie un valore differente dalla casella di combinazione, il nuovo indice viene inviato alla classe derivata in modo da aggiornare il modello. Lo sviluppatore della classe deve comprendere il significato dell'indice nel contesto del modello.
OptionsRadioField La stessa opzione che si applica a OptionsComboField si applica anche a OptionsRadioField. Tuttavia, si applica la seguente eccezione: le opzioni sono visualizzate come una serie di pulsanti di opzione in un gruppo. Un utente deve selezionare uno dei pulsanti di opzione per indicare l'indice dell'opzione selezionata.
BooleanAttributeField Questa classe è utilizzata quando l'attributo dell'elemento del modello è un valore Booleano. Il valore è visualizzato come casella di spunta. Lo sviluppatore deve fornire un valore Booleano da un elemento del modello e accettare un nuovo valore Booleano dall'interfaccia utente per aggiornare l'elemento del modello.
IntegerAttributeField Questa classe è utilizzata quando l'attributo dell'elemento del modello contiene un valore intero. Il campo può rappresentare un valore intero in diversi modi. I seguenti tipi di controlli sono disponibili per la rappresentazione:
  • StyledText
  • Spinner
  • Slider
  • Scale
Nota: questa classe sarà soggetta a modifiche in futuro.
TextAttributeField Utilizzare questo campo quando sono presenti dati di testo nell'elemento del modello.
FilteredTextAttibuteField Questa classe estende il funzionamento di TextAttributeField abilitando il controllo delle condizioni e visualizzando un testo alternativo (messaggio) per l' utente. Ad esempio, lo sviluppatore potrebbe voler filtrare i dati binari o un testo troppo lungo per una corretta visualizzazione.
DataCorrelatingTextAttrField Utilizzare questa classe quando i dati di testo possono essere raggruppati in un pool di dati, correlati ad altri dati, utilizzati come riferimento o configurati in una combinazione di queste opzioni.

Portabilità del codice da layoutProvider

Di seguito è riportata una breve guida per la portabilità del codice esistente, di solito presente nella classe layoutProvider, a una nuova funzione.

Implementazione precedente:
class MyLayoutProvider extends ExtlayoutProvider
{
	layoutControls( CBActionElement element )
	{
			super.layoutControls( element ); // call super first.
			createWidgets(); // create all the UI for display
			refreshWidgets(); // call refreshLayout to populate UI
			return true; // return true is success.
	}

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

	refreshControls( CBActionElement element )
	{
			super.refreshControls( element ); // call super first
			// grab data from model element and apply it to UI widgets
			applyModelDataToWidgets();
			return true; // return true if success.
	}

	/* because the ExtLayoutProvider is SelectionListener, 
	this method is called when Buttons, ComboBoxes and 
	such are modified. */
	widgetSelected( SelectionEvent event )
	{
			// find the widget, get its value and apply it to model 
			applyUiDataToModelElement();
			// call super to update the editor.
			super.widgetSelected();
	}

	/* because the ExtLayoutProvider is ModifyListener, 
	this method is called when StyledText is modified. */
	modifyText( ModifyEvent event )
	{
			// find relevant StyledText control and apply 
			// its value to the model element.
			applyTextUiDataToModelElement();
			super.modifyText();
			}

}
Implementazione corrente:
class MyLayoutProvider extends ExtlayoutProvider
{
			// class declared as internal.
			class MyTextField extends TextFieldAttribute
			{
					String getTextValue(){
							return ((MyModelElement)getSelection()).getTextAttr();
					}
					setTextValue( String newVal ){
							((MyModelElement)getSelection()).setTextAttr( newVal );
					}
					String getFieldName(){
							return MY_FIELD_NAME; // defined elsewhere
					}
			};
	
			MyTextField m_fldText;
			MyDataCorrelationField m_DcField; // declared outside.

			layoutControls( CBActionElement element )
			{
					createWidgetsAndFields(); // create all the UI for display
					updateNonFieldWidgets(); // update non-model widgets 
					// always call super at the end.
					return super.layoutControls( element ); 
			}

			createWidgetsAndFields()
			{
					// create UI widgets for displaying non-model info
					…
					// create Fields
					m_fldText = new MyTextField( this );
					m_fldText.createLabel( … );
					m_fldText.createControl( …. );

					// create more UI widgets for displaying non-model info

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

			}

			refreshControls( CBActionElement element )
			{
					// update NON-UI widgets only.
					applyModelDataToWidgets();
					//always call super at the end.
					return super.refreshControls( element ); 
}

			/*You do not have to have this method unless you want 
			to update NON-model widgets/data. */
			widgetSelected( SelectionEvent event )
			{
					// find the widget and do whatever you need, but 
					// do not update the model. 
					applyUiDataTo_NON_ModelElement();
					// DO NOT call super to update the editor.
			}

			/* You do not need to have this method unless you 
			want to update non-model widgets/data. */
			modifyText( ModifyEvent event )
			{
					// find the widget and do whatever you need, but do not 
					// update the model. 
					applyTextUiDataToModelElement();
					// DO NOT call super to update the editor.

			}

}

Feedback