Le plan de travail implémente une architecture de préférences génériques qui permet aux plug-ins de stocker les valeurs des préférences utilisateur et d'ajouter une page de préférences à la boîte de dialogue des préférences du plan de travail. Nous allons de nouveau utiliser l'exemple de l'outil readme pour voir comment cela se réalise, puis nous aborderons une partie du support sous-jacent pour la génération des pages de préférences.
Le point d'extension org.eclipse.ui.preferencePages vous permet d'ajouter des pages à la boîte de dialogue des préférences du plan de travail (Fenêtre->Préférences). La boîte de dialogue des préférences présente une liste hiérarchique des entrées des préférences utilisateur. Une fois sélectionnée, chaque entrée affiche une page de préférences correspondante.
L'outil readme utilise ce point d'extension pour ajouter la page de préférences 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>
Ces marques définissent une page de préférences, nommée "Readme Example" qui est implémentée par la classe ReadmePreferencePage. La classe doit implémenter l'interface IWorkbenchPreferencePage.
Le plan de travail utilise PreferenceManager pour maintenir une liste de tous les noeuds dans l'arborescence des préférences et leurs pages correspondantes. Cette liste peut être initialisée à partir des informations du registre de plug-in sans exécuter le code de plug-in. La contribution de votre plug-in à la boîte de dialogue des préférences (l'entrée "Readme Example" à gauche) s'affiche avant qu'une section de votre code ne soit exécutée.
Pourquoi la préférence "Readme Example" est-elle ajoutée au niveau supérieur de l'arborescence des préférences à gauche ? Car une contribution de la page des préférences va être ajoutée en tant que racine de l'arborescence à moins qu'un attribut category ne soit spécifié. (Le nom catégorie est un peu erroné. Il vaudrait sans doute mieux parler de chemin d'accès.) L'attribut category spécifie l'ID (ou une séquence d'ID à partir de la racine) de la page parent. Par exemple, les marques suivantes permettent de créer une seconde page de préférences de l'outil readme, "Readme Example Child Page" comme enfant de la page d'origine.
<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>
Lorsque l'utilisateur sélectionne l'entrée pour une page de préférences dans l'arborescence de gauche, le plan de travail crée et affiche une page de préférences à l'aide de la classe spécifiée dans la définition d'extension. Cette action correspond à l'activation du plug-in (s'il n'a pas déjà été activé par une autre opération utilisateur).
L'implémentation d'une page de préférences est similaire à la création d'une page pour un assistant. La page des préférences fournit une méthode createContents qui crée les contrôles SWT représentant le contenu de la page et ajoute des écouteurs pour tous les événements d'intérêt. La page est responsable de la création et du renvoi du composite qui sera le parent de tous les boutons de commande de la page. L'extrait suivant montre les mises en évidence :
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 majorité du code dans cette méthode concerne la création et la présentation des boutons de commande, aussi n'allons nous pas la voir en détails. Voici ce à quoi ressemble la page correspondante :
L'autre principale responsabilité d'une page de préférences est de réagir au message performOk. En règle générale, cette méthode met à jour et stocke les préférences utilisateur et si nécessaire, met à jour d'autres objets plug-in pour refléter le changement de préférences.
Les pages de préférences doivent substituer la méthode doGetPreferenceStore() pour renvoyer un magasin de préférences pour le stockage de leurs valeurs.
Les magasins de préférences sont de nature identique aux paramètres de boîte de dialogue. A la section Paramètres des boîtes de dialogue, nous avons vu comment la classe AbstractUIPlugin gère les paramètres de boîte de dialogue tout au long de la durée de vie d'un plug-in. La même stratégie est employée pour les préférences utilisateur. Votre plug-in peut ajouter des entrées à un magasin de préférences et mettre à jour les valeurs à mesure que l'utilisateur modifie les paramètres dans la page des préférences. La plateforme se charge de sauvegarder ces valeurs dans le répertoire de travail de votre plug-in et d'initialiser le magasin de préférences à partir des paramètres enregistrés.
Le code ci-dessous dans ReadmePreferencePage obtient le magasin de préférences pour ReadmePlugin.
protected IPreferenceStore doGetPreferenceStore() {
return ReadmePlugin.getDefault().getPreferenceStore();
}
Comme ReadmePlugin étend la classe AbstractUIPlugin, il hérite automatiquement d'un magasin de préférences. Ce dernier est initialisé à partir d'un fichier de préférences stocké dans le répertoire du plug-in. La seule chose restant à faire pour ReadmePlugin est d'implémenter une méthode qui initialise les valeurs par défaut des préférences. Ces valeurs sont utilisées la première fois que la page des préférences s'affiche ou lorsque l'utilisateur sélectionne le bouton Valeurs par défaut dans la page des préférences.
protected void initializeDefaultPreferences(IPreferenceStore store) {
// Ces paramètres s'affichent lorsque la boîte de dialogue
// des préférences s'ouvre pour la première fois.
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");
}
Remarque : Si aucune préférence n'est sauvegardée pour un plug-in, un magasin de préférences vide lui est octroyé.
Une fois le magasin de préférences de votre plug-in associé à votre page de préférences, vous pouvez implémenter la logique de récupération et d'enregistrement des préférences.
Les pages de préférences sont responsables de l'initialisation des valeurs de leurs commandes à l'aide des paramètres de préférences issus du magasin de préférences. Ce processus revient à initialiser les valeurs des boutons de commande de la boîte de dialogue dans les paramètres de boîte de dialogue. ReadmePreferencePage initialise la totalité de ses commandes dans une seule méthode, initializeValues, appelée à partir de sa méthode 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));
...
Lorsque le bouton OK (ou Validation) est sélectionné, les valeurs courantes des commandes de la page des préférences doivent être de nouveau enregistrées dans le magasin de préférences. ReadmePreferencePage implémente cette logique dans une méthode distincte 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());
...
}
Lorsque l'utilisateur sélectionne le bouton de commande Valeurs par défaut, la plateforme restaure toutes les valeurs du magasin de préférences aux valeurs spécifiées dans la classe du plug-in. Cependant, votre page de préférences doit faire refléter ces valeurs par défaut dans les commandes de la page de préférences. ReadmePreferencePage implémente ceci dans 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));
...
}
L'implémentation d'une page de préférences consiste principalement en du code SWT. Ce dernier est utilisé pour créer les commandes de la page de préférences, définir les valeurs des commandes et les récupérer. Le package org.eclipse.jface.preference fournit des classes auxiliaires, appelées éditeurs de zone qui créent les widgets et implémentent la définition des valeurs et le code de récupération pour les types de préférences les plus courants. La plateforme fournit des éditeurs de zone pour l'affichage et la mise à jour de nombreux types de valeurs : booléens, couleurs, chaînes, entiers, polices et noms de fichier.
FieldEditorPreferencePage implémente une page qui utilise ces éditeurs de zone pour afficher et stocker les valeurs de préférences de la page.
Au lieu de créer des commandes SWT pour remplir son contenu, FieldEditorPreferencePage crée des éditeurs de zone pour afficher le contenu.
public void createFieldEditors() {
// The first string is the preference key name
// The second string is the label shown next to the 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()));
...
A chaque éditeur de zone est affecté le nom de sa clé de préférence correspondante et le libellé du texte de la commande SWT est créé. Le type de commande créé dépend du type d'éditeur de zone. Par exemple, un éditeur de zone booléen crée une case à cocher.
Comme la page des préférences est associée à un magasin de préférences (spécifié dans la méthode doGetPreferenceStore), le code permettant de stocker les valeurs courantes, d'initialiser les valeurs des commandes à partir du magasin de préférences et de restaurer leurs valeurs par défaut peut être totalement implémenté dans FieldEditorPreferencePage.
FieldEditorPreferencePage utilise une grille avec une colonne comme présentation par défaut des widgets d'éditeur de zone. Pour des exigences de présentation particulière, vous pouvez remplacer la méthode createContents.