Preferenze

Il workbench implementa un'architettura di preferenze generica che consente ai plug-in di memorizzare i valori delle preferenze dell'utente e di fornire una pagina delle preferenze alla finestra di dialogo delle preferenze del workbench. Verrà di nuovo esaminato l'esempio readme tool per vedere come avviene questa operazione e, quindi, si analizzerà il supporto sottostante per la creazione di pagine delle preferenze.

org.eclipse.ui.preferencePages

Il punto di estensione org.eclipse.ui.preferencePages consente all'utente di fornire pagine alla finestra di dialogo delle preferenze del workbench (Finestra > Preferenze). La finestra di dialogo delle preferenze presenta un elenco gerarchico delle voci di preferenze dell'utente. Quando selezionata, ogni voce visualizza una corrispondente pagina di preferenze.

Il readme tool utilizza questo punto di estensione per aggiungere la pagina delle preferenze Readme Example.

<extension
    point = "org.eclipse.ui.preferencePages">
    <page 
        id="org.eclipse.ui.examples.readmetool.Page1"
        class="org.eclipse.ui.examples.readmetool.ReadmePreferencePage"
        name="Readme Example">
    </page>
</extension>

Questo codice definisce una pagina delle preferenze denominata "Readme Example" che viene implementata dalla classe ReadmePreferencePage. La classe deve implementare l'interfaccia IWorkbenchPreferencePage.

Il workbench utilizza un PreferenceManager per gestire un elenco di tutti i nodi della struttura delle preferenze e delle rispettive pagine corrispondenti. Questo elenco può essere inizializzato mediante informazioni presenti nel registro di plug-in, senza dover eseguire alcun codice del plug-in.  Il contributo del plug-in dell'utente alla finestra di dialogo delle preferenze (la voce "Readme Example" a sinistra) viene visualizzato prima dell'esecuzione di qualsiasi codice.

La preferenza "Readme Example" viene aggiunta al livello più alto della struttura delle preferenze situata a sinistra.  Perché? Perché un contributo di pagina delle preferenze verrà aggiunto come elemento principale della struttura, a meno che non venga specificato un attributo di categoria. (Il nome categoria è forse fuorviante. Un termine più adatto potrebbe essere percorso.) L'attributo categoria specifica l'id (o una sequenza di id dalla directory principale) della pagina principale. Ad esempio, il codice seguente creerà una seconda pagina delle preferenze di readme tool, "Readme Example Child Page,", come elemento secondario della pagina originale.

<extension
    point = "org.eclipse.ui.preferencePages">
    <page 
        id="org.eclipse.ui.examples.readmetool.Page1"
        class="org.eclipse.ui.examples.readmetool.ReadmePreferencePage"
        name="Readme Example">
    </page>    
    <page 
        id="org.eclipse.ui.examples.readmetool.Page2"
        class="org.eclipse.ui.examples.readmetool.ReadmePreferencePage2"
        name="Readme Example Child Page"
        category="org.eclipse.ui.examples.readmetool.Page1>
    </page>
</extension>

Quando l'utente seleziona la voce di una pagina delle preferenze nella struttura di sinistra, il workbench creerà e visualizzerà una pagina delle preferenze utilizzando la classe specificata nella definizione dell'estensione.  Questa azione è quella che determina l'attivazione del plug-in (se non era già stato attivato in seguito ad un'altra operazione dell'utente).

Pagina delle preferenze

Definizione della pagina

L'implementazione di una pagina delle preferenze è simile alla creazione di una pagina per una procedura guidata. La pagina delle preferenze fornisce un metodo createContents che crea i controlli SWT che rappresentano il contenuto della pagina e aggiunge listener per tutti gli eventi di interesse. La pagina è responsabile della creazione e della restituzione del composto da cui derivano tutti i controlli presenti nella pagina.  Il seguente frammento di codice mostra questi punti fondamentali:

