Composants additionnels avec JFace

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

description

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.

Transcript of Composants additionnels avec JFace

Page 1: Composants additionnels avec JFace

Développement de clients riches : Plateforme Eclipse

Mickaël BARON - 2008 (Rév. Janvier 2009) mailto:[email protected] ou mailto:[email protected]

Composants additionnels avec JFace

Chapitre 2 : BoChapitre 2 : Boîîtes tes àà outilsoutils

Page 2: Composants additionnels avec JFace

2JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

Creative Commons

Contrat Paternité

Partage des Conditions Initiales à l'Identique

2.0 France

http://creativecommons.org/licenses/by-sa/2.0/fr

Licence

Page 3: Composants additionnels avec JFace

3JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 mbaron.developpez.com/eclipse/jface2

Page 4: Composants additionnels avec JFace

4JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 5: Composants additionnels avec JFace

5JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 6: Composants additionnels avec JFace

6JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace / Boîtes de dialogue

� Hiérarchie des principales classes de dialogue

Dialog

InputDialogIconAndMessageDialog TrayDialog

PreferenceDialogTitleAreaDialog

WizardDialog

ErrorDialog MessageDialog

ProgressMonitorDialog

Classes étudiées

Classes génériques

Etudiées dans les parties Preference et

Wizard

Page 7: Composants additionnels avec JFace

7JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace / Boîtes de dialogue

� Boîtes de dialogue de type IconAndMessageDialog

� ErrorDialog

� MessageDialog

� ProgressMonitorDialog Une IconAndMessageDialogse caractérise par un

message d’information …

et une icône

Page 8: Composants additionnels avec JFace

8JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : MessageDialog

� Les boîtes de dialogue de type MessageDialog sont utiliséespour 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)

Page 9: Composants additionnels avec JFace

9JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : MessageDialog

� Exemple : afficher différents types de MessageDialogpublic 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 : " + confirma tionStatus);

}

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 infor matif.") ;}

public static void questionDialog(Shell pShell) {boolean questionStatus = MessageDialog. openQuestion(pShell, "JFace Message Dialog

: Question", "[Placer ici votre message] Etes-vous su r 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 i ci

votre message] Attention, il s'est passé quelque cho se d’étrange ...") ;}

} MessageDialogExample.javadu projet DialogExamples

Page 10: Composants additionnels avec JFace

10JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : MessageDialog

� Exemple (suite) : afficher différents types de MessageDialog

Confirmation

Error

Information

Question

Warning

Page 11: Composants additionnels avec JFace

11JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / 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)

Page 12: Composants additionnels avec JFace

12JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / 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)

Page 13: Composants additionnels avec JFace

13JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : ErrorDialog

� Exemple : afficher des boîtes ErrorDialogpublic class ErrorDialogExample {

public static void errorDialog(Shell pShell, int se verity) {String statusMessage = "[Placer ici le status de l'err eur]\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 I D", 0, statusMessage, null);

ErrorDialog. openError(pShell, "JFace Error Dialog", "[Placer ici le messag ed'erreur] \n\n Un problème est survenu au niveau ... ", errorStatus);

}}

ErrorDialogExample.java du projet DialogExamples

Page 14: Composants additionnels avec JFace

14JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : ErrorDialog

� Exemple : afficher des boîtes ErrorDialog

Status : Info

Status : Warning

Status : Error

Page 15: Composants additionnels avec JFace

15JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 16: Composants additionnels avec JFace

16JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace / Boîtes de dialogue : ProgressMonitorDialog

� Un objet de type IRunnableWithProgress permet de décrireune opération de longue durée

� Une classe de type IRunnableWithProgress doit implémenter

� run(IProgressMonitor monitor) : traitement de l’opération dont lerapport en cours de traitement est envoyé à monitor

