$30 off During Our Annual Pro Sale. View Details »

Eclipse : composants de additionnels avec JFace

Eclipse : composants de additionnels avec JFace

Ce support de cours s'intéresse à présenter les composants additionnels JFace suivants : les boîtes de dialogue, les Wizards, les Preferences et la gestion des ressources.

Mickael BARON

January 26, 2013
Tweet

More Decks by Mickael BARON

Other Decks in Programming

Transcript

  1. Développement de clients
    riches : Plateforme Eclipse
    Mickaël BARON - 2008 (Rév. Janvier 2009)
    mailto:[email protected] ou mailto:[email protected]
    mickael-baron.fr
    mickaelbaron
    Composants additionnels avec JFace
    Chapitre 2 : Boîtes à outils

    View Slide

  2. 2
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    Creative Commons
    Contrat Paternité
    Partage des Conditions Initiales à l'Identique
    2.0 France
    http://creativecommons.org/licenses/by-sa/2.0/fr
    Licence

    View Slide

  3. 3
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    3
    À propos de l’auteur …
    † Mickaël BARON
    † Ingénieur de Recherche au LIAS
    † https://www.lias-lab.fr
    † Equipe : Ingénierie des Données et des Modèles
    † Responsable des plateformes logicielles, « coach » technique
    † Ancien responsable Java de Developpez.com (2011-2021)
    † Communauté Francophone dédiée au développement informatique
    † https://java.developpez.com
    † 4 millions de visiteurs uniques et 12 millions de pages vues par mois
    † 750 00 membres, 2000 forums et jusqu'à 5000 messages par jour
    mickael-baron.fr
    mickaelbaron

    View Slide

  4. 4
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    Organisation du cours sur JFace : composants
    additionnels
    † Dialog : gérer les messages utilisateur
    † Wizard : création d’assistants
    † Preference : création de pages de préférences
    † Resource : gestion des ressources
    † Nous décrirons lors de la partie « plugin » qu’un Wizard ou
    une boîte de préférence peut être conçu par extension
    Tous les exemples du cours
    sont disponibles directement à l’adresse
    mickael-baron.fr/eclipse/intro-jface2

    View Slide

  5. 5
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue
    † Dans le cours SWT, nous avons présenté les boîtes de dialo-
    gue qui couvrent la majorité des besoins des IHM
    † Toutefois, JFace fournit une abstraction permettant
    † Afficher des messages de validation
    † Valider des entrées
    † Faciliter la spécialisation selon les besoins de la plateforme
    † Dans cette partie nous étudions les points suivants
    † Présentation des principales boîtes de dialogue et différences avec
    celles de SWT
    † Personnalisation de boîtes de dialogue
    † Nous verrons dans les prochaines parties du cours que l’API
    boîtes de dialogue de JFace est chapeau aux Wizards et aux
    boîtes de préférences

    View Slide

  6. 6
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue
    † Les API de boîtes de dialogue sont fournies dans le package
    org.eclipse.jface.dialogs
    † Toutes les boîtes de dialogue dérivent directement ou
    indirectement de la classe Dialog
    † Nous présentons principalement trois types de dialogue
    † IconAndMessageDialog : boîtes de dialogues qui affichent une icône
    et un texte comme principaux composants accompagnés de boutons
    de contrôle
    † InputDialog : boîtes de dialogues pour la saisie d’une chaîne de
    caractères accompagnées de boutons de contrôle
    † TitleAreaDialog : boîtes de dialogues décomposées en zones. Une
    zone de contenus (un titre), une zone de dialogue, une zone de
    progression et une zone de contrôle

    View Slide

  7. 7
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue
    † Hiérarchie des principales classes de dialogue
    Dialog
    InputDialog
    IconAndMessageDialog TrayDialog
    PreferenceDialog
    TitleAreaDialog
    WizardDialog
    ErrorDialog MessageDialog
    ProgressMonitorDialog
    Classes étudiées
    Classes génériques
    Etudiées dans les
    parties Preference et
    Wizard

    View Slide

  8. 8
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue
    † Boîtes de dialogue de type IconAndMessageDialog
    † ErrorDialog
    † MessageDialog
    † ProgressMonitorDialog
    Une IconAndMessageDialog
    se caractérise par un
    message d’information …
    et une icône

    View Slide

  9. 9
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : MessageDialog
    † Les boîtes de dialogue de type MessageDialog sont utilisées
    pour afficher un message suivant une sévérité donnée
    † MessageDialog hérite de IconAndMessageDialog
    † L’icône affiché est fonction de la sévérité (MessageDialog)
    † ERROR
    † INFORMATION
    † NONE
    † QUESTION
    † WARNING
    † La classe MessageDialog fournit une méthode statique pour
    chaque sévérité (factory de MessageDialog)
    † boolean openConfirm(Shell parent, String title, String message) :
    ouvre une boîte de confirmation (OK/Cancel)
    † autant qu’il y a de sévérité (sauf NONE)

    View Slide

  10. 10
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : MessageDialog
    † Exemple : afficher différents types de MessageDialog
    public class MessageDialogExample {
    public static void confirmDialog(Shell pShell) {
    boolean confirmationStatus = MessageDialog.openConfirm(pShell, "JFace Message
    Dialog : Confirmation", "[Placer ici votre message] ...");
    System.out.println("Valeur retournée : " + confirmationStatus);
    }
    public static void errorDialog(Shell pShell) {
    MessageDialog.openError(pShell, "JFace Message Dialog : Error", "[Placer ici votre
    message] Attention une erreur est survenue.");
    }
    public static void informationDialog(Shell pShell) {
    MessageDialog.openInformation(pShell, "JFace Message Dialog : Information",
    "[Placer ici votre message] Message à caractère informatif.");
    }
    public static void questionDialog(Shell pShell) {
    boolean questionStatus = MessageDialog.openQuestion(pShell, "JFace Message Dialog
    : Question", "[Placer ici votre message] Etes-vous sur de vouloir faire cela.");
    System.out.println("Valeur retournée : " + questionStatus);
    }
    public static void warningDialog(Shell pShell) {
    MessageDialog.openWarning(pShell, "JFace Message Dialog : Warning", "[Placer ici
    votre message] Attention, il s'est passé quelque chose d’étrange ...");
    }
    } MessageDialogExample.java
    du projet DialogExamples

    View Slide

  11. 11
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : MessageDialog
    † Exemple (suite) : afficher différents types de MessageDialog
    Confirmation
    Error
    Information
    Question
    Warning

    View Slide

  12. 12
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ErrorDialog
    † Les boîtes de dialogue de type ErrorDialog sont utilisées
    pour gérer une ou plusieurs erreur(s)
    † ErrorDialog hérite de IconAndMessageDialog
    † A la différence de la boîte MessageDialog (sévérité ERROR),
    une ErrorDialog contient un objet IStatus qui décrit le status
    des erreurs
    † La classe ErrorDialog fournit une méthode statique pour
    construire une boîte de dialogue erreur
    † static int openError(Shell parent, String dialogTitle, String message,
    IStatus status)

    View Slide

  13. 13
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ErrorDialog
    † Un objet IStatus est défini par les attributs suivants
    † id du plugin : id du plugin associé au status (voir chapitre suivant)
    † une sévérité (CANCEL, ERROR, INFO, OK, MESSAGE)
    † code : code donné par le plugin
    † un message : un message qui accompagne le status
    † une exception : une exception liée au problème (peut être null)
    † La classe Status est une implémentation par défaut
    † Status(int severity, String pluginId, int code, String message,
    Throwable exception)
    † La classe MultiStatus est une sous classe de Status permet-
    tant de gérer plusieurs status
    † MultiStatus(String plugId, int code, IStatus[] status, String message,
    Throwable exception)

    View Slide

  14. 14
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ErrorDialog
    † Exemple : afficher des boîtes ErrorDialog
    public class ErrorDialogExample {
    public static void errorDialog(Shell pShell, int severity) {
    String statusMessage = "[Placer ici le status de l'erreur]\n\n";
    switch (severity) {
    case IStatus.ERROR:
    statusMessage += "Status Error Message";
    break;
    case IStatus.INFO:
    statusMessage += "Status Info Message";
    break;
    case IStatus.WARNING:
    statusMessage += "Status Warning Message";
    break;
    default:
    statusMessage += "Status Error Message";
    break;
    }
    IStatus errorStatus = new Status(severity, "My Plug-In ID", 0, statusMessage, null);
    ErrorDialog.openError(pShell, "JFace Error Dialog", "[Placer ici le message
    d'erreur] \n\n Un problème est survenu au niveau ...", errorStatus);
    }
    }
    ErrorDialogExample.java du
    projet DialogExamples

    View Slide

  15. 15
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ErrorDialog
    † Exemple : afficher des boîtes ErrorDialog
    Status : Info
    Status : Warning
    Status : Error

    View Slide

  16. 16
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ProgressMonitorDialog
    † Les boîtes de dialogue de type ProgressMonitorDialog
    permettent d’afficher l’état progressif d’une opération de
    longue durée
    † ProgressMonitorDialog(Shell parent) : construction d’une dialogue
    † ProgressMonitorDialog hérite de IconAndMessageDialog
    † L’usage typique est de passer par la méthode run
    † run(boolean fork, boolean canceable, IRunnableWithProgress
    runnable) throws InvocationTargetException, InterruptedException
    † boolean fork : l’opération dans un thread séparé ou pas
    † boolean canceable : pour activer l’annulation
    † IRunnableWithProgress runnable : l’opération à démarrer
    † InvocationTargetException : si problème lors de l’opération
    † InterruptedException : si action annulation

    View Slide

  17. 17
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ProgressMonitorDialog
    † Un objet de type IRunnableWithProgress permet de décrire
    une opération de longue durée
    † Une classe de type IRunnableWithProgress doit implémenter
    † run(IProgressMonitor monitor) : traitement de l’opération dont le
    rapport en cours de traitement est envoyé à monitor
    † Un IProgressMonitor renseigne l’état d’avancement d’une
    opération (concepts de tâches et sous-tâches)
    † beginTask(String name, int tw) : notifie que l’opération a débuté
    name message à afficher, tw nombre d’unités à réaliser (UNKNOWN
    si pas déterminable)
    † worked(int work) : nombre d’unités déjà réalisée
    † subTask(String name) : notifie qu’une sous tâche a débuté
    † done() : notifie que l’opération est terminée (tâche complétée ou
    l’utilisateur a affectué une annulation)
    † boolean isCanceled() : savoir si l’utilisateur a annulé l’opération

    View Slide

  18. 18
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ProgressMonitorDialog
    † Exemple : afficher des boîtes ProgressMonitorDialog
    public class ProgressMonitorDialogExample {
    public static void progressMonitorDialog(Shell pShell, boolean indeterminate) {
    try {
    new ProgressMonitorDialog(pShell).run(true, true,
    new WorkLessOperation(indeterminate));
    } catch (InvocationTargetException e) {
    MessageDialog.openError(pShell, "Erreur", e.getMessage());
    } catch (InterruptedException e) {
    MessageDialog.openInformation(pShell, "Annulée", e.getMessage());
    }
    }
    }
    ProgressMonitorDialogExample.java
    du projet DialogExamples

    View Slide

  19. 19
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : ProgressMonitorDialog
    † Exemple (suite) : afficher des boîtes ProgressMonitorDialog
    public class WorkLessOperation implements IRunnableWithProgress {
    private static final int TOTAL_TIME = 10000;
    private static final int INCREMENT = 500;
    private boolean indeterminate;
    public WorkLessOperation(boolean indeterminate) {
    this.indeterminate = indeterminate;
    }
    public void run(IProgressMonitor monitor) throws InvocationTargetException,
    InterruptedException {
    monitor.beginTask("Operation \"WorkLess\" en cours", indeterminate ?
    IProgressMonitor.UNKNOWN : TOTAL_TIME);
    for (int total = 0; total < TOTAL_TIME && !monitor.isCanceled(); total += INCREMENT){
    Thread.sleep(INCREMENT);
    monitor.worked(INCREMENT);
    if (total == TOTAL_TIME / 2)
    monitor.subTask("La moitiée de l'opération \"WorkLess\" est réelisée");
    }
    monitor.done();
    if (monitor.isCanceled())
    throw new InterruptedException("Opération \"WorkLess\" annulée");
    }
    }
    WorkLessOperation.java du projet
    DialogExamples
    Démarrage de
    l’opération
    Evolution de
    l’opération
    Opération terminée

    View Slide

  20. 20
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue
    † Boîtes de dialogue de type InputDialog
    Une InputDialog se
    caractérise par un message
    d’information …
    une zone de saisie
    de texte
    Et une zone de
    messages pour la
    validation des données
    Une zone de boutons de contrôle
    généralement cancel et ok pour
    valider ou pas la saisie

    View Slide

  21. 21
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : InputDialog
    † Les boîtes InputDialog permettent la saisie d’un texte
    † InputDialog hérite directement de la classe Dialog
    † Possibilité d’effectuer une validation sur la saisie effectuée
    au travers d’un objet IInputValidator
    † InputDialog(Shell pshell, String dialogTitle, String dialogMessage,
    String initialValue, IInputValidator validator) : constructeur
    † String getValue() : accesseur sur la valeur saisie dans le dialogue
    † L’interface IInputValidator fournit une méthode de validation
    † String isValid(String newText) : doit retourner un message d’erreur si
    la validation échoue, sinon retourne null

    View Slide

  22. 22
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : InputDialog
    † Exemple : afficher des boîtes InputDialog
    public class InputDialogExample {
    public static void validationIntegerInputDialog(Shell pShell) {
    InputDialog myInputDialog = new InputDialog(pShell, "JFace Input Dialog",
    "[Placer Message pour la saisie] Saisir votre texte",
    "Ma Valeur", new IntegerInputValidator());
    if (myInputDialog.open() == Window.OK) {
    System.out.println("Vous avez sélectionné la validation en saisissant : "
    + myInputDialog.getValue());
    } else {
    System.out.println("Vous avez sélectionné l'annulation.");
    }
    }
    ...
    }
    InputDialogExample.java du projet
    DialogExamples

    View Slide

  23. 23
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : InputDialog
    † Exemple (suite) : afficher des boîtes InputDialog
    public class IntegerInputValidator implements IInputValidator {
    public String isValid(String newText) {
    try {
    int value = new Integer(newText).intValue();
    if (value < 0)
    return "Doit être positif";
    if (value > 1000)
    return "Ne doit pas être supérieur à 1000";
    } catch (NumberFormatException e) {
    return "Ne correspond pas à un entier";
    }
    return null;
    }
    }
    public class StringInputValidator implements IInputValidator {
    public String isValid(String newText) {
    int length = newText.length();
    if (length < 4)
    return "Chaîne trop courte (doit être supérieure à 4)";
    if (length > 10)
    return "Chaîne trop longue (doit être inférieure à 10)";
    return null;
    }
    }
    StringInputValidator.java du projet
    DialogExamples
    IntegerInputValidator.java
    du projet DialogExamples

    View Slide

  24. 24
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue
    Zone de contenu
    Zone de dialogue
    Zone de progression
    (optionnelle)
    Zone de contrôle
    † Boîtes de dialogue de type TitleAreaDialog
    † SaveAsDialog
    † WizarDialog
    † …

    View Slide

  25. 25
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : custom TitleAreaDialog
    † Nous avons étudié pour l’instant les dialogues prédéfinis par
    la bibliothèque JFace
    † Intéressons-nous à montrer comment fournir une boîte de
    dialogue personnalisée basée sur une TitleAreaDialog
    † Quelques méthodes à redéfinir …
    † Control createContents(Composite parent) : construit la partie
    contenu (partie haute)
    † Control createDialogArea(Composite parent) : construit la partie
    dialogue (partie médiane)
    † void createButtonsForButtonBar(Composite parent) : ajoute des
    boutons à la zone de boutons (partie basse)
    Nous reviendrons sur les aspects liés à
    TitleAreaDialog au moment des Wizards

    View Slide

  26. 26
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : custom TitleAreaDialog
    † Exemple : afficher une TitleAreaDialog personnalisée
    public class CustomTitleAreaDialog extends TitleAreaDialog {
    private String title;
    private String message;
    private String dialogMessage;
    public CustomTitleAreaDialog(Shell parentShell, String pTitle, String pMessage,
    String pDialogMessage) {
    super(parentShell);
    this.title = pTitle;
    this.message = pMessage;
    this.dialogMessage = pDialogMessage;
    this.setShellStyle(this.getShellStyle() | SWT.RESIZE);
    }
    protected void createButtonsForButtonBar(Composite parent) {
    this.createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
    true);
    }
    ...
    }
    CustomTitleAreaDialog.java du projet
    DialogExamples

    View Slide

  27. 27
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace / Boîtes de dialogue : custom TitleAreaDialog
    † Exemple (suite) : afficher une TitleAreaDialog personnalisée
    public class CustomTitleAreaDialog extends TitleAreaDialog {
    ... // Suite
    protected Control createContents(Composite parent) {
    Control contents = super.createContents(parent);
    this.setTitle(title);
    this.setMessage(message);
    this.getShell().setText(title);
    return contents;
    }
    protected Control createDialogArea(Composite parent) {
    Composite composite = (Composite)super.createDialogArea(parent);
    Composite inComposite = new Composite(composite, SWT.NONE);
    inComposite.setLayout(new GridLayout(1, false));
    GridData gd = new GridData();
    gd.horizontalIndent = 5;
    gd.verticalIndent = 5;
    inComposite.setLayoutData(gd);
    Label label = new Label(inComposite, SWT.NONE);
    label.setText(dialogMessage);
    Button button = new Button(inComposite, SWT.FLAT);
    button.setText("Ceci est un Bouton");
    return composite;
    }
    }
    CustomTitleAreaDialog.java du projet
    DialogExamples
    Création de la
    partie dialogue

    View Slide

  28. 28
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard
    † Un Wizard est un assistant qui permet de guider l’utilisateur
    à réaliser une tâche structurée
    † Un Wizard se présente sous la forme d’une IHM avec
    plusieurs traces opérationnelles possibles
    † En sortie de l’assistant un post-traitement est réalisé
    † Génération de code à partir d’un squelette prédéfini
    † Configuration d’une installation
    † Cette partie est guidée par un exemple file rouge « Assistant
    de réservation d’un transport pour les vacances »
    † L’exemple est inspiré de celui proposé par l’article suivant
    † Tutorial Wizard : www.eclipse.org/articles/Article-JFace
    Wizards/wizardArticle.html
    Le projet Akrogen permet de décrire les Wizards en
    XML/XUL et génère automatiquement le Wizard Eclipse
    akrogen.sourceforge.net

    View Slide

  29. 29
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : exemple « fil rouge »
    Le bouton « Next » est
    disponible à la condition
    que certaines informations
    soient saisies et valides
    Le bouton « Cancel »
    permet de sortir à tout
    moment de l’assistant
    Le bouton « Finish »
    permet de réaliser le
    post traitement
    selon les
    informations saisies
    Contrainte 1 : la
    date de départ doit
    être inférieure à la
    date de retour
    Contrainte 2 :
    le lieu de
    départ doit être
    différent du lieu
    d’arrivée
    Une page définie un squelette
    d’IHM (une zone de contenu, une
    zone de dialogue et des boutons
    de contrôle
    Selon le choix
    du transport
    la page
    suivante est
    différente

    View Slide

  30. 30
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : exemple « fil rouge »
    Une page qui gère
    un transport par
    voiture
    Une page qui gère
    un transport par
    avion
    Le bouton « Finish » est
    maintenant disponible.
    Le traitement relatif à la
    page sera alors réalisé

    View Slide

  31. 31
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : caractéristiques
    † Page
    † Squelette d’IHM : boutons prédéfinis, conteneur disponible pour
    personnaliser l’interface et champs paramétrables (description et titre)
    † Contraintes de validation : indiquent si certains boutons de contrôles
    doivent être activés ou pas (finish, next, …)
    † Règles de navigation : condition qui permet de savoir quelle page sera
    affichée lors de l’action « next » ou « back »
    † Wizard
    † Conteneur des pages : toutes les pages sont stockées dans le Wizard
    † Gestion du modèle : création de l’instance du modèle
    † Traitement terminal : retourne l’état du bouton « finish » (selon l’état
    du modèle) et effectue le traitement associé

    View Slide

  32. 32
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : schéma de fonctionnement
    Wizard
    IWizard
    Page 1
    IWizardPage
    Page 2
    IWizardPage
    Page n
    IWizardPage
    WizardModel
    - propriété 1
    - propriété 2
    - …
    + getPropriété1()
    + setPropriété1()
    + getPropriété2()
    + setPropriété2()
    + ...
    WizardMain
    WizardDialog
    1..n
    1
    1
    2
    4
    1
    1
    1
    3
    2
    3
    4
    1
    2
    3
    4
    Cancel
    Next
    Previous
    Finish
    Le modèle du Wizard,
    instancié par Wizard
    Le Wizard qui
    gère les pages et
    les traitements
    terminaux
    Les pages qui
    gèrent les
    différentes
    IHMs du Wizard
    Les différents
    états de
    l’automate
    Une classe conteneur qui
    permet de manipuler un Wizard
    dans une boite de dialogue

    View Slide

  33. 33
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : IWizard/Wizard
    † L’interface IWizard définit le contrôleur de l’assistant en
    gérant les différentes pages
    † Affiche en premier plan, selon le contexte, la page via l’utilisation d’un
    CardLayout
    † Décide quand l’assistant peut être terminé et comment il doit le faire
    † La classe Wizard fournit une implémentation par défaut en
    ajoutant des méthodes spécifiques
    † De nombreuses méthodes …
    † void addPage(IWizardPage) : ajoute une page à l’assistant
    † void addPages() : endroit où sont ajoutées toutes les pages
    † boolean canFinish() : utilisée pour indiquer l’état du bouton « finish »
    † abstract boolean performFinish() : implémentation du traitement final
    † Et pleins d’autres méthodes …
    Utilisez de
    préférence la
    classe Wizard

    View Slide

  34. 34
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : IWizard/Wizard
    † Exemple : contrôleur du Wizard
    public class HolidayWizard extends Wizard {
    ...
    public void addPages() {
    holidayPage = new HolidayMainPage();
    addPage(holidayPage);
    planePage = new PlanePage("");
    addPage(planePage);
    carPage = new CarPage("");
    addPage(carPage);
    }
    public boolean canFinish() {
    if (this.getContainer().getCurrentPage() == holidayPage)
    return false;
    if (model.usePlane)
    return planeCompleted;
    return carCompleted;
    }
    public boolean performFinish() {
    String summary = model.toString();
    System.out.println(summary);
    return true;
    }
    ...
    }
    Ne peut terminer l’assistant
    sur la première page
    Selon le type de transport,
    retourne l’état de terminaison
    Le traitement terminal est
    simpliste, il consiste à afficher un
    résumé des données du modèle
    sur la console
    HolidayWizard.java du projet
    WizardExamples

    View Slide

  35. 35
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : modèle du Wizard
    † L’objectif du modèle est de persister les différentes données
    saisies dans les pages de l’assistant
    † Il n’existe pas d’API pour le modèle puisque les données de
    l’assistant sont fonctionnelles
    † Les données sont utilisées lors du traitement final et doivent
    donc être accessibles
    † Plusieurs approches sont à envisager pour la mise en place
    d’un modèle dans un Wizard
    † Chaque page abrite les données qui lui sont propres
    † Un modèle transverse contenant les données utiles pour le traitement

    View Slide

  36. 36
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : modèle du Wizard
    † Exemple : modèle du Wizard
    public class HolidayModel {
    protected String departureDate;
    protected String returnDate;
    protected String destination;
    protected String departure;
    protected boolean usePlane;
    protected boolean resetFlights;
    protected String selectedFlights;
    float price;
    protected String seatChoice;
    protected String rentalCompany;
    protected String carPrice;
    protected boolean buyInsurance;
    boolean discounted = false;
    public String toString() {
    // Construction de la chaîne suivant les données saisies ...
    }
    }
    public class HolidayWizard extends Wizard {
    ...
    HolidayModel model;
    public HolidayWizard() {
    model = new HolidayModel();
    }
    public boolean performFinish() {
    String summary = model.toString();
    System.out.println(summary);
    return true;
    }
    ...
    }
    HolidayModel.java du projet
    WizardExamples
    HolidayWizard.java du projet
    WizardExamples
    Liste des attributs utilisés
    par l’assistant

    View Slide

  37. 37
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : IWizardPage
    † Un objet IWizardPage fournit une description concernant une
    page d’un assistant
    † La classe WizardPage fournit une implémentation par défaut
    et des méthodes spécifiques
    † De nombreuses méthodes …
    † boolean canFlipToNextPage() : page suivante est-elle affichable ?
    † IWizardPage getNextPage() : référence sur la page suivante
    † IWizardPage getPreviousPage() : référence sur la page précédente
    † boolean isPageComplete() : page finalisée ou pas ?
    † void setPageComplete(boolean v) : modifie l’état de finalisation
    † IWizard getWizard() : référence de l’assistant (important pour accéder
    à la référence du modèle)

    View Slide

  38. 38
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : IWizardPage
    † Exemple : interface utilisateur d’une page
    public class CarPage extends WizardPage implements Listener {
    ...
    public CarPage(String pTitle) {
    super(pTitle);
    setTitle("Travel by car");
    setDescription("Specify car choices");
    ...
    }
    public void createControl(Composite parent) {
    // Construction de l’IHM
    }
    public void handleEvent(Event e) {
    if (e.widget == companyCombo) {
    // Traitement relatif à la sélection sur le Combo
    }
    setPageComplete(isPageComplete());
    getWizard().getContainer().updateButtons();
    }
    public boolean canFlipToNextPage() {
    return false;
    }
    ... // Suite dans le prochain transparent
    }
    CarPage.java du projet
    WizardExamples
    Lors d’une
    modification sur
    l’IHM, une demande
    de validation est
    réalisée
    Construction classique
    d’une IHM via
    SWT/JFace

    View Slide

  39. 39
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard : IWizardPage
    † Exemple (suite) : valider les données d’une page
    public class CarPage extends WizardPage implements Listener {
    ...
    public boolean isPageComplete() {
    HolidayWizard wizard = (HolidayWizard)getWizard();
    if (companyCombo.getText().length() == 0) {
    wizard.carCompleted = false;
    return false;
    }
    saveDataToModel();
    return true;
    }
    private void saveDataToModel() {
    HolidayWizard wizard = (HolidayWizard) getWizard();
    wizard.model.rentalCompany = companyCombo.getText();
    wizard.model.carPrice = priceText.getText();
    wizard.model.buyInsurance = insuranceButton.getSelection();
    wizard.carCompleted = true;
    }
    }
    CarPage.java du projet
    WizardExamples
    Extraction de la
    référence du Wizard
    Sauvegarde des
    données dans le
    modèle quand la
    page peut être
    complétée

    View Slide

  40. 40
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard
    † Pour afficher le Wizard deux solutions sont disponibles
    † Utiliser un WizardDialog qui fournit directement une boîte de dialogue
    † Utiliser la plateforme UI d’Eclipse (voir chapitre plugin) en se
    connectant au point d’extension fourni par org.eclipse.ui.newWizards
    † La classe WizardDialog fournit une encapsulation d’une boîte
    de dialogue (TitleAreaDialog de JFace)
    † WizardDialog permet de modifier et d’accéder à certaines
    propriétés graphiques de l’assistant (taille d’une page, page
    en cours, …)
    † De nombreuses méthodes …
    † WizardDialog(Shell parentShell, IWizard newWizard) : constructeur
    † open() : ouverture de la boîte de dialogue
    TitleAreaDialog : voir partie
    précédente

    View Slide

  41. 41
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Wizard
    † Exemple : afficher l’assistant
    public class HolidayWizard extends Wizard {
    ...
    public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("Wizard Example");
    shell.setLayout(new FillLayout());
    Button myButton = new Button(shell, SWT.FLAT);
    myButton.setText("Ouvrir Holiday Wizard");
    myButton.addSelectionListener(new SelectionAdapter() {
    public void widgetSelected(SelectionEvent e) {
    HolidayWizard wizard = new HolidayWizard();
    wizard.setWindowTitle("Holiday Wizard");
    WizardDialog refWizardDialog = new WizardDialog(shell, wizard);
    refWizardDialog.open();
    }
    });
    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
    if (!display.readAndDispatch())
    display.sleep();
    }
    display.dispose();
    }
    }
    HolidayWizard.java du projet
    WizardExamples
    Ouverture de l’assistant encapsulé
    dans une boîte de dialogue

    View Slide

  42. 42
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference
    † Les préférences permettent de gérer le paramétrage d’une
    application
    † La plateforme Eclipse fournit une gestion homogène et
    extensible des préférences
    † Caractéristiques principales de l’API Preference fournies par
    la plateforme Eclipse
    † Gestion du chargement et de la sauvegarde des paramètres
    † Squelette d’IHM : boutons prédéfinis (apply, default, cancel et ok)
    conteneur disponible pour personnaliser l’interface et champs
    paramétrables (description et titre)
    † Conteneur de pages de préférences

    View Slide

  43. 43
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : caractéristiques
    Pour un nœud est
    associée, une page
    de préférence
    Des boutons actions
    pour la boîte de
    dialogue de préférences
    Des boutons actions
    pour la page de
    préférences
    Des interfaces
    personnalisées
    par page
    Pour un autre nœud est
    associée une autre page
    de préférences

    View Slide

  44. 44
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : schéma de fonctionnement
    PreferenceMain
    PreferenceDialog
    PreferenceStore
    IPreferenceStore
    PreferenceManager
    PreferenceManager
    PreferenceNode
    IPreferenceNode
    PreferencePage
    IPreferencePage
    FieldEditorPreferencePage
    FieldEditorPreferencePage
    FieldEditor
    FieldEditor
    Relation hiérarchique entre
    les nœuds et les pages
    1
    Définition d’une
    page (associée à
    un nœud)
    Gestion implicite du chargement/sauvegarde des préférences
    Fichier de properties
    1..n
    1
    1
    Contient un ensemble
    de Composite pour
    l’IHM
    1
    1..n
    Le gestionnaire de
    persistance des préférences
    Boîte de dialogue
    des préférences
    Définition d’un nœud
    Définition d’une page de
    préférences qui gère
    exclusivement les
    FieldEditors
    Composants prédéfinis qui
    gère implicitement la
    persistance

    View Slide

  45. 45
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : IPreferencePage/PreferencePage
    † Une page fournit un regroupement de composants et de
    boutons de contrôle (defaults, apply, cancel et ok)
    † Une page est définie par l’interface IPreferencePage et son
    implémentation par défaut PreferencePage
    † La classe PreferencePage demande l’implémentation de
    † Control createContents(Composite parent) : retourne le contrôle en
    charge de définir l’IHM
    † Différentes méthodes sont également utilisables
    † performApply(), performOk, … : réalise le traitement associé à l’action
    sur un bouton de contrôle
    † setValid(boolean v) : si false, les boutons ok et valid sont désactivés
    † setMessage(String message, int newType) : affiche un message
    de sévérité donné par newType (ERROR, INFORMATION, NONE,
    WARNING)

    View Slide

  46. 46
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : IPreferencePage/PreferencePage
    † Exemple : page de préférences
    public class PreferencePageOne extends PreferencePage {
    private Text textFieldOne;
    private Text textFieldTwo;
    public PreferencePageOne() {
    super("Page Une");
    setDescription("Préféence des options 'Page Une'");
    }
    protected Control createContents(Composite comp) {
    Composite myComposite = new Composite(comp, SWT.NONE);
    myComposite.setLayout(new GridLayout(2, false));
    Label label = new Label(myComposite,SWT.LEFT);
    label.setText("Champs 1:");
    textFieldOne = new Text(myComposite, SWT.BORDER);
    textFieldOne.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    label = new Label(myComposite,SWT.LEFT);
    label.setText("Champs 2:");
    textFieldTwo = new Text(myComposite, SWT.BORDER);
    textFieldTwo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    return myComposite;
    }
    }
    Construction de
    l’IHM de cette page
    Définition du titre et de la
    description qui seront affichés
    en position haute de la page
    PreferencePageOne.java du
    projet PreferenceExamples

    View Slide

  47. 47
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : IPreferencePage/PreferencePage
    † Exemple (suite) : page de préférences
    public class PreferencePageOne extends PreferencePage {
    ...
    protected Control createContents(Composite comp) {
    ...
    textFieldOne = new Text(myComposite, SWT.BORDER);
    textFieldOne.addKeyListener(new KeyAdapter() {
    public void keyReleased(KeyEvent e) {
    validFieldOneValue();
    }
    }
    return myComposite;
    }
    private void validFieldOneValue() {
    String value = textFieldOne.getText();
    if (value == null || value.equals("")) {
    PreferencePageOne.this.setValid(false);
    }
    if (this.isValid()) {
    this.setMessage(null);
    } else {
    this.setMessage("Champs 1 : ne peut être vide", ERROR);
    }
    }
    }
    Vérifie à chaque
    saisie que le champ
    n’est pas vide
    PreferencePageOne.java du
    projet PreferenceExamples

    View Slide

  48. 48
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : IPreferenceNode/PreferenceNode
    † Le gestionnaire de préférences s’occupe de gérer les pages
    par l’intermédiaire de nœuds
    † Un nœud est associé à une seule page (IPreferencePage)
    † Un nœud est décrit par l’interface IPreferenceNode et son
    implémentation par défaut PreferenceNode
    † Plusieurs constructeurs définis
    † PreferenceNode(String id, IPreferencePage page) : construit un nœud
    id associé un objet PreferencePage page
    † PreferenceNode(String id, String label, ImageDescriptor image, String
    className) : un nœud id avec un nom, une icône et la page
    † Le nom et l’image donnent une représentation au nœud
    † Plusieurs méthodes de gestion de nœuds
    † add(IPreferenceNode node) : ajouter un sous nœud
    † IPreferenceNode[] getSubNodes() : retourne les sous noeuds

    View Slide

  49. 49
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : IPreferenceNode/PreferenceNode
    † Exemple : associer un nœud avec une page
    public class PreferenceExample {
    public PreferenceExample() {
    Display myDisplay = new Display();
    ...
    PreferenceNode one = new PreferenceNode("one", new PreferencePageOne());
    PreferenceNode two = new PreferenceNode("two", new PreferencePageTwo());
    PreferenceNode three = new PreferenceNode("three", "three", null,
    PreferencePageTwo.class.getName());
    one.add(two);
    one.add(three);
    System.out.println(one.getSubNodes().length); // Doit retourner 2 ...
    ...
    }
    public static void main(String[] args) {
    new PreferenceExample();
    }
    }
    PreferenceExample.java du
    projet PreferenceExamples
    Construit un nœud trois en
    se basant sur la définition
    du nœud 2
    Ajout du nœud two et
    three à la racine de one

    View Slide

  50. 50
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : PreferenceDialog
    † La gestion de la hiérarchie entre les nœuds et les pages est
    obtenue par un objet de type PreferenceManager
    † Différentes méthodes à utiliser
    † boolean addTo(String path, IPreferenceNode node) : ajoute un sous
    nœud au nœud identifié par path
    † void addToRoot(IPreferenceNode node) : ajoute le nœud node à la
    racine du gestionnaire de préférences
    † L’objet PreferenceManager est utilisé comme point de départ
    à l’affichage de la boîte de préférences via PreferenceDialog
    † PreferenceDialog(Shell parent, PreferenceManager pm) : construit
    une boîte de préférence sous le contrôle d’un PreferenceManager

    View Slide

  51. 51
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : PreferenceDialog
    † Exemple : afficher une boîte de dialogue de préférences
    public class PreferenceExample {
    public PreferenceExample() {
    ...
    PreferenceNode one = new PreferenceNode("one", new PreferencePageOne());
    PreferenceNode two = new PreferenceNode("two", new PreferencePageTwo());
    PreferenceNode three = new PreferenceNode("three", "Page Three", null,
    PreferencePageTwo.class.getName());
    one.add(two);
    one.add(three);
    PreferenceManager mgr = new PreferenceManager();
    mgr.addToRoot(one);
    // Autre écriture pour ajouter two et three à one
    // mgr.addTo("one", two);
    // mgr.addTo("one", three);
    PreferenceDialog myPreferenceDialog = new PreferenceDialog(null, mgr);
    myPreferenceDialog.open();
    myDisplay.dispose();
    }
    public static void main(String[] args) {
    new PreferenceExample();
    }
    }
    PreferenceExample.java du
    projet PreferenceExamples
    Construction d’un
    gestionnaire de
    préférences
    Ajout du nœud
    one à la racine
    Construction
    d’une boîte de
    dialogue de
    préférences

    View Slide

  52. 52
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : PreferenceStore
    † L’API JFace fournit un mécanisme qui permet de persister les
    informations de préférences
    † L’API de persistance s’appuie sur la classe PreferenceStore
    qui permet la sauvegarde et le chargement à partir d’un flux
    † Principales méthodes …
    † boolean getBoolean(String name) … : des accesseurs sur des valeurs
    de préférence par l’intermédiaire d’un nom
    † boolean getDefaultBoolean(String name) … : des accesseurs sur les
    valeurs par défaut au travers d’un nom
    † void setValue(String name, boolean value) : des modifieurs sur les
    valeurs au travers d’un nom et d’une valeur
    † void setDefaultValue(String name, boolean value) : des modifieurs sur
    les valeurs par défaut par l’intermédiaire d’un nom et d’une valeur
    † save() et save(OutputStream, String header) : sauvegarde
    † load() et load(InputStream) : chargement

    View Slide

  53. 53
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : PreferenceStore
    † Exemple : chargement et sauvegarde de préférences
    public class PreferenceStoreExample {
    public PreferenceStoreExample() {
    ...
    PreferenceNode one = new PreferenceNode("one", new PreferenceStorePageOne());
    PreferenceNode two = new PreferenceNode("two", new PreferenceStorePageTwo());
    PreferenceManager mgr = new PreferenceManager();
    mgr.addToRoot(one);
    mgr.addTo("one", two);
    PreferenceDialog myPreferenceDialog = new PreferenceDialog(null, mgr);
    PreferenceStore ps = new PreferenceStore("prefs.properties");
    try {
    ps.load();
    } catch (IOException e) {
    e.printStackTrace();
    }
    myPreferenceDialog.setPreferenceStore(ps);
    myPreferenceDialog.open();
    try {
    ps.save();
    } catch (IOException e) {
    e.printStackTrace();
    }
    ...
    }
    }
    PreferenceStoreExample.java du
    projet PreferenceExamples
    Création d’un
    PreferenceStore
    à partir d’un
    fichier « plat »
    prefs.properties
    Chargement des préférences
    Associe l’objet PreferenceStore
    à l’objet PreferenceDialog qui le
    dispatchera à toutes les pages

    View Slide

  54. 54
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : PreferenceStore
    † Exemple (suite) : chargement et sauvegarde de préférences
    public class PreferenceStorePageOne extends PreferencePage {
    private static final String FIELD1_PROPERTIES = "pageOne.field1";
    private static final String FIELD2_PROPERTIES = "pageOne.field2";
    protected Control createContents(Composite comp) {
    ...
    textFieldOne.setText(currentPreferenceStore.getString(FIELD1_PROPERTIES));
    textFieldTwo.setText(currentPreferenceStore.getString(FIELD2_PROPERTIES));
    ...
    }
    public boolean performApply() {
    this.performOk();
    }
    public boolean performOk() {
    IPreferenceStore currentPreferenceStore = getPreferenceStore();
    // Modification du contenu de la sauvegarde à partir des champs de texte
    if (this.textFieldOne != null)
    currentPreferenceStore.setValue(FIELD1_PROPERTIES, textFieldOne.getText());
    if (this.textFieldTwo != null)
    currentPreferenceStore.setValue(FIELD2_PROPERTIES, textFieldTwo.getText());
    return t rue;
    }
    }
    PreferenceStorePageOne.java du
    projet PreferenceExamples
    A la construction
    besoin d’initialiser le
    contenu des
    composants
    Appeler lors de
    l’action Apply
    Récupération de
    gestionnaire de persistance
    Sauvegarde des préférences
    Appeler lors de
    l’action Ok

    View Slide

  55. 55
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor
    † La construction d’une page de préférences impose de devoir
    gérer explicitement la persistance des valeurs
    † Les composants FieldEditor fournissent une encapsulation de
    la gestion de la persistance de manière à masquer cette
    étape répétitive
    † Un composant FieldEditor encapsule également un composant
    graphique
    † Selon le composant utilisé, des contrôles de cohérence
    implicites peuvent être réalisés (Integer correctement formé)
    † JFace fournit une bibliothèque prédéfinie de composants
    graphiques
    † Construction commune d’un composant FieldEditor
    † FieldEditor(String name, String label, Composite parent) : FieldEditor
    identifié par name, une valeur pour un label et le composant parent

    View Slide

  56. 56
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor
    PreferenceFieldEditorPageOne.java
    du projet PreferenceExamples
    BooleanFieldEditor
    StringFieldEditor
    IntegerFieldEditor
    ColorFieldEditor
    DirectoryFieldEditor
    FileFieldEditor

    View Slide

  57. 57
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor
    PreferenceFieldEditorPageTwo.java
    du projet PreferenceExamples
    FontFieldEditor
    RadioGroupFieldEditor
    PathEditor
    ScaleFieldEditor

    View Slide

  58. 58
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditorPreferencePage
    † Pour intégrer des objets FieldEditors dans une page de
    préférences, la page doit étendre FieldEditorPreferencePage
    † Une page FieldEditorPreferencePage positionne verticalement
    les objects FieldEditors
    † Styles des FieldEditors lors de la construction d’une page
    † GRID : l’espace entre le label et le composant est uniforme
    † FLAT : l’espace entre le champ de texte et le composant varie
    † FieldEditorPreferencePage nécessite l’implémentation de
    † Control createContents(Composite parent) : retourne le contrôle en
    charge de définir l’IHM
    † Différentes méthodes sont également utilisables
    † addField(FieldEditor fe) : ajoute l’objet FieldEditor à la page
    † getFieldEditorParent() : permet de retourne le parent de la page (à
    utiliser lors de la construction des composants FieldEditors)

    View Slide

  59. 59
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditorPreferencePage
    † Exemple : page de préférences pour FieldEditors
    public class PreferenceFieldEditorPageOne extends FieldEditorPreferencePage {
    private static final String FILE_PROPERTIES = "pageOne.file";
    ...
    public PreferenceFieldEditorPageOne() {
    super("Page Une", GRID);
    }
    protected void createFieldEditors() {
    BooleanFieldEditor bfe = new BooleanFieldEditor(CHECK_PROPERTIES, "Booléen",
    getFieldEditorParent());
    addField(bfe);
    StringFieldEditor sfe = new StringFieldEditor(STRING_PROPERTIES, "Chaîne de
    caractères", getFieldEditorParent());
    addField(sfe);
    IntegerFieldEditor ife = new IntegerFieldEditor(INTEGER_PROPERTIES,"Entier",
    getFieldEditorParent());
    addField(ife);
    ColorFieldEditor cfe = new ColorFieldEditor(COLOR_PROPERTIES,"Couleur",
    getFieldEditorParent());
    addField(cfe);
    DirectoryFieldEditor dfe = new DirectoryFieldEditor(DIRECTORY_PROPERTIES,
    "Répertoire", getFieldEditorParent());
    addField(dfe);
    FileFieldEditor ffe = new FileFieldEditor(FILE_PROPERTIES, "Fichier",
    getFieldEditorParent());
    addField(ffe);
    }
    } PreferenceFieldEditorPageOne.java
    du projet PreferenceExamples
    Style GRID définit comment sont
    affichés les FieldEditors
    L’identifiant du FieldEditor est utilisé
    pour persister la préférence

    View Slide

  60. 60
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditorPreferencePage
    † Exemple (suite) : page de préférences pour FieldEditors
    public class PreferenceFieldEditorExample {
    public PreferenceFieldEditorExample() {
    ...
    PreferenceNode one = new PreferenceNode("one", new PreferenceFieldEditorPageOne());
    PreferenceNode two = new PreferenceNode("two", new PreferenceFieldEditorPageTwo());
    PreferenceNode three = new PreferenceNode("three", new
    PreferenceFieldEditorPageThree());
    PreferenceManager mgr = new PreferenceManager();
    mgr.addToRoot(one);
    mgr.addToRoot(two);
    mgr.addToRoot(three);
    PreferenceDialog myPreferenceDialog = new PreferenceDialog(null, mgr);
    PreferenceStore ps = new PreferenceStore("fieldprefs.properties");
    try {
    ps.load();
    } catch (IOException e) { e.printStackTrace(); }
    myPreferenceDialog.setPreferenceStore(ps);
    myPreferenceDialog.open();
    try {
    ps.save();
    } catch (IOException e) { e.printStackTrace(); }
    ...
    }
    } PreferenceFieldEditorExample.java du
    projet PreferenceExamples
    Construction identique aux
    objets de type PreferencePage
    Fichier contenant les valeurs des
    préférences

    View Slide

  61. 61
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditorPreferencePage
    † Exemple (suite) : page de préférences pour FieldEditors
    PreferenceFieldEditorPageOne.java
    du projet PreferenceExamples
    fieldprefs.properties du projet
    PreferenceExamples
    pageOne.string

    View Slide

  62. 62
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Il se peut que les composants FieldEditor ne correspondent
    pas directement aux besoins
    † Possibilité de créer facilement de nouveaux FieldEditor
    † Principales méthodes
    † int getNumberOfControls() : retourne le nombre de composants
    contenu dans le FieldEditor
    † adjustForNumColumns(int nC) : ajuste la valeur « horizontal span »
    par le nombre de colonne nC
    † doFillIntoGrid(Composite p, int nC) : construction des composants via
    le parent p et le nombre de colonne nC
    † doLoad() : chargement des préférences
    † doLoadDefault() : chargement par défaut
    † doStore() : sauvegarde des préférences

    View Slide

  63. 63
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Exemple : composant FieldEditor min/max
    PreferenceFieldEditorPageFour.java
    du projet PreferenceExamples
    La valeur min est supérieure à la
    valeur max => génération erreur
    La valeur min ou la valeur max
    contient une valeur non cohérente
    => génération erreur
    Le but de ce FieldEditor est de fournir
    deux zones de saisies d’entier dont la
    valeur min est strictement inférieure à
    la valeur max
    Un composite
    contient un label et
    un champ de texte

    View Slide

  64. 64
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Exemple (suite) : composant FieldEditor min/max
    public class MinMaxFieldEditor {
    ...
    protected void doFillIntoGrid(Composite parent, int numColumns) {
    top = parent;
    ...
    Label label = this.getLabelControl(parent);
    GridData labelData = new GridData();
    labelData.horizontalSpan = numColumns;
    label.setLayoutData(labelData);
    ...
    minField = new Text(minComposite, SWT.BORDER);
    minField.addKeyListener(new KeyAdapter() {
    public void keyReleased(KeyEvent e) {
    clearErrorMessage();
    }
    });
    minField.addFocusListener(new FocusAdapter()) {
    public void focusGained(FocusEvent e) {
    refreshValidateState();
    }
    public void focusLost(FocusEvent e) {
    valueChanged();
    clearErrorMessage();
    }
    }
    }
    }
    La validation est réalisée
    lors de la perte du focus
    MinMaxFieldEditor.java du projet
    PreferenceExamples
    Le label est positionné
    sur la partie haute

    View Slide

  65. 65
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Exemple (suite) : composant FieldEditor min/max
    public class MinMaxFieldEditor {
    ...
    protected void adjustForNumColumns(int numColumns) {
    GridData layoutData = (GridData)top.getLayoutData();
    layoutData.horizontalSpan = numColumns;
    }
    public int getNumberOfControls() {
    return 2;
    }
    protected void doLoadDefault() {
    if (minField != null && maxField !=null) {
    int minValue = getPreferenceStore().getDefaultInt(getPreferenceName() +
    MIN_NAME);
    int maxValue = getPreferenceStore().getDefaultInt(getPreferenceName() +
    MAX_NAME);
    minField.setText("" + minValue); maxField.setText("" + maxValue);
    }
    valueChanged();
    }
    protected void doLoad() {
    ...
    }
    protected void doStore() {
    if (minField != null && maxField !=null) {
    Integer i = new Integer(minField.getText());
    Integer j = new Integer(maxField.getText());
    getPreferenceStore().setValue(getPreferenceName() + MIN_NAME, i.intValue());
    getPreferenceStore().setValue(getPreferenceName() + MAX_NAME, j.intValue());
    }
    }
    MinMaxFieldEditor.java du projet
    PreferenceExamples
    Modification des
    paramètres de l’agent de
    placement du parent
    Deux composites
    • minComposite
    • maxComposite
    Même principe que
    doLoadDefault()

    View Slide

  66. 66
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    public class PreferencePersoFieldEditorExample {
    public PreferencePersoFieldEditorExample() {
    PreferenceManager mgr = new PreferenceManager();
    PreferenceNode three = new PreferenceNode("three",
    new PreferenceFieldEditorPageThree());
    PreferenceNode four = new PreferenceNode("four",
    new PreferenceFieldEditorPageFour());
    mgr.addToRoot(three);
    mgr.addToRoot(four);
    PreferenceDialog myPreferenceDialog = new PreferenceDialog(null, mgr);
    PreferenceStore ps = new PreferenceStore("persofieldprefs.properties");
    ...
    }
    }
    JFace/Preference : FieldEditor personnalisé
    † Exemple (suite) : composant FieldEditor min/max
    public class PreferenceFieldEditorPageFour extends FieldEditorPreferencePage {
    public PreferenceFieldEditorPageFour() {
    super("Page Quatre", GRID);
    }
    protected void createFieldEditors() {
    MinMaxFieldEditor bfe = new MinMaxFieldEditor("tolerance", "Tolérence", 3,
    getFieldEditorParent());
    addField(bfe);
    }
    }
    PreferencePersoFieldEditorExample.java
    du projet PreferenceExamples
    PreferencePersoFieldEditorPageFour.java
    du projet PreferenceExamples

    View Slide

  67. 67
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Exemple : espaces entre FieldEditors
    PreferencePersoFieldEditorPageTwo.java
    du projet PreferenceExamples
    PreferencePersoFieldEditorPageFour.java
    du projet PreferenceExamples
    Construction d’objets SpacerFieldEditor pour
    définir explicitement des espaces entre les
    FieldEditors
    Exemple basé sur celui-ci …
    www.eclipse.org/articles/Article-Field-Editors/field_editors.html

    View Slide

  68. 68
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Exemple (suite) : espaces entre FieldEditors
    public class LabelFieldEditor extends FieldEditor {
    private Label label;
    private int vGap;
    public LabelFieldEditor(String value, Composite parent, int pVGap) {
    init("label", value);
    this.vGap = pVGap;
    if (vGap < 0) { this.vGap = 0; }
    createControl(parent);
    }
    protected void adjustForNumColumns(int numColumns) {
    ((GridData) label.getLayoutData()).horizontalSpan = numColumns;
    }
    protected void doFillIntoGrid(Composite parent, int numColumns) {
    label = getLabelControl(parent);
    GridData gridData = new GridData();
    ...
    gridData.heightHint = vGap;
    label.setLayoutData(gridData);
    }
    public int getNumberOfControls() {
    return 1;
    }
    protected void doLoad() {}
    protected void doLoadDefault() {}
    protected void doStore() {}
    }
    LabelFieldEditor.java du projet
    PreferenceExamples
    Spécifier la hauteur du
    composant label
    Ne sauvegarde pas les
    préférences
    FieldEditor spécifique permettant
    d’afficher un label et de spécifier
    une hauteur

    View Slide

  69. 69
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Preference : FieldEditor personnalisé
    † Exemple (suite) : espaces entre FieldEditors
    public class SpacerFieldEditor extends LabelFieldEditor {
    public SpacerFieldEditor(Composite parent, int pVGap) {
    super("", parent, pVGap);
    }
    }
    public class PreferenceFieldEditorPageThree extends FieldEditorPreferencePage {
    protected void createFieldEditors() {
    FontFieldEditor ffe = new FontFieldEditor(FONT_PROPERTIES, "Police",
    getFieldEditorParent());
    addField(ffe);
    SpacerFieldEditor spacer = new SpacerFieldEditor(getFieldEditorParent(), V_GAP);
    addField(spacer);
    RadioGroupFieldEditor rfe = new RadioGroupFieldEditor(RADIO_PROPERTIES,
    "Radio Group", 2, strings, getFieldEditorParent(), true);
    addField(rfe);
    spacer = new SpacerFieldEditor(getFieldEditorParent(), V_GAP);
    addField(spacer);
    ...
    }
    }
    SpacerFieldEditor.java du projet
    PreferenceExamples
    PreferenceFieldEditorPageThree.java du
    projet PreferenceExamples
    Entre chaque FieldEditor un
    SpacerFieldEditor pour ajouter un
    espace horizontal
    Un SpacerFieldEditor
    est un LabelFieldEditor
    sans valeur de texte

    View Slide

  70. 70
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Resource : ImageDescriptor
    † Nous avons vu dans la partie SWT que la création d’objets
    Image nécessitait l’utilisation d’un Display
    † Un descripteur d’image définit par ImageDescriptor est une
    sorte de factory d’images sans utilisation explicite d’un
    Display
    † A partir d’un ImageDescriptor, il est possible de
    † Image createImage() : créer un objet Image
    † ImageData getImageData() : créer un objet ImageData
    † Création à partir d’un fichier
    † static ImageDescriptor createFromFile(Class location, String filename)
    † location chemin de la classe qui définit le répertoire de la ressource
    † filename nom du fichier
    † Création à partir d’une URL
    † static ImageDescriptor createFromURL(URL url)

    View Slide

  71. 71
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Resource : ImageDescriptor
    † Exemple : afficher une image via un ImageDescriptor
    package eclipse.jface.resourceexamples;
    public class ImageDescriptorExample {
    public ImageDescriptorExample() {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("ImageDescriptor : File and URL");
    shell.setLayout(new GridLayout(1, false));
    ImageDescriptor imageDescr = ImageDescriptor.createFromFile(
    eclipse.jface.resourceexamples.ImageDescriptorExample.class,
    "image/superstar.jpg");
    Label myLabelImage = new Label(shell, SWT.NONE);
    myLabelImage.setImage(imageDescr.createImage());
    shell.pack();
    shell.open();
    ...
    }
    public static void main(String[] args) {
    new ImageDescriptorExample();
    }
    }
    ImageDescriptorExample.java du projet
    ResourceExamples
    L’image est localisée dans
    un sous répertoire image
    qui est à la racine du sous
    package resourceexamples
    Création d’un Image à partir
    d’un ImageDescriptor

    View Slide

  72. 72
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Resource : Resource
    † Lors de la conception d’interfaces utilisateurs, il est souvent
    nécessaire de réutiliser des mêmes ressources : couleurs,
    fontes, images, ressources bundles
    † JFaceResources fournit un mécanisme pour la déclaration de
    ressources dans des registres et de les appeler par un nom
    † Chaque type de ressource est défini dans un registre dont les
    accès sont définis dans JFaceResources
    † ColorRegistry pour les couleurs via getColorRegistry()
    † FontRegistry pour les fontes via getFontRegistry()
    † ImageRegistry pour les images via getImageRegistry()
    † Les registres fonctionnent sur un principe commun : cas du
    registre ColorRegistry
    † put(String id, RGB colorData) : ajouter une couleur au registre
    † Color get(String id) : accesseur sur la couleur identifiée par id

    View Slide

  73. 73
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Resource : Resource
    † Exemple : gestion des ressources via les registres
    public class ResourcesExample {
    public static final String SUPERSTAR_KEULKEUL_IMAGE = "superstar";
    public static final String ARIAL_KEULKEUL_FONT = "Arial";
    public static final String RED_KEULKEUL_COLOR = "red";
    public static final String BLACK_KEULKEUL_COLOR = "black";
    public void ResourcesExample() {
    // Color resources definition
    ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
    colorRegistry.put(BLACK_KEULKEUL_COLOR, new RGB(0,0,0));
    colorRegistry.put(RED_KEULKEUL_COLOR, new RGB(255, 0, 0));
    // Font resources definition
    FontRegistry fontRegistry = JFaceResources.getFontRegistry();
    FontData fontData = new FontData(ARIAL_KEULKEUL_FONT, 40, SWT.BOLD);
    fontRegistry.put(ARIAL_KEULKEUL_FONT, new FontData[]{fontData});
    // Image resources definition
    ImageRegistry imageRegistry = JFaceResources.getImageRegistry();
    ImageDescriptor myImageDescriptor =
    ImageDescriptor.createFromFile(eclipse.jface.resourceexamples.ResourcesExample.
    class, "image/superstar.jpg");
    imageRegistry.put(SUPERSTAR_KEULKEUL_IMAGE, myImageDescriptor);
    }
    ...
    } ResourcesExample.java du projet
    ResourceExamples

    View Slide

  74. 74
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    JFace/Resource : Resource
    † Exemple (suite) : gestion des ressources via les registres
    public class ResourcesExample {
    public ResourcesExample() {
    Display display = new Display();
    initResources();
    final Shell shell = new Shell(display);
    shell.setText("JFaceResources : Registry");
    shell.setLayout(new GridLayout());
    // The first parameter gives the peer to localize the image file.
    Label myLabelImage = new Label(shell, SWT.NONE);
    myLabelImage.setImage(JFaceResources.getImageRegistry()
    .get(SUPERSTAR_KEULKEUL_IMAGE));
    Label myLabelColor = new Label(shell, SWT.NONE);
    myLabelColor.setBackground(JFaceResources.getColorRegistry()
    .get(BLACK_KEULKEUL_COLOR));
    myLabelColor.setForeground(JFaceResources.getColorRegistry()
    .get(RED_KEULKEUL_COLOR));
    myLabelColor.setFont(JFaceResources.getFontRegistry()
    .get(ARIAL_KEULKEUL_FONT));
    myLabelColor.setText("He is a super star baby");
    ...
    }
    }
    ResourcesExample.java du projet
    ResourceExamples
    Récupération des ressources
    via les registres associés

    View Slide

  75. 75
    JFace II - M. Baron - Page
    mickael-baron.fr mickaelbaron
    Bilan …
    † Premières impressions …
    † De nombreuses APIs pour gérer des fonctionnalités indispensables à
    des applications classiques
    † Des composants homogènes via l’héritage de la classe Dialog
    † Les choses non étudiées, prochainement
    † Gestion de texte via le composant TextViewer
    † Intégration des Wizards et des Preferences dans la plateforme
    Eclipse via la notion d’extension (voir chapitre Conception de plug-ins)
    † Prochaine étape : Conception de plug-ins
    † Pour l’instant nous avons étudié les APIs qui se limitent à la couche
    graphique
    † Le prochain chapitre s’intéressera à la conception de plug-ins

    View Slide