protected Control createContents(Composite parent)
{
    ...
    //composite_textField << parent
    Composite composite_textField = createComposite(parent, 2);
    Label label_textField = createLabel(composite_textField, "Text Field"); 
    textField = createTextField(composite_textField);
    pushButton_textField = createPushButton(composite_textField, "Change");

    //composite_tab << parent
    Composite composite_tab = createComposite(parent, 2);
    Label label1 = createLabel(composite_tab, "Radio Button Options");

    tabForward(composite_tab);
    //radio button composite << tab composite
    Composite composite_radioButton = createComposite(composite_tab, 1);
    radioButton1 = createRadioButton(composite_radioButton, "Radio button 1");
    radioButton2 = createRadioButton(composite_radioButton, "Radio button 2");
    radioButton3 = createRadioButton(composite_radioButton, "Radio button 3");
    ...
    initializeValues();
    ...
    return new Composite(parent, SWT.NULL);
}

La maggior parte del codice in questo metodo riguarda la creazione e la disposizione dei controlli, quindi non verrà trattato in dettaglio.  Ecco come appare la pagina corrispondente:

L'altra responsabilità principale di una pagina delle preferenze è di "reagire" al messaggio di performOk. Generalmente, questo metodo aggiorna e memorizza le preferenze dell'utente e, se necessario, aggiorna qualsiasi altro oggetto del plug-in per riflettere la modifica nelle preferenze.

Le pagine delle preferenze dovrebbero ricoprire il metodo doGetPreferenceStore() per restituire una memorizzazione di preferenze in cui memorizzare i rispettivi valori.

Memorizzazione di preferenze dei plug-in

Le memorizzazioni di preferenze sono simili alle impostazioni delle finestre di dialogo. In Impostazioni delle finestre di dialogo, è stato descritto come la classe AbstractUIPlugin conserva le impostazioni della finestra di dialogo durante tutto il ciclo di vita di un plug-in. La stessa strategia viene impiegata per le preferenze dell'utente. Il plug-in dell'utente può aggiungere voci ad una memorizzazione di preferenze ed aggiornare i valori man mano che l'utente modifica le impostazioni nella pagina delle preferenze. La piattaforma si occuperà del salvataggio di tali valori nella directory di lavoro del plug-in e dell'inizializzazione della memorizzazione di preferenze in base alle impostazioni salvate.

Il seguente codice in ReadmePreferencePage ottiene la memorizzazione di preferenze per ReadmePlugin.

protected IPreferenceStore doGetPreferenceStore() {

 return ReadmePlugin.getDefault().getPreferenceStore();

}

Poiché ReadmePlugin estende la classe AbstractUIPlugin, eredita automaticamente una memorizzazione di preferenze. Tale memorizzazione di preferenze viene inizializzata da un file delle preferenze memorizzato nella directory del plug-in.  ReadmePlugin deve solo implementare un metodo che inizializzi le preferenze sui valori predefiniti. Questi valori vengono utilizzati alla prima apertura della pagina delle preferenze oppure quando l'utente preme il pulsante Impostazioni predefinite della pagina delle preferenze.

protected void initializeDefaultPreferences(IPreferenceStore store) {

 // Queste impostazioni verranno visualizzate quando la finestra Preferenze

 // viene aperta per la prima volta.

 store.setDefault(IReadmeConstants.PRE_CHECK1, true);

 store.setDefault(IReadmeConstants.PRE_CHECK2, true);

 store.setDefault(IReadmeConstants.PRE_CHECK3, false);

 store.setDefault(IReadmeConstants.PRE_RADIO_CHOICE, 2);

 store.setDefault(IReadmeConstants.PRE_TEXT, "Default text");

}

Nota:  se non esistono preferenze salvate per un plug-in, quest'ultimo riceverà una memorizzazione di preferenze vuota.

Richiamo e salvataggio delle preferenze

Una volta associata la memorizzazione di preferenze del plug-in alla pagina delle preferenze, è possibile implementare la logica per il richiamo e il salvataggio delle preferenze.

Le pagine delle preferenze sono responsabili dell'inizializzazione dei valori dei rispettivi controlli mediante le impostazioni presenti nella memorizzazione di preferenze. Questo processo è simile all'inizializzazione dei valori di controllo delle finestre di dialogo presenti nelle impostazioni delle finestre di dialogo. ReadmePreferencePage inizializza tutti i propri controlli in un singolo metodo, initializeValues, richiamato dal rispettivo metodo createContents.