� Un IProgressMonitor renseigne l’état d’avancement d’uneopé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 (UNKNOWNsi 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

Page 17: Composants additionnels avec JFace

17JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace / Boîtes de dialogue : ProgressMonitorDialog

� Exemple : afficher des boîtes ProgressMonitorDialogpublic class ProgressMonitorDialogExample {

public static void progressMonitorDialog(Shell pShell, b oolean 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.javadu projet DialogExamples

Page 18: Composants additionnels avec JFace

18JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace / Boîtes de dialogue : ProgressMonitorDialog

� Exemple (suite) : afficher des boîtes ProgressMonitorDialogpublic class WorkLessOperation implements IRunnableWith Progress {

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 Invocat ionTargetException,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 \"WorkLe ss\" 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

Page 19: Composants additionnels avec JFace

19JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 20: Composants additionnels avec JFace

20JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / 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

Page 21: Composants additionnels avec JFace

21JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : InputDialog

� Exemple : afficher des boîtes InputDialogpublic class InputDialogExample {

public static void validationIntegerInputDialog(Shell p Shell) {InputDialog myInputDialog = new InputDialog(pShell, "JFa ce 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 sai sissant : "

+ myInputDialog.getValue());} else {

System. out.println("Vous avez sélectionné l'annulation.");}

}...

}

InputDialogExample.java du projet DialogExamples

Page 22: Composants additionnels avec JFace

22JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace / Boîtes de dialogue : InputDialog

� Exemple (suite) : afficher des boîtes InputDialogpublic 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.javadu projet DialogExamples

Page 23: Composants additionnels avec JFace

23JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

� …

Page 24: Composants additionnels avec JFace

24JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 25: Composants additionnels avec JFace

25JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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, Strin g 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

Page 26: Composants additionnels avec JFace

26JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace / Boîtes de dialogue : custom TitleAreaDialog

� Exemple (suite) : afficher une TitleAreaDialog personnalisée public class CustomTitleAreaDialog extends TitleAreaD ialog {

... // 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.createDialogAre a(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

Page 27: Composants additionnels avec JFace

27JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 « Assistantde 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

Page 28: Composants additionnels avec JFace

28JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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 retourContrainte 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

Page 29: Composants additionnels avec JFace

29JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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é

Page 30: Composants additionnels avec JFace

30JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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é

Page 31: Composants additionnels avec JFace

31JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Wizard : schéma de fonctionnement

WizardIWizard

WizardIWizard

Page 1IWizardPage

Page 1IWizardPage

Page 2IWizardPage

Page 2IWizardPage

Page nIWizardPage

Page nIWizardPage

WizardModel

- propriété 1- propriété 2- …

+ getPropriété1()+ setPropriété1()+ getPropriété2()+ setPropriété2()+ ...

WizardMainWizardDialog

WizardMainWizardDialog

1..n

1

12

4

1

1

1

3

2

34

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

Page 32: Composants additionnels avec JFace

32JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 33: Composants additionnels avec JFace

33JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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() == holiday Page)

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 projetWizardExamples

Page 34: Composants additionnels avec JFace

34JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 35: Composants additionnels avec JFace

35JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 projetWizardExamples

HolidayWizard.java du projetWizardExamples

Liste des attributs utilisés par l’assistant

Page 36: Composants additionnels avec JFace

36JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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)

Page 37: Composants additionnels avec JFace

37JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Wizard : IWizardPage

� Exemple : interface utilisateur d’une page public class CarPage extends WizardPage implements Lis tener {

...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 projetWizardExamples

Lors d’une modification sur

l’IHM, une demande de validation est

réalisée

Construction classique d’une IHM via SWT/JFace

Page 38: Composants additionnels avec JFace

38JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Wizard : IWizardPage

� Exemple (suite) : valider les données d’une page

public class CarPage extends WizardPage implements Lis tener {...

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.getSele ction();wizard.carCompleted = true;

}}

CarPage.java du projetWizardExamples

Extraction de la référence du Wizard

Sauvegarde des données dans le modèle quand la page peut être complétée

Page 39: Composants additionnels avec JFace

39JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 40: Composants additionnels avec JFace

40JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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(she ll, wizard);refWizardDialog.open();

}});

shell.pack();shell.open();while (!shell.isDisposed()) {

if (!display.readAndDispatch())display.sleep();

}display.dispose();

}}

HolidayWizard.java du projetWizardExamples

Ouverture de l’assistant encapsulédans une boîte de dialogue

Page 41: Composants additionnels avec JFace

41JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 42: Composants additionnels avec JFace

42JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : caractéristiques

Pour un nœud est associée, une page

de préférence

Des boutons actionspour la boîte de

dialogue de préférences

Des boutons actionspour 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

Page 43: Composants additionnels avec JFace

43JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : schéma de fonctionnement

PreferenceMainPreferenceDialog

PreferenceMainPreferenceDialog

PreferenceStoreIPreferenceStore

PreferenceStoreIPreferenceStore

PreferenceManagerPreferenceManager

PreferenceManagerPreferenceManager

PreferenceNodeIPreferenceNode

PreferenceNodeIPreferenceNode

PreferencePageIPreferencePage

PreferencePageIPreferencePage

FieldEditorPreferencePageFieldEditorPreferencePage

FieldEditorPreferencePageFieldEditorPreferencePage

FieldEditorFieldEditor

FieldEditorFieldEditor

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 depersistance 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

Page 44: Composants additionnels avec JFace

44JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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)

Page 45: Composants additionnels avec JFace

45JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 46: Composants additionnels avec JFace

46JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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

Page 47: Composants additionnels avec JFace

47JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : IPreferenceNode/PreferenceNode

� Le gestionnaire de préférences s’occupe de gérer les pagespar 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 sonimplémentation par défaut PreferenceNode

� Plusieurs constructeurs définis

� PreferenceNode(String id, IPreferencePage page) : construit un nœudid associé un objet PreferencePage page

� PreferenceNode(String id, String label, ImageDescriptor image, StringclassName) : 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

Page 48: Composants additionnels avec JFace

48JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 Prefer encePageOne());PreferenceNode two = new PreferenceNode("two", new Prefer encePageTwo());PreferenceNode three = new PreferenceNode("three", "thre e", 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 2Ajout du nœud two et three à la racine de one

Page 49: Composants additionnels avec JFace

49JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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

Page 50: Composants additionnels avec JFace

50JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : PreferenceDialog

� Exemple : afficher une boîte de dialogue de préférencespublic class PreferenceExample {

public PreferenceExample() {...PreferenceNode one = new PreferenceNode("one", new Prefer encePageOne());PreferenceNode two = new PreferenceNode("two", new Prefer encePageTwo());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 PreferenceDia log(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

Page 51: Composants additionnels avec JFace

51JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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 PreferenceStorequi permet la sauvegarde et le chargement à partir d’un flux

� Principales méthodes …

� boolean getBoolean(String name) … : des accesseurs sur des valeursde préférence par l’intermédiaire d’un nom

� boolean getDefaultBoolean(String name) … : des accesseurs sur lesvaleurs par défaut au travers d’un nom

� void setValue(String name, boolean value) : des modifieurs sur lesvaleurs au travers d’un nom et d’une valeur

� void setDefaultValue(String name, boolean value) : des modifieurs surles 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

Page 52: Composants additionnels avec JFace

52JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : PreferenceStore

� Exemple : chargement et sauvegarde de préférencespublic class PreferenceStoreExample {

public PreferenceStoreExample() {...PreferenceNode one = new PreferenceNode("one", new Prefer enceStorePageOne());PreferenceNode two = new PreferenceNode("two", new Prefer enceStorePageTwo());PreferenceManager mgr = new PreferenceManager();mgr.addToRoot(one);mgr.addTo("one", two);

PreferenceDialog myPreferenceDialog = new PreferenceDia log(null, mgr);PreferenceStore ps = new PreferenceStore("prefs.propert ies");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

Page 53: Composants additionnels avec JFace

53JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : PreferenceStore

� Exemple (suite) : chargement et sauvegarde de préférencespublic class PreferenceStorePageOne extends PreferenceP age {

private static final String FIELD1_PROPERTIES = "pageOne.field1";private static final String FIELD2_PROPERTIES = "pageOne.field2";

protected Control createContents(Composite comp) {...textFieldOne.setText(currentPreferenceStore.getStri ng(FIELD1_PROPERTIES));textFieldTwo.setText(currentPreferenceStore.getStri ng(FIELD2_PROPERTIES));...

}

public boolean performApply() {this.performOk();

}

public boolean performOk() {IPreferenceStore currentPreferenceStore = getPreferenceStore();// Modification du contenu de la sauvegarde à partir des champs de texteif (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

Page 54: Composants additionnels avec JFace

54JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditor

� La construction d’une page de préférences impose de devoirgérer explicitement la persistance des valeurs

� Les composants FieldEditor fournissent une encapsulation dela gestion de la persistance de manière à masquer cetteétape répétitive

� Un composant FieldEditor encapsule également un composantgraphique

� 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 composantsgraphiques

� Construction commune d’un composant FieldEditor

� FieldEditor(String name, String label, Composite parent) : FieldEditoridentifié par name, une valeur pour un label et le composant parent

Page 55: Composants additionnels avec JFace

55JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditor

PreferenceFieldEditorPageOne.java du projet PreferenceExamples

BooleanFieldEditor

StringFieldEditor

IntegerFieldEditor

ColorFieldEditor

DirectoryFieldEditor

FileFieldEditor

Page 56: Composants additionnels avec JFace

56JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditor

PreferenceFieldEditorPageTwo.java du projet PreferenceExamples

FontFieldEditor

RadioGroupFieldEditor

PathEditor

ScaleFieldEditor

Page 57: Composants additionnels avec JFace

57JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditorPreferencePage

� Pour intégrer des objets FieldEditors dans une page depréférences, la page doit étendre FieldEditorPreferencePage

� Une page FieldEditorPreferencePage positionne verticalementles 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)

Page 58: Composants additionnels avec JFace

58JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditorPreferencePage

� Exemple : page de préférences pour FieldEditorspublic class PreferenceFieldEditorPageOne extends Field EditorPreferencePage {

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

Page 59: Composants additionnels avec JFace

59JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditorPreferencePage

� Exemple (suite) : page de préférences pour FieldEditorspublic 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 PreferenceDia log(null, mgr);PreferenceStore ps = new PreferenceStore("fieldprefs.pr operties");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

Page 60: Composants additionnels avec JFace

60JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Preference : FieldEditorPreferencePage

� Exemple (suite) : page de préférences pour FieldEditors

PreferenceFieldEditorPageOne.java du projet PreferenceExamples

fieldprefs.properties du projetPreferenceExamples

pageOne.string

Page 61: Composants additionnels avec JFace

61JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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

Page 62: Composants additionnels avec JFace

62JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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 maxcontient 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 compositecontient un label et un champ de texte

Page 63: Composants additionnels avec JFace

63JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : FieldEditor personnalisé

� Exemple (suite) : composant FieldEditor min/maxpublic class MinMaxFieldEditor {

...protected void doFillIntoGrid(Composite parent, int numC olumns) {

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 projetPreferenceExamples

Le label est positionnésur la partie haute

Page 64: Composants additionnels avec JFace

64JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : FieldEditor personnalisé

� Exemple (suite) : composant FieldEditor min/maxpublic 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(getP referenceName() +

MIN_NAME);int maxValue = getPreferenceStore().getDefaultInt(getP referenceName() +

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 projetPreferenceExamples

Modification des paramètres de l’agent de placement du parent

Deux composites• minComposite• maxComposite

Même principe que doLoadDefault()

Page 65: Composants additionnels avec JFace

65JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 PreferenceDia log(null, mgr);

PreferenceStore ps = new PreferenceStore("persofieldpre fs.properties");...

}}

JFace/Preference : FieldEditor personnalisé

� Exemple (suite) : composant FieldEditor min/maxpublic class PreferenceFieldEditorPageFour extends FieldEditorPreferencePage {

public PreferenceFieldEditorPageFour() {super("Page Quatre", GRID);

}protected void createFieldEditors() {

MinMaxFieldEditor bfe = new MinMaxFieldEditor("toleranc e", "Tolérence", 3,getFieldEditorParent());

addField(bfe);}

}

PreferencePersoFieldEditorExample.java du projet PreferenceExamples

PreferencePersoFieldEditorPageFour.java du projet PreferenceExamples

Page 66: Composants additionnels avec JFace

66JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : FieldEditor personnalisé

� Exemple : espaces entre FieldEditorsPreferencePersoFieldEditorPageTwo.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

Page 67: Composants additionnels avec JFace

67JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/Preference : FieldEditor personnalisé

� Exemple (suite) : espaces entre FieldEditorspublic 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 = nu mColumns;}protected void doFillIntoGrid(Composite parent, int numC olumns) {

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 projetPreferenceExamples

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

Page 68: Composants additionnels avec JFace

68JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.comJFace/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(getFie ldEditorParent(), 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 projetPreferenceExamples

PreferenceFieldEditorPageThree.java du projet PreferenceExamples

Entre chaque FieldEditor un SpacerFieldEditor pour ajouter un

espace horizontal

Un SpacerFieldEditorest un LabelFieldEditorsans valeur de texte

Page 69: Composants additionnels avec JFace

69JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 unesorte 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)

Page 70: Composants additionnels avec JFace

70JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Resource : ImageDescriptor

� Exemple : afficher une image via un ImageDescriptorpackage 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.ImageDescriptorExamp le.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 projetResourceExamples

L’image est localisée dans un sous répertoire imagequi est à la racine du sous package resourceexamples

Création d’un Image à partir d’un ImageDescriptor

Page 71: Composants additionnels avec JFace

71JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

JFace/Resource : Resource

� Lors de la conception d’interfaces utilisateurs, il est souventnécessaire de réutiliser des mêmes ressources : couleurs,fontes, images, ressources bundles

� JFaceResources fournit un mécanisme pour la déclaration deressources dans des registres et de les appeler par un nom

� Chaque type de ressource est défini dans un registre dont lesaccè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 duregistre ColorRegistry

� put(String id, RGB colorData) : ajouter une couleur au registre

� Color get(String id) : accesseur sur la couleur identifiée par id

Page 72: Composants additionnels avec JFace

72JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 definitionColorRegistry 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 definitionFontRegistry fontRegistry = JFaceResources. getFontRegistry();FontData fontData = new FontData( ARIAL_KEULKEUL_FONT, 40, SWT. BOLD);fontRegistry.put( ARIAL_KEULKEUL_FONT, new FontData[]{fontData});

// Image resources definitionImageRegistry 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

Page 73: Composants additionnels avec JFace

73JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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 t he 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 projetResourceExamples

Récupération des ressources via les registres associés

Page 74: Composants additionnels avec JFace

74JFace II - M. Baron - Page

keul

keul

.blo

gspo

t.com

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