private void initializeValues() {

 IPreferenceStore store = getPreferenceStore();

 checkBox1.setSelection(store.getBoolean(IReadmeConstants.PRE_CHECK1));

 checkBox2.setSelection(store.getBoolean(IReadmeConstants.PRE_CHECK2));

 checkBox3.setSelection(store.getBoolean(IReadmeConstants.PRE_CHECK3));
 ...

Quando viene premuto il pulsante OK (o Applica), i valori correnti dei controlli, presenti sulla pagina delle preferenze, dovrebbero essere inseriti nella memorizzazione di preferenze. ReadmePreferencePage implementa questa logica in un metodo separato, storeValues.

private void storeValues() {

 IPreferenceStore store = getPreferenceStore();

 store.setValue(IReadmeConstants.PRE_CHECK1, checkBox1.getSelection());

 store.setValue(IReadmeConstants.PRE_CHECK2, checkBox2.getSelection());

 store.setValue(IReadmeConstants.PRE_CHECK3, checkBox3.getSelection());

 ...

}

Quando l'utente preme il pulsante Impostazioni predefinite, la piattaforma ripristinerà i valori della memorizzazione di preferenze sui valori predefiniti specificati nella classe di plug-in. Tuttavia, la pagina delle preferenze dell'utente ha la responsabilità di riportare questi valori predefiniti nei controlli sulla pagina delle preferenze. ReadmePreferencePage effettua questa implementazione in initializeDefaults.

private void initializeDefaults() {

 IPreferenceStore store = getPreferenceStore();

 checkBox1.setSelection(store.getDefaultBoolean(IReadmeConstants.PRE_CHECK1));

 checkBox2.setSelection(store.getDefaultBoolean(IReadmeConstants.PRE_CHECK2));

 checkBox3.setSelection(store.getDefaultBoolean(IReadmeConstants.PRE_CHECK3));

 ...

}

Editor di campo

L'implementazione di una pagina delle preferenze è principalmente compito del codice SWT.  Il codice SWT viene utilizzato per creare i controlli della pagina delle preferenze, per impostare i valori dei controlli e per richiamare tali valori. Il pacchetto org.eclipse.jface.preference fornisce classi helper, denominate editor di campo, che creano i widget ed implementano l'impostazione dei valori e il richiamo del codice per i tipi di preferenze più comuni. La piattaforma fornisce editor di campo per la visualizzazione e l'aggiornamento di vari tipi di valori, incluso booleani, colori, stringhe, numeri interi, tipi di carattere e nomi file.

FieldEditorPreferencePage implementa una pagina che utilizza questi editor di campo per visualizzare e memorizzare i valori di preferenze sulla pagina.

Anziché creare controlli SWT per il riempimento del proprio contenuto, FieldEditorPreferencePage crea editor di campo per visualizzare i contenuti.

public void createFieldEditors() {

    // La prima stringa è il nome della chiave di preferenza
    // La seconda stringa è l'etichetta che appare accanto al widget 
    addField(new BooleanFieldEditor(USE_OLD_MODE, "Use old mode",
        getFieldEditorParent()));

    addField(new StringFieldEditor(APPLICATION_NAME, "Application Name",
        getFieldEditorParent()));

    addField(new ColorFieldEditor(COLOR, "Text Color", getFieldEditorParent()));
    ...

Ad ogni editor di campo viene assegnato il nome della corrispondente chiave di preferenze e l'etichetta di testo per il controllo SWT che l'editor provvederà a creare. Il tipo di controllo dipende dal tipo di editor di campo. Ad esempio, un editor di campo booleani crea una casella di controllo.

Dato che la pagina delle preferenze è associata ad una memorizzazione di preferenze (specificata nel metodo doGetPreferenceStore), il codice per la memorizzazione dei valori correnti, per l'inizializzazione dei valori di controllo dalla memorizzazione di preferenze e per il ripristino dei controlli ai valori predefiniti può essere interamente implementato in FieldEditorPreferencePage.

FieldEditorPreferencePage utilizzerà un layout di griglia con una colonna come layout predefinito per i widget di editor di campo.  Per layout con requisiti speciali, è possibile ricoprire il metodo createContents.