• Like
Composants de visualisation (Viewer) avec JFace
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Composants de visualisation (Viewer) avec JFace

  • 5,899 views
Published

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
5,899
On SlideShare
0
From Embeds
0
Number of Embeds
6

Actions

Shares
Downloads
234
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Développement de clientsriches : Plateforme Eclipse Chapitre 2 : Boîtes à outilsComposants de Visualisation (Viewer) avec JFace Mickaël BARON - 2007 (Rév. Janvier 2009) mailto:baron.mickael@gmail.com ou mailto:baron@ensma.fr
  • 2. Licence Creative Commons Contrat Paternité Partage des Conditions Initiales à lIdentique 2.0 Francekeulkeul.blogspot.com http://creativecommons.org/licenses/by-sa/2.0/fr JFace I - M. Baron - Page 2
  • 3. Organisation du cours sur JFace : partie Viewers Composants de visualisation avec SWT Manipulation du modèle par le ContentProvider Manipulation du rendu par le LabelProvider Tour complet de tous les viewers Sélection Des informations complémentaires peuvent être trouvées sur mon blog Edition keulkeul.blogspot.comkeulkeul.blogspot.com Techniques de Tri et de Filtre Tous les exemples du cours sont disponibles directement à l’adresse mbaron.developpez.com/eclipse/jface1 JFace I - M. Baron - Page 3
  • 4. JFace : généralités Nous avons vu que la boîte à outils SWT fournissait un ensemble de composants graphiques de base JFace s’appuie sur la bibliothèque SWT pour fournir une API de développement plus évoluée et plus structurée Les principaux concepts proposés par JFace une abstraction des composants natifs SWTkeulkeul.blogspot.com une séparation de la partie modèle et de la vue (modèle MVC) des composants graphiques additionnels (Dialog, Preferences, …) une utilisation plus fine des ressources (Action, ImageDescriptor, …) JFace I - M. Baron - Page 4
  • 5. JFace : généralités JFace a pour fonction de simplifier les développements en SWT, sans pour autant masquer totalement SWT Nous verrons dans la suite que JFace ne cache pas complètement SWT dans les sens où il est possible d’accéder directement aux composants SWT Combinée à SWT, JFace est utilisée pour le développement d’applications pour la plateforme Eclipse La plateforme Eclipse s’appuie sur JFace et SWTkeulkeul.blogspot.com L’extension et l’encapsulation de SWT La boîte à outils connectée aux composants natifs JFace I - M. Baron - Page 5
  • 6. JFace : généralités Pré-requis : connaître Java et les principes de SWT Plan du cours JFace Les composants de visualisation (TableViewer, …) (Partie 1) Les boîtes de dialogue évoluées (Partie 2) Les préférences utilisateur (Partie 2) La gestion de ressources (ImageDescriptor, Action, …) (Partie 2) La création d’assistants (Wizards) (Partie 2) Utilisation tant que possible des nouveautés proposées par l’API Eclipse 3.3keulkeul.blogspot.com Différents articles et exemples www.eclipse.org/articles/Article-TreeViewer/TreeViewerArticle.htm wiki.eclipse.org/index.php/JFaceSnippets keulkeul.blogspot.com (mon blog perso) JFace I - M. Baron - Page 6
  • 7. JFace : installation La librairie JFace fait partie intégrante du projet Eclipse, et les binaires sont disponibles dans la distribution Eclipse Les packages JFace sont préfixés par org.eclipse.jface Les viewers : org.eclipse.jface.viewers Les boîtes de dialogues : org.eclipse.jface.dialogs Les préférences : org.eclipse.jface.preference Pour SWT, il faut Les ressources : org.eclipse.jface.resource télécharger l’archive Les assistants : org.eclipse.jface.wizard sur le site d’Eclipse Les sources sont également fournies avec la distributionkeulkeul.blogspot.com Eclipse Tout comme pour la boîte à outils SWT, il est possible de créer une application Java reposant sur JFace (hors application Eclipse RCP ou plugin) JFace I - M. Baron - Page 7
  • 8. JFace : configuration … La configuration présentée ci-dessous décrit l’utilisation du package viewers pour un simple projet Java Etape 1 : création d’un projet Javakeulkeul.blogspot.com Une autre configuration basée sur l’utilisation de développement de plug-in (via le PDE) sera décrite dans la partie plug-in Eclipse JFace I - M. Baron - Page 8
  • 9. JFace : configuration … (suite) Etape 2 : ajout des dépendances aux librairies JFace org.eclipse.core.commands org.eclipse.equinox.app org.eclipse.jface org.eclipse.swtkeulkeul.blogspot.com Les librairies ajoutées dans le chemin de construction ne sont pas exhaustives. Il s’agit d’un minimum pour utiliser une TableViewer JFace I - M. Baron - Page 9
  • 10. JFace / Viewers : introduction Typiquement en SWT, vous créez le composant, ajoutez des données et appelez des méthodes De ce fait il devient difficile de mettre à jour proprement les données des composants Une approche MVC (Model, View, Control) est fournie par la surcouche JFace Elle permet la séparation « stricte » entre le modèle de données et le modèle graphique Ajouter plus facilement des écouteurs (listeners) sur le modèle dekeulkeul.blogspot.com données pour notifier de ces changements Brancher plusieurs vues pour un même modèle Accéder aux autres modèles (sélection, édition, …) « Customiser » le rendu des données JFace I - M. Baron - Page 10
  • 11. JFace / Viewers : introduction L’implémentation proposée par JFace de MVC se rapproche plus du Document/Vue ou Model/View (le contrôleur étant associé à la vue) Principe de l’architecture Le modèle est l’élément principale du composant La ou les vue(s) du composant sont abonnées au modèle La modèle notifie ses vues suite à des modifications La partie Documentkeulkeul.blogspot.com La partie Modèle V (Notification des vues (En Java le vue et le après modification) contrôleur ne sont pas M dissociés) C JFace I - M. Baron - Page 11
  • 12. JFace / Viewers : introduction La boîte à outils SWT fournit des composants de visualisation qui s’appuient sur des composants du système Ces composants n’ont pas été étudiés dans le cours SWT puisqu’il semble plus important de les présenter avec leur « habillage MVC » Liste des composants de visualisation : Table : organisation des données dans un tableau Tree : organisation des données sous forme d’arbre List : organisation des données sous forme de listekeulkeul.blogspot.com A noter que le composant TableTree n’est pas un composant natif comme peut l’être Table ou Tree Le composant TableTree est un composant de type custom obtenu par composition d’un Tree et d’une JFace I - M. Baron - Page 12 Table
  • 13. JFace / Viewers : introduction Le package org.eclipse.jfaces.viewers fournit un ensemble de classes pour l’encapsulation des composants SWT Les composants de visualisation sont appelés des Viewers Le nom des classes est composé du nom de l’encapsulation SWT suivi de « Viewer » Dans la suite de ce cours, nous étudierons les composants : TreeViewer : un arbre TableViewer : un tableau ListViewer : une listekeulkeul.blogspot.com TableTreeViewer : un tableau avec un arbre sur la première colonne CheckboxTableViewer : un tableau avec des éléments à cocher CheckboxTreeViewer : un arbre avec des éléments à cocher ComboViewer : une boite à valeurs JFace I - M. Baron - Page 13
  • 14. JFace / Viewers : introduction TreeViewer TableViewerkeulkeul.blogspot.com TableTreeViewer (TreeViewer avec colonnes) JFace I - M. Baron - Page 14
  • 15. JFace / Viewers : introduction CheckboxTableViewer ComboViewer ListViewer CheckboxTreeViewerkeulkeul.blogspot.com JFace I - M. Baron - Page 15
  • 16. JFace / Viewers : composants natifs Nous allons nous intéresser à présenter, avant la description des viewers, les composants natifs de visualisation Composants présentés : Table, Tree, ComboBox Nous ferons uniquement une présentation des concepts nécessaires pour la suite (plus de détail voir API SWT) L’intérêt ? Même si les viewers fournissent une abstraction des composants natifs, il est souvent utile d’accéder aux composants natifs pour : Modifier le nom d’une colonne (TableColumn)keulkeul.blogspot.com Modifier l’agencement d’un viewer (setLayoutData(…)) Pourquoi pas au niveau du cours SWT ? Redondant avec cette partie car au final il est plus flexible d’utiliser les composants de visualisation par l’API JFaceJFace I - M. Baron - Page 16
  • 17. JFace / Viewers : Table Un composant Table est construit suivant le principe des composants SWT Table(Composite p, int style) : construction à partir d’un parent et d’un style Différents styles disponibles SINGLE, MULTI, FULL_SELECTION, HIDE_SELECTION : concerne le type de sélection autorisée (FULL_SELECTION = ligne complète) CHECK : la première colonne contient une boîte à cocher VIRTUAL : pour afficher de nombreuses lignes (à voir plus tard) Un composant Table est composé de colonnes décrites par la classe TableColumnkeulkeul.blogspot.com de lignes décrites par la classe TableItem TableColumn et TableItem hérite de la classe Item qui rappelons-le (voir cours SWT) s’occupe de gérer une image et un texte JFace I - M. Baron - Page 17
  • 18. JFace / Viewers : Table La classe TableColumn décrit une colonne TableColumn(Table parent, int style) : préciser l’objet parent Table et un style Le style donne la position du contenu : LEFT, RIGHT et CENTER Un objet TableColumn peut être vu comme un composant label dans le sens où il peut afficher du texte et une image Les valeurs à afficher sont transmises par l’intermédiaire des modifieurs setText(String p) et setImage(Image i) De nombreuses autres informations peuvent être renseignées setMoveable/Resizable(boolean p) : colonne déplaçablekeulkeul.blogspot.com setResizable(boolean p) : colonne redimensionnable setToolTipText(String p) : modifier valeur de la bulle d’aide setWidth(int width) : modifier largeur de la colonne addSelectionListener(SelectionListener sl) : ajouter un écouteur sur la sélection JFace I - M. Baron - Page 18
  • 19. JFace / Viewers : Table Exemple : une table et ses colonnes public class TableColumnExample { public TableColumnExample() { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Exemple de la Table SWT"); shell.setLayout(new FillLayout()); Table table = new Table(shell, SWT.NONE); table.setHeaderVisible(true); Construction de trois colonnes for (int i = 0; i < 3; i++) { TableColumn column = new TableColumn(table, SWT.NONE); column.setWidth(100); Fixe la largeur column.setText("Colonnne " + i); column.setMoveable(true); column.setResizable(true); }keulkeul.blogspot.com ... } Les colonnes sont ... déplaçables et } redimensionnables TableColumnExample.java Il manque les du projet TableExamples cellules !! JFace I - M. Baron - Page 19
  • 20. JFace / Viewers : Table La classe TableItem représente une ligne d’un tableau et peut être vu comme un ensemble de labels (cellule = Label) TableItem(Table parent, int style) : préciser le parent Table et un style Pas de style particulier, mais tout autre style qui s’applique à un Label Possibilité de modifier pour chaque cellule du TableItem le texte et l’image setImage(int i, Image im) ou setImage(Image[] im) setText(int i, String s) ou setText(String[] es) Contrairement à TableColumn, TableItem fournit des méthodes pour modifier l’apparence d’une cellulekeulkeul.blogspot.com setForeground(int i, Color c) et setBackground(int i, Color c) : modifi- cation de la couleur de fond et du dessus setFont(int i, Font f) : modification de la fonte pour une cellule donnée setChecked(boolean b) : état de la boite à cocher uniquement pour la première colonne JFace I - M. Baron - Page 20
  • 21. JFace / Viewers : Table Exemple : une table, ses colonnes et ses lignes public class TableRowColumnExample { Construction de 50 public TableRowColumnExample() { lignes ... for (int i = 0; i < 50; i++) { new TableItem(table, SWT.NONE); } Couleur de fond des cellules différente selon la « parité » TableItem[] items = table.getItems(); for (int i = 0; i < items.length; i++) { int backgroundColor = (i % 2 == 0 ? SWT.COLOR_CYAN : SWT.COLOR_RED); items[i].setBackground(Display.getDefault().getSystemColor(backgroundColor)); for (int j = 0 ; j < 3 ; j++) { items[i].setText(j, "cellule " + j + ":" + i); } } Modification du contenu de la ...keulkeul.blogspot.com } cellule de la ligne i de la colonne j ... } TableRowColumnExample.java du projet TableExamples JFace I - M. Baron - Page 21
  • 22. JFace / Viewers : Table Le composant Table fournit un ensemble de méthodes pour Modifier la sélection setSelection(int index) : sélectionne un seul élément setSelection(int[] indices) : sélectionne un ensemble d’élément Accéder aux TableColumn et TableItem TableColumn getColumn(int i) : accesseur sur un TableColumn TableItem getItem(int i) : accesseur sur un TableItem TableItem getItem(Point p) : accesseur sur un TableItem à un emplacement donné (x et y relatif au composant Table) Customiser l’apparence graphique setHeaderVisible(boolean s) : affiche ou pas les en-têtes des colonneskeulkeul.blogspot.com setLinesVisible(boolean s) : affiche ou pas les lignes de la table Effectuer des traitements sur le contenu setTopIndex(int i) : positionne l’élément i en tête de la table clear(int i) : efface le contenu d’une ligne JFace I - M. Baron - Page 22
  • 23. JFace / Viewers : Table Exemple (suite) : une table, ses colonnes et ses lignes public class AdvancedTableRowColumnExample { Active la sélection multiple public AdvancedTableRowColumnExample() { et la sélection de la ligne ... complète Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION); ... table.setHeaderVisible(true); Positionner la ligne 20 table.setLinesVisible(true); en haut de la table Sélectionne les lignes 22 et 25 table.setTopIndex(20); int[] selectedIndex = {22, 25}; table.setSelection(selectedIndex); table.clear(23); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch())keulkeul.blogspot.com display.sleep(); } display.dispose(); Efface le contenu de la } ligne 23 (suppression ... du texte) } AdvancedTableRowColumnExample du projet TableExamples JFace I - M. Baron - Page 23
  • 24. JFace / Viewers : Tree Un composant Tree est construit suivant le principe des composants SWT Tree(Composite p, int style) : construction à partir d’un parent et d’un style Les différents styles disponibles sont les mêmes que ceux utilisés pour le composant Table Un composant Tree est composé de colonnes décrites par la classe TreeColumnkeulkeul.blogspot.com de lignes décrites par la classe TreeItem TreeColumn et TreeItem hérite de la classe Item qui (voir cours SWT) s’occupe de gérer une image et un texte JFace I - M. Baron - Page 24
  • 25. JFace / Viewers : Tree La classe TreeColumn décrit une colonne et possède les mêmes fonctionnalités que la classe TableColumn Plusieurs colonnes Un arbre contenant des noeuds sur la colonne 1 Chaque item désigne une ligne (1 nœud + plusieurs cellules)keulkeul.blogspot.com Depuis la version 3.1, possibilité d’avoir plusieurs colonnes pour un composant Tree, ceci permet de remplacer le compo- sant TableTree devenu « déprécié » JFace I - M. Baron - Page 25
  • 26. JFace / Viewers : Tree La classe TreeItem désigne une ligne contenant des cellules Chaque cellule peut être vue comme un ensemble de labels Une cellule du TreeItem contient un nœud de l’arbre les autres sont considérées comme des cellules d’une table A la différence des TableItem, les TreeItem peuvent contenir d’autres TreeItem (un nœud peut contenir des sous nœuds) TreeItem(Tree parent, int style) : préciser le parent Tree et un style TreeItem(TreeItem parentItem, int style) : précise le nœud parent Possibilité de modifier pour chaque cellule du TreeItem lekeulkeul.blogspot.com texte et l’image Possibilité de déplier le contenu d’un nœud setExpanded(boolean expanded) : si expanded est vrai, le nœud est déplié JFace I - M. Baron - Page 26
  • 27. JFace / Viewers : Tree Exemple : un arbre et ses noeuds public class TreeExample { public TreeExample() { ... Les nœuds Tree myTree = new Tree(shell, SWT.FULL_SELECTION); parents x4 final int ROW = 4; for (int i = 0; i < ROW; i++) { TreeItem current = new TreeItem(myTree, SWT.NONE); Les sous nœuds current.setText("Noeud " + i); parents x3 final int SUB_ROW = 3; for (int j = 0; j < SUB_ROW; j++) { TreeItem subCurrent = new TreeItem(current, SWT.NONE); subCurrent.setText("Sous Noeud " + j); } } shell.open(); ...keulkeul.blogspot.com } ... } TreeExample du projet TreeExamples JFace I - M. Baron - Page 27
  • 28. JFace / Viewers : Tree Exemple (suite) : un arbre, ses colonnes et ses noeuds public class TreeColumnExample { public TreeColumnExample() { ... Tree myTree = new Tree(shell, SWT.FULL_SELECTION); TreeColumn column = new TreeColumn(myTree, SWT.NONE); column.setText("Colonne 1"); column.setResizable(true); column.setMoveable(true); column.setWidth(100); Création des colonnes ... final int ROW = 4; for (int i = 0; i < ROW; i++) { TreeItem current = new TreeItem(myTree, SWT.NONE); current.setText("Noeud " + i); final int SUB_ROW = 3; for (int j = 0; j < SUB_ROW; j++) { TreeItem subCurrent = new TreeItem(current, SWT.NONE); subCurrent.setText("Sous Noeud " + j);keulkeul.blogspot.com subCurrent.setText(1, "valeur 1 " + j); subCurrent.setText(2, "valeur 2 " + j); } } shell.open(); ... } TreeColonneExample du projet ... } TreeExamples JFace I - M. Baron - Page 28
  • 29. JFace / Viewers : Tree Le composant Tree fournit un ensemble de méthodes pour Modifier la sélection setSelection(TreeItem index) : sélectionne un seul élément setSelection(TreeItem[] indices) : sélectionne un ensemble d’élément Accéder aux TableColumn et TableItem TreeColumn getColumn(int i) : accesseur sur un TreeColumn TreeItem getItem(int i) : accesseur sur un TreeItem Customiser l’apparence graphique setHeaderVisible(boolean s) : affiche ou pas les en-têtes des colonnes setLinesVisible(boolean s) : affiche ou pas les lignes de la tablekeulkeul.blogspot.com Effectuer des traitements sur le contenu setTopItem(TreeItem i) : positionne l’élément i en tête de la table clear(int i, boolean a) : efface le contenu d’une ligne, si a est vraie les sous nœuds sont supprimés JFace I - M. Baron - Page 29
  • 30. JFace / Viewers : Tree Exemple (suite) : un arbre, ses colonnes et ses noeuds public class TreeColumnSelectionExample { public TreeColumnSelectionExample() { ... Tree myTree = new Tree(shell, SWT.FULL_SELECTION); ... final int ROW = 4; for (int i = 0; i < ROW; i++) { TreeItem current = new TreeItem(myTree, SWT.NONE); for (int j = 0; j < SUB_ROW; j++) { ... } Afficher le nœud 5 en } haut du Tree myTree.setTopItem(myTree.getItem(5)); myTree.setSelection(myTree.getItem(5)); myTree.getItem(5).setExpanded(true);keulkeul.blogspot.com Modifier la sélection shell.open(); sur le nœud 5 ... } Déplier le nœud 5 ... } TreeColonneSelectionExample du projet TreeExamples JFace I - M. Baron - Page 30
  • 31. JFace / Viewers : Viewer Un composant Viewer est organisé autour de trois concepts Input Objet métier qui sera affiché par le Viewer Il peut s’agir d’un simple objet (une liste de String par exemple) ou d’un objet « structurée » ContentProvider Adaptation des données de l’Input pour le type du Viewer Remarque : notifié si l’input est modifié LabelProviderkeulkeul.blogspot.com S’intéresse au rendu de chaque élément transmis par ContentProvider Peut fournir du texte ou des images Ces concepts seront étudiées très succinctement puis détaillés pour chaque composant Viewer JFace I - M. Baron - Page 31
  • 32. Person JFace / Viewers : Viewer - name : String - firstName : String Transmission -… des données à Concept stockant les Les données sont transmises pour + getName() : String l’Input données à afficher structuration + getFirstName() : String (Initialisation) getElements(myList) +… Input Input List<Person> List<Person> ContentProvider myList 1 2 ContentProvider List<Person> myList Person[] 3 IStructuredContentProvider Les données à afficher par la table 6 "Dupont" TableViewer TableViewer Les données sont Transmission pour structurées : Person[]chaque TableItem de Le viewer centralise les Pour chaque ligne et chaque colonne Person, 0la table d’une chaîne "Dupont" appels aux différents transmission d’un objet Person et de de caractères concepts l’indice de colonne concernékeulkeul.blogspot.com getColumnText(Person, i) Table Table 4 LabelProvider LabelProvider 5 ITableLabelProvider Retour pour appel à getColumnText(…) d’une chaîne à afficher dans la cellule : String JFace I - M. Baron - Page 32
  • 33. JFace / Viewers : Viewer Hiérarchie des principaux Viewers En charge de gérer le Gestion des composants de LabelProvider, le texte. Non étudiés dans ce Viewer ContentProvider et cours l’Input En charge de ContentViewer TextViewer gérer le tri et le filtre En charge des Viewers Classe qui décrit le contenant des StructuredViewer colonnes (new 3.3) … comportement de viewers de type Liste En charge des En charge des viewers ColumnViewer viewers de type de type Table (new 3.3) Arbre (new 3.3) AbstractListViewerkeulkeul.blogspot.com AbstractTableViewer AbstractTreeViewer ListViewer TreeViewer TableViewer ComboViewer JFace I - M. Baron - Page 33
  • 34. JFace / Viewers : un exemple pour débuter Exemple : TableViewer et ses trois concepts Cinq colonneskeulkeul.blogspot.com Un objet Person contenant un nom, un prénom, un sport, un age et une TableViewerExample.java du projet habitude alimentaire TableViewerExamples JFace I - M. Baron - Page 34
  • 35. JFace / Viewers : un exemple pour débuter Exemple (suite) : TableViewer et ses trois concepts public class Person { private String name; private String firstName; Cinq propriétés private String sportName; private int old; private boolean vegetarian; public Person(String name, String firstName, String sportName, int years, boolean vegetarian) { this.name = name; this.firstName = firstName; this.sportName = sportName; this.old = years; this.vegetarian = vegetarian; } public String getName() { return name;keulkeul.blogspot.com } public void setName(String name) { Cinq modifieurs et this.name = name; accesseurs } ... Person.java du projet } TableViewerExamples JFace I - M. Baron - Page 35
  • 36. JFace / Viewers : un exemple pour débuter Exemple (suite) : TableViewer et ses trois concepts public class TableViewerExample { public TableViewerExample() { Display display = new Display(); Shell shell = new Shell(display); TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); ... viewer.setContentProvider(new MyStructuredContentProvider()); viewer.setLabelProvider(new MyTableLabelProvider()); List<Person> myPersonList = new ArrayList<Person>(); myPersonList... viewer.setInput(myPersonList); Table table = viewer.getTable(); Concept : Input new TableColumn(table, SWT.CENTER).setText("Nom"); new TableColumn(table, SWT.CENTER).setText("Prénom"); new TableColumn(table, SWT.CENTER).setText("Sport"); ... for (int i = 0; i < n; i++) {keulkeul.blogspot.com table.getColumn(i).setWidth(100); } shell.open(); La description détaillée de }... ... TableViewer sera réalisée dans la suite du cours TableViewerExample.java du projet TableViewerExamples JFace I - M. Baron - Page 36
  • 37. JFace / Viewers : un exemple pour débuter Exemple (suite) : TableViewer et ses trois concepts static class MyStructuredContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { ArrayList<Person> localInputElement = (ArrayList<Person>)inputElement; return localInputElement.toArray(); } Concept : ContentProvider } static class MyTableLP extends BaseLabelProvider implements ITableLabelProvider { public String getColumnText(Object element, int columnIndex) { Person currentPerson = (Person)element; switch(columnIndex) { case 0 : return currentPerson.getName(); Concept : LabelProvider case 1 : return currentPerson.getFirstName(); case 2 : return currentPerson.getSportName(); case 3 : return Integer.toString(currentPerson.getOld()); case 4 : return Boolean.toString(currentPerson.isVegetarian()); default : return ""; } }keulkeul.blogspot.com public Image getColumnImage(Object element, int columnIndex) { return null; } } TableViewerExample.java du projet TableViewerExamples JFace I - M. Baron - Page 37
  • 38. JFace / Viewers : ContentProvider Le rôle du ContentProvider est de fournir une adaptation des données du modèle (fournies par Input) pour un type de Viewer (TableViewer, TreeViewer, …) Un ContentProvider générique est décrit par l’interface IContentProvider L’interface IContentProvider fournit une seule méthode void inputChanged(Viewer, Object oldInput, Object newInput) : en charge de notifier le ContentProvider si les données du modèle (Input) ont changékeulkeul.blogspot.com La méthode setContentProvider(IContentProvider) permet d’associer un ContentProvider avec un Viewer De façon générale vous n’aurez pas à implémenter directe- ment l’interface IContentProvider JFace I - M. Baron - Page 38
  • 39. JFace / Viewers : ContentProvider Selon le Viewer utilisé, l’API fournit des ContentProvider défini par des interfaces assurant les fonctionnalités des viewers concernés La méthode assertContentProvider(IContentProvider) s’assure que le IContentProvider fourni à la vue est du bon type La méthode assert est protected et ne peut être accessible directement Dans le cas où vous implémentez une mauvaise interface, le viewer n’affiche aucune informationkeulkeul.blogspot.com A noter que l’API fournit des implémentations « toutes prêtes » offrant des fonctionnalités directement utilisables Dans la suite, nous nous occuperons de nos propres implémentations de IContentProvider JFace I - M. Baron - Page 39
  • 40. JFace / Viewers : ContentProvider Nous fournissons ci-dessous un récapitulatif facilitant le choix de l’interface à implémenter pour les viewers étudiés IStructuredContentProvider : TableViewer, CheckboxTableViewer, ListViewer ILazyContentProvider : TableViewer, CheckboxTableViewer ITreeContentProvider : TreeViewer, CheckboxTreeViewer ILazyTreeContentProvider : TreeViewer, CheckboxTreeViewer ITreePathContentProvider : TreeViewer, CheckboxTreeViewer …keulkeul.blogspot.com Seront étudiées en priorité les interfaces ITreeContentProvider et IStructuredContentProvider Il existe d’autres interfaces de type ContentProvider qui ne seront pas étudiées dans ce cours JFace I - M. Baron - Page 40
  • 41. JFace / Viewers : ContentProvider Hiérarchie des principales interfaces ContentProvider Quand le nombre Quand le nombre IContentProvider d’éléments d’un arbre d’éléments est inconnu est inconnu ILazyContentProvider ILazyTreeContentProvider Permet de connaître le … IStructuredContentProvider nombre d’éléments (lignes, racines, …) Et pleins d’autres encore …keulkeul.blogspot.com ITreePathContentProvider ITreeContentProvider Lazy pour Lazy Loading signifie que Permet de connaître la relation entre l’élément considéré n’est chargé qu’au élément et son père et vice-et-versa moment où il est effectivement utilisé JFace I - M. Baron - Page 41
  • 42. JFace / Viewers : ContentProvider L’interface IStructuredContentProvider peut être considérée comme le point de départ de l’utilisation des Viewers IStructuredContentProvider fournit une API pour connaître le nombre d’éléments d’un viewer Nombre de lignes d’un tableau (TableViewer) Nombre d’éléments d’une liste (ListViewer) Nombre d’éléments racine d’un arbre (élément ne possédant pas de père) (TreeViewer) Cette interface propose une seule méthodekeulkeul.blogspot.com Object[] getElements(Object inputElement) : retourne toutes les lignes à afficher Le paramètre inputElement est donné par l’objet input du composant viewer JFace I - M. Baron - Page 42
  • 43. JFace / Viewers : ContentProvider Exemple : TableViewer et IStructuredContentProvider public class TableViewerExample { public TableViewerExample() { Display display = new Display(); Shell shell = new Shell(display); TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); ... viewer.setContentProvider(new MyStructuredContentProvider()); List<Person> myPersonList = new ArrayList<Person>(); myPersonList... viewer.setInput(myPersonList); TableViewerExample.java ... du projet } TableViewerExamples L’input est de type List<Person> static class MyStructuredContentProvider implements IStructuredContentProvider {keulkeul.blogspot.com public Object[] getElements(Object inputElement) { ArrayList<Person> localInputElement = (ArrayList<Person>)inputElement; return localInputElement.toArray(); } } L’input est transmis en ... En retour de cette méthode, il faut transmettre paramètre de getElements(…) } les lignes du tableau qui seront affichées JFace I - M. Baron - Page 43
  • 44. JFace / Viewers : LabelProvider Nous avons vu que le rôle du ContentProvider était de fournir les objets du modèle (Input) au Viewer Le rôle du LabelProvider est d’effectuer un rendu de chaque élément transmis par le ContentProvider Ce rendu s’effectue via un composant de type label qui permet d’afficher une image et un texte Rendu de la cellule Ici un label sans Colonne d’un obtenu par un label l’affichage de TableViewer (Image + Texte) l’imagekeulkeul.blogspot.com L’API proposée par JFace n’est pas aussi souple que celle de Swing pour la gestion du rendu des éléments d’un viewer Nous verrons dans les exemples proposés que des solutions « bricolages » existent JFace I - M. Baron - Page 44
  • 45. JFace / Viewers : LabelProvider Un LabelProvider générique est défini par l’interface IBaseLabelProvider qui ne propose rien d’exceptionnelle Une implémentation par défaut de IBaseLabelProvider est fournie par la classe BaseLabelProvider Hiérarchie des principales interfaces LabelProvider Utilisée pour les viewers de type LabelProvider adapté IBaseLabelProvider StructuredViewer comme pour les composants de TreeViewer sauf TableViewer type TableViewer ILabelProvider ITableLabelProviderkeulkeul.blogspot.com ITreePathLabelProvider IViewerLabelProvider Ajoute une méthode updateLabel Ajoute une méthode updateLabel spécialiser dans la mise à jour de chemin spécialiser dans la mise à jour pour un TreeViewer (à voir plus tard) d’élément (à voir plus tard) JFace I - M. Baron - Page 45
  • 46. JFace / Viewers : LabelProvider L’interface ILabelProvider permet d’afficher une image et un texte pour un élément d’un Viewer (excepté le TableViewer) Rappelons qu’un élément peut correspondre à une ligne d’une liste, à un nœud d’un arbre, … L’interface possède deux méthodes : Image getImage(Object element) : affichage d’un objet Image String getText(Object element) : affichage d’un texte Le paramètre element correspond à un élément transmis parkeulkeul.blogspot.com le ContentProvider (exemple : un objet de type Person) A noter que pour supprimer l’affichage du texte ou d’une image, il faut retourner null JFace I - M. Baron - Page 46
  • 47. JFace / Viewers : LabelProvider L’interface ITableLabelProvider fournit du texte/image pour chaque colonne d’un élément donné pour un TableViewer L’interface possède deux méthodes : Image getColumnImage(Object element, int columnIndex) : retourne une image pour une colonne et un élément donnés String getColumnText(Object element, int columnIndex) : retourne un texte pour une colonne et un élément donnés Concernant l’exemple, element est de type Person. Il faudra donc en fonction de la valeur de columnIndex retourner dekeulkeul.blogspot.com l’attribut adéquate de l’objet Person La méthode getColumnImage(…) sera appelée autant de fois qu’il y a de lignes JFace I - M. Baron - Page 47
  • 48. JFace / Viewers : LabelProvider Depuis l’API Eclipse 3.3, il est possible d’associer à un viewer un LabelProvider unique pour toutes les colonnes (avant 3.3) un LabelProvider différent pour chaque colonne (depuis 3.3) Cette nouvelle API permet donc de paramétrer plus finement le rendu des différents éléments Ceci a été rendu possible par l’ajout de ColumnViewer Concernant la modification du LabelProvider unique pourkeulkeul.blogspot.com toutes les colonnes, ColumnViewer fournit une méthode setLabelProvider(IBaseLabelProvider p) : associer un LabelProvider à toutes les colonnes JFace I - M. Baron - Page 48
  • 49. JFace / Viewers : LabelProvider Exemple : un LabelProvider pour toutes les colonnes public class TableViewerExample { public TableViewerExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setLabelProvider(new MyTableLabelProvider()); ... } Implémentation par défaut de ... IBaseLabelProvider class MyTableLP extends BaseLabelProvider implements ITableLabelProvider { public String getColumnText(Object element, int columnIndex) { Person currentPerson = (Person)element; Selon la valeur de switch(columnIndex) { columnIndex on case 0 : return currentPerson.getName(); case 1 : return currentPerson.getFirstName(); sélectionne l’attribut à case 2 : return currentPerson.getSportName(); afficher case 3 : return Integer.toString(currentPerson.getOld()); case 4 : return Boolean.toString(currentPerson.isVegetarian()); default : return "";keulkeul.blogspot.com } } public Image getColumnImage(Object element, int columnIndex) { return null; } }} N’affiche pas d’image TableViewerExample.java du projet TableViewerExamples JFace I - M. Baron - Page 49
  • 50. JFace / Viewers : LabelProvider Pour la gestion de l’affichage de l’en-tête de la table il faut passer par les objets natifs TableColumn Exemple : un LabelProvider pour toutes les colonnes public class TableViewerExample { public TableViewerExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setLabelProvider(new MyTableLabelProvider()); Table table = viewer.getTable(); new TableColumn(table, SWT.CENTER).setText("Nom"); new TableColumn(table, SWT.CENTER).setText("Prénom"); new TableColumn(table, SWT.CENTER).setText("Sport"); new TableColumn(table, SWT.CENTER).setText("Age"); new TableColumn(table, SWT.CENTER).setText("Végétarien"); for (int i = 0; i < n; i++) { Nécessite de construire deskeulkeul.blogspot.com table.getColumn(i).setWidth(100); } TableColumn pour ... paramétrer chaque en-tête } ... de colonne } TableViewerExample.java du projet TableViewerExamples JFace I - M. Baron - Page 50
  • 51. JFace / Viewers : LabelProvider Les LabelProviders peuvent être différents pour chaque colonne (nouveauté Eclipse 3.3) Ne concerne que les composants de type ColumnViewer, c’est-à-dire les composants TableViewer et TreeViewer La classe abstraite ViewerColumn s’occupe de représenter une colonne d’un composant ColumnViewer setLabelProvider(CellLabelProvider clp) : modifie le LabelProvider pour une colonnekeulkeul.blogspot.com setEditingSupport(EditingSupport es) : modification de l’éditeur (à voir plus tard) CellLabelProvider, qui hérite de BaseLabelProvider, est une nouveauté 3.3 JFace I - M. Baron - Page 51
  • 52. JFace / Viewers : LabelProvider Selon le composant ColumnViewer utilisé (TableViewer ou TreeViewer) l’API fournit respectivement deux sous classes à ViewerColumn TableViewerColumn pour associer un LabelProvider à une colonne d’un TableViewer TreeViewerColumn pour associer un LabelProvider à une colonne d’un TreeViewer Le principe d’utilisation entre ces deux classes reste le mêmekeulkeul.blogspot.com Nous détaillerons donc TableViewerColumn puis pour TreeViewerColumn nous donnerons simplement des exemples JFace I - M. Baron - Page 52
  • 53. JFace / Viewers : LabelProvider Un TableViewerColumn fournit une seule méthode permet- tant d’accéder au composant natif décrivant une colonne TableColumn getColumn() : accesseur sur une colonne d’une Table Rappelons qu’un TableColumn décrit « nativement » une colonne d’un objet Table (Table contient n TableColumn) L’accès à TableColumn va permettre de paramétrer le contenu de la colonne (un nom, une image, une dimension) La construction d’un TableViewerColumn précisera qu’une nouvelle colonne doit être associer à un TableViewerkeulkeul.blogspot.com Nativement, cela revient à associer un TableColumn avec un objet Table Par conséquent, il n’est pas possible de supprimer des colon- nes sans reconstruire l’objet TableViewer JFace I - M. Baron - Page 53
  • 54. JFace / Viewers : LabelProvider Différents constructeurs pour la classe TableViewerColumn TableViewerColumn(TableViewer tv, int style) : construit une colonne avec un style (associer un nouveau TableColumn avec une Table) TableViewerColumn(TableViewer tv, int style, int index) : même chose avec la possibilité de choisir l’index de la nouvelle colonne dans la table Le style de la colonne précise l’emplacement du texte dans la colonne (LEFT, RIGHT et CENTER) Démarche pour utiliser un LabelProvider différent pour chaque colonnekeulkeul.blogspot.com Construire le TableViewer Construire et paramétrer (nom et taille par exemple) toutes les colon- nes via un TableViewerColumn A partir de chaque référence des TableViewerColumn, associer un LabelProvider unique JFace I - M. Baron - Page 54
  • 55. JFace / Viewers : LabelProvider Exemple : un LabelProvider pour chaque colonne public class TableViewerColumnExample { public TableViewerColumnExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyStructuredContentProvider()); TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { ... } Un LabelProvider par column.getColumn().setText("Nom"); colonne (à voir après) column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { ... } column.getColumn().setText("Sport"); ... Modification de l’en- tête de la colonnekeulkeul.blogspot.com viewer.setInput(myPersonList); Table table = viewer.getTable(); table.setLayoutData(new GridData(GridData.FILL_BOTH)); ... Nécessite toujours de } manipuler le composant } natif Table TableViewerColumnExample.java du projet TableViewerExamples JFace I - M. Baron - Page 55
  • 56. JFace / Viewers : LabelProvider Un objet ViewerColumn manipule un LabelProvider de type CellLabelProvider (qui hérite de BaseLabelProvider) Le rôle de CellLabelProvider est de fournir des méthodes pour la manipulation des bulles d’aides de type Color getToolTipBackgroundColor(Object objet) : retourne la couleur du fond de la bulle d’aide String getToolTipText(Object element) : retourne le texte contenu dans la bulle d’aide int getTooltipDisplayDelayTime(Object element) : durée qu’il faut pour afficher la bulle d’aide boolean useNativeToolTip(Object object) : indique si les bulles d’aideskeulkeul.blogspot.com natives doivent être utilisées Pour utiliser les bulles d’aides il faut les activer … ColumnViewerToolTipSupport.enableFor(myViewer, ToolTip.NO_RECREATE) Activation des bulles d’aides pour un viewer donné JFace I - M. Baron - Page 56
  • 57. JFace / Viewers : LabelProvider CellLabelProvider est abstraite, deux classes concrètes sont fournies par l’API ColumnLabelProvider : LabelProvider spécifique à une colonne OwnerDrawLabelProvider : LabelProvider pour dessiner le contenu ColumnLabelProvider fournit des méthodes pour modifier Color getBackground(Object element) : la couleur de fond Color getForeground(Object element) : la couleur de l’avantkeulkeul.blogspot.com Font getFont(Object element) : la fonte Image getImage(Object element) : l’image (si null = d’image) String getText(Object element) : le texte JFace I - M. Baron - Page 57
  • 58. JFace / Viewers : LabelProvider Exemple (suite) : LabelProvider pour chaque colonne Cinq colonnes qui ont chacune un LabelProvider La couleur de fond de cette colonne est différente des autreskeulkeul.blogspot.com TableViewerColumnExample.java du projet TableViewerExamples JFace I - M. Baron - Page 58
  • 59. JFace / Viewers : LabelProvider Exemple (suite) : LabelProvider pour chaque colonne public class TableViewerColumnExample { public TableViewerColumnExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyStructuredContentProvider()); TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { public Color getBackground(Object element) { return Display.getDefault().getSystemColor(SWT.COLOR_GREEN); } public String getText(Object element) { Person currentPerson = (Person)element; Modifie la couleur de return currentPerson.getName(); } fond de la première } colonne column.getColumn().setText("Nom"); column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { Retourne le texte àkeulkeul.blogspot.com Person currentPerson = (Person)element; return currentPerson.getFirstName(); afficher dans la } cellule } column.getColumn().setText("Sport"); ... } TableViewerColumnExample.java } du projet TableViewerExamples JFace I - M. Baron - Page 59
  • 60. JFace / Viewers : LabelProvider Exemple (suite) : LabelProvider pour chaque colonne public class TableViewerColumnExample { public TableViewerColumnExample() { ... column.setLabelProvider(new ColumnLabelProvider() { public int getToolTipDisplayDelayTime(Object object) { return 500; } public int getToolTipTimeDisplayed(Object object) { return 5000; } public Color getToolTipBackgroundColor(Object object) { Gestion des return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); bulles d’aides } par colonne public String getToolTipText(Object element) { return "Ceci est un exemple de bulle d’aide"; } public boolean useNativeToolTip(Object object) { return false; }keulkeul.blogspot.com }); column.getColumn().setText("Végétarien"); ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE); } } N’oubliez pas d’activer les bulles d’aides TableViewerColumnExample.java via ColumnViewerToolTipSupport du projet TableViewerExamples JFace I - M. Baron - Page 60
  • 61. JFace / Viewers : LabelProvider Les LabelProvider proposés actuellement ne permettent que d’afficher du texte et/ou une image Pour dessiner dans le label (possibilité également de passer par une image), l’API 3.3 fournit OwnerDrawLabelProvider La classe abstraite OwnerDrawLabelProvider permet de « dessiner » dans le label (ex : une cellule pour une table) abstract void measure(Event event, Object e) : dimensionner le label abstract void paint(Event event, Object e) : dessiner le contenu abstract void erase(Event event, Object e) : dessiner la sélectionkeulkeul.blogspot.com static void setUpOwnerDraw(ColumnViewer viewer) : rediriger les événements du Viewer dans le LabelProvider Pour qu’un ColumnViewer prenne en compte un LabelProvider de type OwnerDrawLabelProvider, employez obligatoirement setUpOwnerDraw JFace I - M. Baron - Page 61
  • 62. JFace / Viewers : LabelProvider Exemple : dessiner le contenu des cellules public class OwnerDrawLabelExample { public OwnerDrawLabelExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new OwnerDrawLabelProvider() { protected void measure(Event event, Object element) { Person currentPerson = (Person)element; Précise la int height = event.gc.textExtent(currentPerson.getName()).y + 5; dimension du int width = event.gc.textExtent(currentPerson.getName()).x; event.setBounds(new Rectangle(0,0, width, height)); label } protected void paint(Event event, Object element) { // La suite dans le slide suivant ... } } column.getColumn().setText("Nom"); ... // Traitement des autres colonnes OwnerDrawLabelProvider.setUpOwnerDraw(viewer);keulkeul.blogspot.com } } Style, couleur et fonte différents dans un même label OwnerDrawLabelExample.java du projet TableViewerExamples JFace I - M. Baron - Page 62
  • 63. JFace / Viewers : LabelProvider Exemple (suite) : dessiner le contenu des cellules protected void paint(Event event, Object element) { Person currentPerson = (Person)element; Display display = viewer.getControl().getDisplay(); Utilisation d’un TextLayout pour TextLayout layout = new TextLayout(display); faciliter l’agencement layout.setText(currentPerson.getName()); du texte dans la cellule TextStyle plain = new TextStyle(JFaceResources .getFont(JFaceResources.DEFAULT_FONT), display .getSystemColor(SWT.COLOR_LIST_FOREGROUND), null); Précise les TextStyle italic = new TextStyle(JFaceResources.getFontRegistry() différents .getItalic(JFaceResources.DEFAULT_FONT), display styles .getSystemColor(SWT.COLOR_BLUE), null); Font newFont = new Font(display, "Arial", 9, SWT.BOLD); TextStyle font = new TextStyle(newFont, display La cellule la plus grande .getSystemColor(SWT.COLOR_WHITE), display .getSystemColor(SWT.COLOR_BLACK)); fixe la taille de toutes les autres dimensionskeulkeul.blogspot.com layout.setStyle(plain, 0, 2); layout.setStyle(italic, 3, 5); d’une même colonne layout.setStyle(font, 6, currentPerson.getName().length() - 1); layout.draw(event.gc, event.x, event.y); } OwnerDrawLabelExample.java du projet TableViewerExamples JFace I - M. Baron - Page 63
  • 64. JFace / Viewers : TableViewer Nous avons vu que le composant TableViewer permettait d’encapsuler le composant Table de l’API SWT ContentProvider autorisés IStructuredContentProvider et ILazyContentProvider LabelProvider autorisés ILabelProvider et ITableLabelProvider pour toutes les colonnes ColumnLabelProvider et OwnerDrawLabelProvider pour chaque colon- ne via le composant TableViewerColumn Différents styles sont utilisables (voir partie Table pour con- naître sont qui sont exploitables)keulkeul.blogspot.com Particulièrement le style SWT.VIRTUAL permet d’utiliser le ContentProvider ILazyContentProvider Si le style est SWT.VIRTUAL utilisez obligatoirement ILazyContentProvider au risque de lever une exception JFace I - M. Baron - Page 64
  • 65. JFace / Viewers : TableViewer Le principe du « Lazy Loading » est de ne charger en mé- moire que les objets effectivement utilisés Selon les besoins, de nouveaux objets sont alors ajoutés en mémoire Dans le cas de l’interface ILazyContentProvider seuls les objets visibles, représentés par les lignes affichées, sont pris en compte par le TableViewer Si il y a affichage de nouvelles lignes, les objets associéskeulkeul.blogspot.com sont ajoutés dans le TableViewer L’interface ILazyContentProvider contient une méthode updateElement(int index) : appelée quand une nouvelle ligne (index) est visible JFace I - M. Baron - Page 65
  • 66. JFace / Viewers : TableViewer Pour utiliser ILazyContentProvider, il faut connaître la taille des éléments à afficher AbstractTableViewer#setItemCount(int count) : précise le nombre d’élément count géré par la table A chaque nouvel objet dans la TableViewer (appelle de la méthode updateElement), prise en compte de l’objet dans la table par : AbstractTableViewer#replace(Object el, int index) : objet el à ajouter à la position indexkeulkeul.blogspot.com 12 objets ont été chargés dans la TableViewer JFace I - M. Baron - Page 66
  • 67. JFace / Viewers : TableViewer Exemple : TableViewer et ILazyContentProvider public class LazyContentProviderExample { public LazyContentProviderExample() { ... TableViewer viewer = new TableViewer(shell, SWT.VIRTUAL | SWT.FULL_SELECTION); viewer.setLabelProvider(new MyTableLabelProvider()); viewer.setContentProvider(new MyLazyContentProvider(viewer)); ... viewer.setInput(myPersonList); viewer.setItemCount(myPersonList.size()); Précise le nombre de ligne ... dans la table } static class MyLazyContentProvider implements ILazyContentProvider { private AbstractTableViewer ref; private ArrayList<Person> myPersonList; private MyLazyContentProvider(AbstractTableViewer pRef) { this.ref = pRef; } Ajoute un objet à la public void updateElement(int index) { position indexkeulkeul.blogspot.com ref.replace(myPersonList.get(index), index); } public void inputChanged(Viewer view, Object oldInput, Object newInput) { this.myPersonList = (ArrayList<Person>)newInput; } public void dispose() {} LazyContentProviderExample.java } du projet TableViewerExamples } JFace I - M. Baron - Page 67
  • 68. JFace / Viewers : TreeViewer Le composant TreeViewer permet d’encapsuler le composant Tree de l’API SWT ContentProvider autorisés ITreeContentProvider, ILazyTreeContentProvider, ITreePathContentProvider et ILazyTreePathContentProvider LabelProvider autorisés ILabelProvider pour toutes les colonnes ColumnLabelProvider et OwnerDrawLabelProvider pour chaque colon- ne via le composant TreeViewerColumnkeulkeul.blogspot.com Différents styles sont utilisables (voir partie Table pour con- naître ceux qui sont exploitables) Notons que le fait d’utiliser plusieurs TreeViewerColumn permet de construire un TableTreeViewer JFace I - M. Baron - Page 68
  • 69. JFace / Viewers : TreeViewer L’interface ITreeContentProvider est utilisée par un viewer de type arbre (Tree) Elle hérite de l’interface IStructuredContentProvider qui fournit une méthode pour déterminer le nombre d’éléments (dans ce cas, le nombre d’éléments racines) ITreeContentProvider fournit trois méthodes Object[] getChildren(Object paramElement) : retourne les enfants d’un élément donnékeulkeul.blogspot.com Object getParent(Object element) : retourne l’élément père d’un élément boolean hasChildren(Object element) : précise si l’élément est racine ou pas JFace I - M. Baron - Page 69
  • 70. JFace / Viewers : TreeViewer Exemple : TreeViewer et ITreeContentProvider public class Job { private List<Person> myPerson; Job.java du projet private String job; TreeViewerExamples public void addPerson(Person pPerson) { myPerson.add(pPerson); pPerson.setParent(this); } public List<Person> getPersons() { return myPerson; } public String getJob() { return job; }} public class Person { private String name; ... private Job parent; public Person(String pName, ...) { name = pNamae; ...keulkeul.blogspot.com } public String getName() { return name; Person.java du projet } TreeViewerExamples public void setParent(Job pJob) { this.parent = pJob; } ... } JFace I - M. Baron - Page 70
  • 71. JFace / Viewers : TreeViewer Exemple (suite) : TreeViewer et ITreeContentProvider public class TreeViewerExample { private List<Job> myPersonWork; public TreeViewerExample() { ... TreeViewer viewer = new TreeViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyTreeContentProvider()); myPersonWork = new ArrayList<Job>(); Construction d’un Job currentWork = new Job("Informaticien"); ContentProvider currentWork.addPerson(new Person("Robert Glan", "Nancy", "25", "Voiture", "1600")); currentWork.addPerson(new Person(...)); viewer.setInput(myPersonWork); ... Transformation des } données de l’Input static class MyTreeContentProvider implements ITreeContentProvider { public Object[] getElements(Object element) { final Object[] currentPersonWorks = ((List<Job>) element).toArray(); return currentPersonWorks;keulkeul.blogspot.com } public void dispose() { } public void inputChanged(Viewer v, Object belement, Object aelement) { } ... } } TreeViewerExample.java du projet TreeViewerExamples JFace I - M. Baron - Page 71
  • 72. JFace / Viewers : TreeViewer Exemple (suite) : TreeViewer et ITreeContentProvider static class MyTreeContentProvider implements ITreeContentProvider { ... public Object[] getChildren(Object element) { final Job currentPersonWork = (Job) element; Retourne les return currentPersonWork.getPersons().toArray(); nœuds enfants } public Object getParent(Object element) { if (element instanceof Person) { Retourne le parent return ((Person)element).getParent(); du nœud element } else { return null; } } public boolean hasChildren(Object element) { if (element instanceof Job) { Job current = (Job) element; Le nœud courantkeulkeul.blogspot.com return !current.isPersonEmpty(); comporte-il des sous } else return false; noeuds } } } TreeViewerExample.java du projet TreeViewerExamples JFace I - M. Baron - Page 72
  • 73. JFace / Viewers : TreeViewer Certains ContentProvider comme ITreePathContentProvider et ILazyTreePathContentProvider manipulent des éléments via des chemins TreePath Un TreePath est un chemin qui débute de la racine de l’arbre et qui termine par l’élément considéré Exemple de TreePath : « c:, windows, system, user.dll » Chaque élément du TreePath est appelé un segment Principales méthodes de la classe TreePathkeulkeul.blogspot.com Object getFirstSegment() : récupère le premier élément du chemin Object getLastSegment() : récupère le dernier élément du chemin Object getSegment(int index) : récupère un élément à un index donné int getSegmentCount() : retourne le nombre d’élément d’un chemin JFace I - M. Baron - Page 73
  • 74. JFace / Viewers : TreeViewer L’interface ITreePathContentProvider permet de gérer le ContentProvider via la notion de chemin Elle hérite de l’interface IStructuredContentProvider qui fournit une méthode pour déterminer le nombre d’éléments ITreePathContentProvider fournit trois méthodes Object[] getChildren(TreePath paramPath) : retourne les enfants du dernier élément du cheminkeulkeul.blogspot.com TreePath[] getParents(Object element) : retourne les chemins parents possibles d’un élément donné boolean hasChildren(TreePath element) : précise si le dernier élément du chemin a des enfants ou pas JFace I - M. Baron - Page 74
  • 75. JFace / Viewers : TreeViewer Exemple : TreeViewer et ITreePathContentProvider static class MyTreePathContentProvider implements ITreePathContentProvider { ... public Object[] getChildren(TreePath parentPath) { Object lastSegment = parentPath.getLastSegment(); Retourne les final Job currentPersonWork = (Job) lastSegment; nœuds enfants return currentPersonWork.getPersons().toArray(); } public TreePath[] getParents(Object element) { TreePath[] refParents = new TreePath[1]; Retourne les parents Person currentJob = (Person)element; Object[] segmentTab = {currentJob.getParent()}; du nœud element refParents[0] = new TreePath(segmentTab); return refParents; } public boolean hasChildren(TreePath path) { Object lastSegment = path.getLastSegment(); Le nœud courant if (lastSegment instanceof Job) { comporte-il des souskeulkeul.blogspot.com Job current = (Job)lastSegment; return !current.isPersonEmpty(); noeuds } else { return false; } } } TreeViewerWithPathExample.java } du projet TreeViewerExamples JFace I - M. Baron - Page 75
  • 76. JFace / Viewers : TreeViewer Exemple : TreeViewer et LabelProvider public class TreeViewerExample { private List<Job> myPersonWork; public TreeViewerExample() { ... TreeViewer viewer = new TreeViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyTreeContentProvider()); viewer.setLabelProvider(new MyTreeLabelProvider()); } static class MyTreeLabelProvider extends BaseLabelProvider implements ILabelProvider { public Image getImage(Object element) { return null; } public String getText(Object element) { if (element instanceof Person) { Person current = (Person)element; return current.getName();keulkeul.blogspot.com } else { return element.toString(); } } } TreeViewerExample.java du projet ... } TreeViewerExamples JFace I - M. Baron - Page 76
  • 77. JFace / Viewers : TreeViewer Exemple : Ouverture progressive d’un nœud IDeferredWorkbenchAdapter pour la création différée du nœud (à placer au niveau de l’objet qui modélise un nœud) DeferredTreeContentManager pour la gestion des nœuds différés (à placer dans le ContentProvider) Basé sur www.ji.com.za/unplugged/index.php?paged=4keulkeul.blogspot.com Chargement progressif de 10 noeuds JFace I - M. Baron - Page 77
  • 78. JFace / Viewers : TreeViewer Exemple (suite) : Ouverture progressive d’un nœud public class DeferredTreeContentManagerView extends ViewPart { private TreeParent invisibleRoot; C’est du LazyLoading public TreeViewerExample() { ... TreeViewer viewer = new TreeViewer(shell, SWT.VIRTUAL | SWT.FULL_SELECTION); viewer.setContentProvider(new MyTreeContentProvider()); viewer.setLabelProvider(new MyTreeLabelProvider()); TreeParent root = new TreeParent("Root"); invisibleRoot = new TreeParent(""); invisibleRoot.addChild(root); viewer.setInput(invisibleRoot); } private static class TreeObject { private String name; Nœud acceptant un private TreeObject parent; nœud parentkeulkeul.blogspot.com public TreeObject(String pName) { this.name = pName; } public void setParent(TreeObject pParent) { this.parent = parent; } } DeferredTreeContentManagerView.java ... } du projet TreeViewerExamples JFace I - M. Baron - Page 78
  • 79. JFace / Viewers : TreeViewer Exemple (suite) : Ouverture progressive d’un nœud public class DeferredTreeContentManagerView extends ViewPart { ... private static class TreeParent extends TreeObject implements IDeferredWorkbenchAdapter { private static final int leafLength = 10; Indique si cet objet private ArrayList<TreeObject> children; public TreeParent(String name) { peut avoir des super(name); enfants children = new ArrayList<TreeObject>(); } public boolean isContainer() { return (this instanceof TreeParent); } public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) { collector.add(new TreeParent("Parent"), monitor); for (int i = 0; i < leafLength; i++) { collector.add(new TreeObject("Leaf " + i), monitor); Partie progressive … try {keulkeul.blogspot.com Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public boolean hasChildren() { return children.size() > 0; } } DeferredTreeContentManagerView.java } du projet TreeViewerExamples JFace I - M. Baron - Page 79
  • 80. JFace / Viewers : TreeViewer Exemple (suite) : Ouverture progressive d’un nœud public class DeferredTreeContentManagerView extends ViewPart { ... static class MyTreeContentProvider implements ITreeContentProvider { private DeferredTreeContentManager manager; public Object[] getElements(Object element) { TreeParent myParent = (TreeParent) element; return myParent.getChildren(element); } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (viewer instanceof AbstractTreeViewer) { manager = new DeferredTreeContentManager(this,(AbstractTreeViewer) viewer); } } public Object[] getChildren(Object parentElement) { return manager.getChildren(parentElement); Si parentElement est un } public Object getParent(Object element) { « deferred element », il y a if (element instanceof TreeObject) { création d’un thread return ((TreeObject) element).getParent();keulkeul.blogspot.com } return null; } public boolean hasChildren(Object element) { Y a t il potentiellement des return manager.mayHaveChildren(element); nœuds enfants ? C’est du } LazyLoading } } DeferredTreeContentManagerView.java du projet TreeViewerExamples JFace I - M. Baron - Page 80
  • 81. JFace / Viewers : TableTreeViewer Le composant TableTreeViewer permet de mixer un arbre avec une table Tout comme TableViewer et TreeViewer, le composant TableTreeViewer possède son équivalent en natif Toutefois depuis la nouvelle API Eclipse 3.3, l’utilisation directe du composant TableTreeViewer est « Deprecated » En utilisant des TreeViewerColumn associés à un TreeViewer, il est possible d’obtenir directement un TableTreeViewerkeulkeul.blogspot.com Le mécanisme de création d’un TreeViewerColumn (la colonne) est similaire à un TableViewerColumn TableColumn est remplacé par TreeColumn Possibilité d’associer un CellLabelProvider par colonne JFace I - M. Baron - Page 81
  • 82. JFace / Viewers : TableTreeViewer Exemple : TableTreeViewer = TreeViewer + ViewerColumn public class Person { private String name; private String address; ... public Person(String pName, String pAddress, String pOld, String pVehicule, String pSalary) { name = pNamae; }keulkeul.blogspot.com public String getName() { return name; } public String getAddress() { return address; Person.java du projet } TreeViewerExamples ... } JFace I - M. Baron - Page 82
  • 83. JFace / Viewers : TableTreeViewer Exemple (suite) : TableTreeViewer public class TreeViewerColumnExample { private List<Job> myPersonWork; public TreeViewerExample() { ... TreeViewer viewer = new TreeViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyTreeContentProvider()); ... TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.CENTER); column.setLabelProvider(new ColumnLabelProvider() { public void getText(Object element) { if (element instanceof Person) { Person current = (Person)element; return current.getName(); } else { return element.toString(); // Redéfinie pour retourner le métier } } }keulkeul.blogspot.com column.getColumn().setText("Métier / Nom"); ... // Address, Old, vehicule et salaire même principe } } TreeViewerColumnExample.java du projet TreeViewerExamples JFace I - M. Baron - Page 83
  • 84. JFace / Viewers : ListViewer Le composant ListViewer permet d’encapsuler le composant List de l’API SWT ContentProvider autorisé IStructuredContentProvider LabelProvider autorisé ILabelProvider pour toutes les colonnes Le label permet d’afficher uniquement le contenu du texte.keulkeul.blogspot.com Les images ne sont pas gérées Si vous souhaitez gérer les images au niveau du label, préfé- rez l’utilisation du composant TableViewer avec une colonne JFace I - M. Baron - Page 84
  • 85. JFace / Viewers : ListViewer Exemple : ListViewer en action … public class ListViewerExample { private java.util.List<Person> myPerson = new ArrayList<Person>(); public ListViewerExample() { ... ListViewer myListViewer = new ListViewer(shell, SWT.NONE); myListViewer.setContentProvider(new MyStructuredContentProvider()); myListViewer.setLabelProvider(new MyLabelProvider()); myListViewer.setInput(myPerson); List myList = myListViewer.getList(); GridData gridData = new GridData(GridData.FILL_BOTH); myList.setLayoutData(gridData); ... } static class MyLabelProvider extends LabelProvider { public String getText(Object element) { if (element instanceof Person) { return ((Person)element).getName(); } else {keulkeul.blogspot.com return ""; } } } Affichage du texte ... } ListViewerExample.java du projet OtherViewersExamples JFace I - M. Baron - Page 85
  • 86. JFace / Viewers : ListViewer Exemple (suite) : une liste avec un TableViewer public class ListViewerWithTableViewerExample { public ListViewerWithTableViewerExample() { ... TableViewer myViewer = new TableViewer(shell, SWT.FULL_SELECTION); myListViewer.setContentProvider(new MyStructuredContentProvider()); TableViewerColumn column = new TableViewerColumn(viewer,SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { public Image getImage(Object element) { return null; } public String getText(Object element) { Possibilité d’ajouter Person currentPerson = (Person)element; des images return currentPerson.getName(); } public int getToolTipDisplayDelayTime(Object object) { return 500; } public int getToolTipTimeDisplayed(Object object) { return 5000; } public String getToolTipText(Object element) { Possibilité d’affiner return "Ceci est un exemple de bulle daide"; } le paramétrage des bulles d’aideskeulkeul.blogspot.com public boolean useNativeToolTip(Object object) { return false; } }); ColumnViewerToolTipSupport.enableFor(viewer,ToolTip.NO_RECREATE); ... } } ListViewerWithTableViewerExample.java du projet OtherViewersExamples JFace I - M. Baron - Page 86
  • 87. JFace / Viewers : ComboViewer Exemple : ComboViewer en action … public class ComboViewerExample { public ComboViewerExample() { ... ComboViewer viewer = new ComboViewer(shell, SWT.NONE); viewer.setContentProvider(new MyStructuredContentProvider()); viewer.setLabelProvider(new MyLabelProvider()); ... viewer.setInput(root); Combo myCombo = viewer.getCombo(); GridData gridData = new GridData(GridData.FILL_BOTH); myCombo.setLayoutData(gridData); ... } ... }keulkeul.blogspot.com ComboViewerExample.java du projet OtherViewersExamples JFace I - M. Baron - Page 87
  • 88. JFace / Viewers : Checkbox…Viewer Les composants CheckboxTableViewer, CheckboxTreeViewer permettent de gérer une table et un arbre avec un compo- sant CheckBox dans la première colonne Ces composants fonctionnent sur le même principe que les viewers étudiés précédemment Une écouteur sur l’état des CheckBox permet de notifier tout changementkeulkeul.blogspot.com addCheckStateListener(ICheckStateListener listener) : ajoute un écouteur ICheckStateListener#checkStateChanged(CheckStateChangedEvent) : notifie un changement d’état JFace I - M. Baron - Page 88
  • 89. JFace / Viewers : CheckboxTreeViewer Exemple : CheckboxTreeViewer en action … public class CheckBoxTreeViewerExample { public CheckBoxTreeViewerExample () { ... CheckboxTreeViewer viewer = new CheckboxTreeViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyTreeContentProvider()); viewer.setLabelProvider(new MyTreeLabelProvider()); ... viewer.setInput(root); viewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { if (event.getElement() instanceof TreeParent) { viewer.setSubtreeChecked(event.getElement(), viewer.getChecked(event.getElement())); } } CheckBoxTreeViewerExample.java du }); projet OtherViewersExamples Tree myTree = viewer.getTree(); GridData gridData = new GridData(GridData.FILL_BOTH); myTree.setLayoutData(gridData);keulkeul.blogspot.com ... } ... } Si sélection du nœud parent sélection de tous les sous noeuds JFace I - M. Baron - Page 89
  • 90. JFace / Viewers : CheckboxTableViewer Exemple : CheckboxTableViewer en action … public class CheckBoxTableViewerExample { public CheckBoxTableViewerExample () { ... CheckboxTableViewer viewer = CheckboxTableViewer.newCheckList(shell, SWT.FULL_SELECTION); myListViewer.setContentProvider(new MyStructuredContentProvider()); myListViewer.setLabelProvider(new MyTableLabelProvider()); myListViewer.setInput(root); viewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { PersonData myPersonData = (PersonData)event.getElement(); System.out.println(myPersonData.getName()); } }); Table table = viewer.getTable(); ... }keulkeul.blogspot.com ... } CheckBoxTableViewerExample.java du projet OtherViewersExamples JFace I - M. Baron - Page 90
  • 91. JFace / Viewers : sélection Pour la gestion de la sélection, possibilité de passer par : les composants natifs de la boîte à outils SWT le viewer via un objet (ISelection) Quels sont les besoins autour d’une sélection d’un viewer ? Modifier programmatiquement la sélection Récupérer la sélection courante Notifier quand une sélection se produit Il est préférable d’utiliser la solution par viewer puisqu’ellekeulkeul.blogspot.com est introduite avec l’API JFace et elle manipule des concepts propre à l’Input Nous étudions dans la suite tous les besoins en insistant sur la sélection par le viewer JFace I - M. Baron - Page 91
  • 92. JFace / Viewers : sélection via composant natif Les composants natifs SWT (Table et Tree) disposent de méthodes pour les trois besoins de sélection du composant Table (rappel) Modifier la sélection setSelection(int), setSelection(int[]), setSelection(int start, int end) setSelection(TableItem it), setSelection(TableItem[]) Récupérer la sélection TableItem[] getSelection() int getSelectionCount(), int[] getSelectionIndices(), …keulkeul.blogspot.com Notifier si changement de la sélection Pas d’écouteur défini pour avertir d’un changement de sélection L’écouteur SelectionListener notifie uniquement quand une action utilisateur se produit sur la table addSelectionListener(SelectionListener listener) JFace I - M. Baron - Page 92
  • 93. JFace / Viewers : sélection via composant natif Exemple : sélection par composant natif Si action sur la table affichage de la sélection courante Action = clique souris ou déplacement via les flèche du clavierkeulkeul.blogspot.com Modification de la sélection de manière programmatique NativeTableViewerSelectionExample.java du projet SelectionExamples JFace I - M. Baron - Page 93
  • 94. JFace / Viewers : sélection via composant natif Exemple (suite): sélection par composant natif public class NativeTableViewerSelectionExample { public NativeTableViewerSelectionExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setLabelProvider(new MyTableLabelProvider()); Récupération de la Button myButton = new Button(shell, SWT.FLAT); sélection courante myButton.addSelectionListener(new SelectionAdapter() { public void widgetDisposed(SelectionEvent e) { int selectionIndex = viewer.getTable().getSelectionIndex(); System.out.println("Ancienne Valeur : " + selectionIndex); int intemCount = viewer.getTable().getItemCount(); selectionIndex = (selectionIndex + 1) % itemCount; viewer.getTable().setSelection(selectionIndex); System.out.println("Nouvelle Valeur : " + selectionIndex); } }); viewer.getTable().addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) {keulkeul.blogspot.com System.out.println(viewer.getTable().getSelectionIndex()); } } ... } } NativeTableViewerSelectionExample.java du projet SelectionExamples JFace I - M. Baron - Page 94
  • 95. JFace / Viewers : sélection Remarquons que la gestion de la sélection via le composant natif implique une utilisation de concepts différents que ceux manipulés par l’Input Par exemple, avec le composant natif Table, le programmeur manipule des int et des TableItem Il serait plus pratique de pouvoir maîtriser directement les objets gérés par l’Input (exemple un objet Person) Modifier une sélection : donner en paramètre un objet Person pour sélectionner la ligne associée Récupérer une sélection : un objet de type Personkeulkeul.blogspot.com Par ailleurs l’absence d’un modèle de sélection n’autorise pas la notification du changement de la sélection Utiliser si possible une gestion de la sélection directement par le Viewer JFace I - M. Baron - Page 95
  • 96. JFace / Viewers : sélection La gestion de la sélection au niveau d’un viewer est obtenue est utilisant un objet de type ISelection Un viewer fournit des méthodes pour récupérer et modifier la sélection ISelection getSelection() : accesseur sur la sélection courante setSelection(ISelection, boolean visible) : modifie la sélection, si visible est vraie la sélection est montrée En passant par le viewer, il est possible d’être notifié quandkeulkeul.blogspot.com une sélection a changé addSelectionChangedListener(ISelectionChangeListener) : abonne- ment sur un écouteur de changement de sélection JFace I - M. Baron - Page 96
  • 97. JFace / Viewers : sélection Le type de sélection est fonction du type de viewer utilisé Différentes implémentations de ISelection sont alors fournies StructuredSelection : pour les TableViewer TreeSelection : pour les TreeViewer TextSelection : pour la sélection de zones de texte Un objet ISelection retourne toutes les informations concer- nant une sélection Pour modifier une sélection, il faut passer un objet ISelectionkeulkeul.blogspot.com construit en fonction du type de viewer S’il s’agit d’une TableViewer il faudra construire un objet de type StructuredSelection JFace I - M. Baron - Page 97
  • 98. JFace / Viewers : sélection (StructuredSelection) Différents constructeurs pour StructuredSelection StructuredSelection() : créé une sélection vide StructuredSelection(List element) : créé une sélection multiple StructuredSelection(Object element) : créé une sélection avec un seul élément Les éléments transmis aux constructeurs StructuredSelection sont les éléments stockés dans l’Input (exemple : un objet de type Person) Pour chaque modification de la sélection, il faut construirekeulkeul.blogspot.com un nouvel objet StructuredSelection Les classes TreeSelection et TextSelection seront utilisées ultérieurement JFace I - M. Baron - Page 98
  • 99. JFace / Viewers : sélection (StructuredSelection) Exemple : TableViewer et modification de la sélection public class TableViewerSelectionExample { public TableViewerSelectionExample() { ... TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setLabelProvider(new MyTableLabelProvider()); ... Identifier le type de Button myButton = new Button(shell, SWT.FLAT); myButton.addSelectionListener(new SelectionAdapter() { ISelection public void widgetDisposed(SelectionEvent e) { ISelection mySelection = viewer.getSelection(); if (mySelection instanceof IStructuredSelection) { IStructuredSelection current = (IStructuredSelection)mySelection; int index = myPersonList.indexOf(current.getFirstElement()); index = (index + 1) % myPersonList.size(); viewer.setSelection(new StructuredSelection(myPersonList.get(index)), true); }keulkeul.blogspot.com } }); ... } } TableViewerSelectionExample.java du projet SelectionExamples JFace I - M. Baron - Page 99
  • 100. JFace / Viewers : sélection (StructuredSelection) Exemple : notification du changement de sélectionkeulkeul.blogspot.com La sélection de la second table est « reliée » à la BothTableViewerSelectionExample.java première table du projet SelectionExamples JFace I - M. Baron - Page 100
  • 101. JFace / Viewers : sélection (StructuredSelection) Exemple (suite) : notification du changement de sélection public class BothTableViewerSelectionExample { public BothTableViewerSelectionExample() { ... final TableViewer viewer1 = new TableViewer(shell, SWT.FULL_SELECTION); viewer1.setLabelProvider(new MyTableLabelProvider()); final TableViewer viewer2 = new TableViewer(shell, SWT.FULL_SELECTION); viewer2.setLabelProvider(new MyTableLabelProvider()); ... viewer1.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection currentSelection = (IStructuredSelection)selection; viewer2.setSelection(currentSelection); } } });keulkeul.blogspot.com } } BothTableViewerSelectionExample.java du projet SelectionExamples JFace I - M. Baron - Page 101
  • 102. JFace / Viewers : sélection (TreeSelection) La sélection pour un TreeViewer passe par l’utilisation d’un TreeSelection Le concept manipulé par le TreeSelection est le TreePath A chaque modification de la sélection il faut construire un nouvel objet TreeSelection TreeSelection(TreePath treePath) : sélection à partir d’un chemin TreeSelection(TreePath[] treePaths) : plusieurs sélections Accesseurs sur les sélections couranteskeulkeul.blogspot.com TreePath[] getPaths() : retourne les chemins de la sélection TreePath[] getPathsFor(Object element) : retourne les chemins dont le dernier segment est équivalent à element JFace I - M. Baron - Page 102
  • 103. JFace / Viewers : sélection (TreeSelection) Exemple : manipulation de TreeSelection TreeViewerSelectionExample.java du projet SelectionExamples Modification de la sélectionkeulkeul.blogspot.com Affichage de la sélection JFace I - M. Baron - Page 103
  • 104. JFace / Viewers : sélection (TreeSelection) Exemple (suite) : manipulation de TreeSelection public class TreeViewerSelectionExample { public TreeViewerSelectionExample() { ... TreeViewer viewer = new TreeViewer(shell, SWT.FULL_SELECTION); Button myButton = new Button(shell, SWT.FLAT); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { TreeSelection currentSelection = (TreeSelection)viewer.getSelection(); TreePath[] paths = currentSelection.getPaths(); for (TreePath treePath : paths) { Object lastSegment = treePath.getLastSegment(); System.out.println(lastSegment.toString()); } } }); myButton = new Button(shell, SWT.FLAT); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent arg0) { Job firstJob = myPersonWork.get(0);keulkeul.blogspot.com Object[] tabObject = {firstJob, firstJob.getPersons().get(0)}; TreePath path = new TreePath(tabObject); viewer.setSelection(new TreeSelection(path)); } }); } TreeViewerSelectionExample.java du ... projet SelectionExamples } JFace I - M. Baron - Page 104
  • 105. JFace / Viewers : Edition Tous les composants de type ColumnViewer (TableViewer et TreeViewer) peuvent éditer des éléments Une édition se caractérise par un modèle qui détermine si l’édition est autorisée, la valeur à afficher lors de l’édition et la nouvelle valeur à saisir un composant appelé Editor permettant de modifier la valeur d’un élément Depuis la version 3.3 d’Eclipse, il est possible d’appliquer une édition par élément pour chaque colonne via leskeulkeul.blogspot.com ViewerColumn Nous étudierons l’édition pour le viewer dans sa globalité puis de façon locale à chaque colonne JFace I - M. Baron - Page 105
  • 106. JFace / Viewers : Edition Le modèle d’édition est défini par l’interface ICellModifier boolean canModify(Object element, String property) : indique si la propriété (property) de l’élément donné peut être modifié Object getValue(Object element, String property) : retourne l’objet à afficher lors de l’édition (appelée avec l’édition) void modify(Object element, String property, Object value) : modifie la valeur de la propriété de l’élément donnékeulkeul.blogspot.com Pour identifier la propriété (property) de l’élément considéré (en générale il s’agit de la colonne), une identification par label (une sorte d’étiquette) est réalisée JFace I - M. Baron - Page 106
  • 107. JFace / Viewers : Edition Une fois le modèle d’édition implémentée, l’éditeur doit être fourni pour éditer la nouvelle donnée Un éditeur « Editor » est défini par la classe CellEditor L’API Eclipse fournit un ensemble de CellEditor prédéfini TextCellEditor pour l’édition d’un simple texte ColorCellEditor pour le choix d’une couleur ComboBoxCellEditor pour le choix d’une boite à sélection multiple CheckboxCellEditor pour le choix dans une boite à cocher DialogCellEditor pour la saisie d’une valeur dans une boite de dialoguekeulkeul.blogspot.com Un CellEditor repose sur un objet Composite pour l’édition Nous verrons dans la suite qu’il est possible de fournir son propre composant d’édition JFace I - M. Baron - Page 107
  • 108. JFace / Viewers : Edition Comme il n’y a pas de notion de colonne dans cette approche globale d’édition, il y autant d’éditeur qu’il y a de champs (property) défini Le composant ColumnViewer fournit des « setters » pour préciser le modèle d’édition et les éditeurs void setCellModifier(ICellModifier modifier) : définit le modèle d’édition void setColumnProperties(String[] columnProperties) : défini le tableau de label pour l’idenfication des colonneskeulkeul.blogspot.com void setCellEditors(CellEditor[] editors) : défini le tableau d’éditeurs Pour chaque propriété un éditeur est défini JFace I - M. Baron - Page 108
  • 109. JFace / Viewers : Edition Exemple : édition de cellules d’un TableViewer public class TableViewerEditorExample { public TableViewerEditorExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setUseHashlookup(true); viewer.setContentProvider(new MyStructuredContentProvider()); viewer.setLabelProvider(new MyTableLabelProvider()); viewer.setColumnProperties(new String[] {"NOM", "AGE", "VEGETARIEN"}); viewer.setCellEditors(new CellEditor[] { new TextCellEditor(table), new TextCellEditor(table), new TextCellEditor(table)}); new TableColumn(table, SWT.CENTER).setText("Nom"); new TableColumn(table, SWT.CENTER).setText("Age"); new TableColumn(table, SWT.CENTER).setText("Végétarien"); // Suite dans le prochain transparent ...keulkeul.blogspot.com } } TableViewerEditorExample.java du projet EditorExamples JFace I - M. Baron - Page 109
  • 110. JFace / Viewers : Edition Exemple (suite) : édition de cellules d’un TableViewer public class TableViewerEditorExample { public TableViewerEditorExample() { ... // Suite du précédent transparent viewer.setCellModifier(new ICellModifier() { public boolean canModify(Object element, String property) { return true; } public Object getValue(Object element, String property) { Person currentPerson = (Person)element; if (property.equals("NOM")) { return (currentPerson).getName(); } else if (property.equals("AGE")) { return Integer.toString(currentPerson.getOld()); } else { return Boolean.toString(currentPerson.isVegetarian()); } } public void modify(Object element, String property, Object value) { TableItem currentItem = (TableItem)element;keulkeul.blogspot.com Person currentPerson = (Person)currentItem.getData(); if (property.equals("NOM")) { currentPerson.setName((String)value); } else ... // Modifier le reste des attributs. viewer.refresh(currentPerson); Nécessaire pour mettre à } jour la vue } TableViewerEditorExample.java du } } projet EditorExamples JFace I - M. Baron - Page 110
  • 111. JFace / Viewers : Edition Avec la gestion explicite des colonnes depuis la version 3.3, il est possible de définir un éditeur particulier par colonne Ainsi un ViewerColumn (la colonne) propose un modificateur pour définir un éditeur void setEditingSupport(EditingSupport es) : modifie l’éditeur de la colonne considérée Un éditeur d’une colonne est défini par EditingSupport protected abstract boolean canEdit(Object element) : indique si la valeur de la colonne peut être éditée d’une ligne donnée (element) protected abstract CellEditor getCellEditor(Object element) : retournekeulkeul.blogspot.com le composant de l’édition protected abstract Object getValue(Object element) : retourne la valeur à afficher dans l’éditeur protected abstract void setValue(Object element, Object value) : appelée après l’édition pour modifier les données de Il’Input - Page JFace - M. Baron 111
  • 112. JFace / Viewers : Edition Exemple : édition de cellules d’un TableViewerColumn public class TableViewerColumnEditorExample { public TableViewerColumnEditorExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyStructuredContentProvider()); TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new MyColumnLabelProvider() { public String getText(Object element) { Person currentPerson = (Person)element; return currentPerson.getName(); Création d’un éditeur pour } }); la colonne « Nom » column.getColumn().setText("Nom"); column.setEditingSupport(new MyEditingSupport(viewer)); viewer.setInput(myPersonList); ... }keulkeul.blogspot.com } TableViewerColumnEditorExample.java du projet EditorExamples JFace I - M. Baron - Page 112
  • 113. JFace / Viewers : Edition Exemple (suite) : édition de cellules d’un TableViewerColumn public class TableViewerColumnEditorExample { ... static class MyEditingSupport extends EditingSupport { private CellEditor editor; Utilisation d’un composant private Viewer myViewer; prédéfini par l’API pour l’édition de texte public MyEditingSupport(ColumnViewer viewer) { super(viewer); myViewer = viewer; editor = new TextCellEditor((Composite)viewer.getControl()); } protected boolean canEdit(Object element) { return true; } protected CellEditor getCellEditor(Object element) { return editor; } protected Object getValue(Object element) { Person current = (Person)element; return current.getName();keulkeul.blogspot.com } protected void setValue(Object element, Object value) { Person current = (Person)element; current.setName((String)value); myViewer.refresh(); TableViewerColumnEditorExample.java } } du projet EditorExamples } JFace I - M. Baron - Page 113
  • 114. JFace / Viewers : Edition Nous avons vu que l’objet CellEditor permettait l’édition des données (classes prédéfinies) CellEditor fournit un nombre important de méthodes, dont voici les plus importantes à implémenter protected abstract Control createControl(Composite parent) : création du Composite d’édition protected abstract Object doGetValue() : retourne le contenu d’édition protected abstract void doSetFocus() : donne le focus à l’éditeur protected abstract void doSetValue(Object element) : modifie la valeur de l’éditeur avant éditionkeulkeul.blogspot.com Par ailleurs, il existe des méthodes pour notifier le viewer de l’état de l’éditeur protected void fireApplyEditorValue() : valider le résultat de l’éditeur protected void fireCancelEditor() : annuler le résultat de l’éditeur JFace I - M. Baron - Page 114
  • 115. JFace / Viewers : Edition Exemple : un CellEditor personnalisé public class TableViewerColumnCustomEditorExample { ... static class MyEditingSupport extends EditingSupport { private CellEditor editor; private Viewer myViewer; Création d’un composant d’édition public MyEditingSupport(ColumnViewer viewer) { super(viewer); personnalisé myViewer = viewer; editor = new MyCustomCellEditor((Composite)viewer.getControl()); } ... } } TableViewerColumnCustomEditorExample.java du projet EditorExampleskeulkeul.blogspot.com JFace I - M. Baron - Page 115
  • 116. JFace / Viewers : Edition Exemple (suite) : un CellEditor personnalisé public class MyCustomCellEditor extends CellEditor { private Text myText; private Composite myComposite; public MyCustomCellEditor(Composite parent, int style) { Création d’un super(parent, style); Composite avec un } Label et un Text protected Control createControl(Composite parent) { myComposite = new Composite(parent, SWT.NONE); GridLayout gridLayout = new GridLayout(); ... myComposite.setLayout(gridLayout); Label myLabel = new Label(myComposite, SWT.NONE); myLabel.setText("Saisir : "); myText = new Text(myComposite, SWT.NONE); myText.setLayoutData(new GridData(GridData.FILL_BOTH)); myText.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent e) {keulkeul.blogspot.com MyCustomCellEditor.this.fireApplyEditorValue(); } }); return myComposite; MyCustomCellEditor.java du projet } EditorExamples ... // La suite dans le prochain transparent } JFace I - M. Baron - Page 116
  • 117. JFace / Viewers : Edition Exemple (suite) : un CellEditor personnalisé public class MyCustomCellEditor extends CellEditor { ... // Suite dans le précédent transparent protected Object doGetValue() { Pour retourner le contenu return myText.getText(); } après la fin de l’édition protected void doSetFocus() { Avant l’édition, le focus est placé myText.setFocus(); myText.selectAll(); sur le champ de texte et le texte } présent est sélectionné protected void doSetValue(Object element) { if (element instanceof String) { myText.setText((String)element); Modification du champ de } } texte avant l’éditionkeulkeul.blogspot.com } MyCustomCellEditor.java du projet EditorExamples JFace I - M. Baron - Page 117
  • 118. JFace / Viewers : Filtre Un filtre permet d’afficher ou pas des éléments d’une liste selon une condition donnée Tout composant de type StructuredViewer (Tree, List et Table) peuvent utiliser des filtres Un filtre est défini par la classe ViewerFilter abstract boolean select(Viewer c, Object parentElement, Object element) : element : précise si l’élément donné (element) doit être affiché parentElement : objet transmis à l’Inputkeulkeul.blogspot.com Possibilité de transmettre plusieurs filtres à un composant StructuredViewer void setFilters(ViewerFilter[] p) : applique les filtres JFace I - M. Baron - Page 118
  • 119. JFace / Viewers : Filtre Exemple : filtrer le contenu d’un TableViewer Filtre non appliquékeulkeul.blogspot.com Filtre appliqué sur les personnes végétaiens JFace I - M. Baron - Page 119
  • 120. JFace / Viewers : Filtre Exemple : filtrer le contenu d’un TableViewer public class TableViewerFilterExample { private boolean isFiltred; TableViewerFilterExample.java public TableViewerFilterExample() { du projet FilterExamples ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); Button myButton = new Button(shell, SWT.CHECK); myButton.setText("Filtrer les végétariens"); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { isFiltred = !isFiltred; viewer.refresh(); } }); Nécessaire pour re-déclencher le filtre viewer.setInput(myPersonList); ViewerFilter current = new ViewerFilter() { public boolean select(Viewer viewer, Object parentElement, Object element) { if (isFiltred) { return ((Person)element).isVegetarian();keulkeul.blogspot.com } else { return true; } } }; ViewerFilter[] viewerFilterTab = new ViewerFilter[1]; viewerFilterTab[0] = current; viewer.setFilters(viewerFilterTab); } } JFace I - M. Baron - Page 120
  • 121. JFace / Viewers : Tri Un tri permet d’organiser des éléments d’une liste selon une comparaison de ces éléments Tout Viewer de type StructuredViewer (Tree, List et Table) peuvent utiliser de tris La classe StructuredViewer fournit un modificateur pour la gestion du tri void setComparator(ViewerComparator comparator) : comparator gère le tri Comparator getComparator() : accesseur sur le tri en courskeulkeul.blogspot.com L’activation du tri est obtenu par un ViewerComparator non null Pour désactiver le tri, le ViewerComparator doit être null JFace I - M. Baron - Page 121
  • 122. JFace / Viewers : Tri La classe ViewerComparator contient les méthodes suivantes int compare(Viewer viewer, Object e1, Object e2) : retourne un entier correspondant à la différence de e1 par rapport à e2 void sort(Viewer viewer, Object[] elements) : tri les éléments contenus dans le viewer (Input) et retourne le résultat dans elements La méthode int compare(…) retourne un entier signé dont le signe va renseigner sur la position de e1 par rapport à e2 si zéro : e1 et e2 sont égaux si négatif : e1 est inférieur à e2 si positif : e1 est supérieur à e2keulkeul.blogspot.com Les méthodes de comparaison des types existant (ex : String) retournent un entier correspondant à la différence "Dupont".compareToIgnoreCase("Motte") retourne -9 "Dupont" est inférieur à "Motte" de 9 éléments (D à M) M. Baron - Page JFace I - 122
  • 123. JFace / Viewers : Tri Exemple : tri croissant sur une colonne Désactivation du trikeulkeul.blogspot.com Activation du tri TableViewerGlobalSorterExample.java du projet SortExamples JFace I - M. Baron - Page 123
  • 124. JFace / Viewers : Tri Exemple (suite) : tri croissant sur une colonne public class TableViewerGlobalSorterExample { private boolean isSorted = false; public TableViewerGlobalSorterExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); Button myButton = new Button(shell, SWT.CHECK); myButton.setText("Trier les noms"); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { isSorted = !isSorted; If (isSorted) { viewer.setComparator(new MyViewerComparer()); } else { viewer.setComparator(null); } viewer.refresh(); Activation du tri } }); Désactivation du tri } private static class MyViewerComparer extends ViewerComparator {keulkeul.blogspot.com public int compare(Viewer viewer, Object e1, Object e2) { Person p1 = (Person) e1; Person p2 = (Person) e2; return p1.getName().compareToIgnoreCase(p2.getName()); } } ... TableViewerGlobalSorterExample.java } du projet SortExamples JFace I - M. Baron - Page 124
  • 125. JFace / Viewers : Tri Un tri peut être croissant ou décroissant Il peut être intéressant d’afficher le sens de tri sur la colonne à trier Cet affichage doit être précisé directement sur le composant natif Table La classe Table fournit deux méthodes void setSortColumn(TableColumn tc) : précise la colonne à trier void setSortDirection(int direction) : précise le sens du tri (SWT.UP,keulkeul.blogspot.com SWT.DOWN et SWT.NONE) Pour désactiver l’affichage du tri, mettre à null la colonne à trier et mettre à NONE la direction du tri JFace I - M. Baron - Page 125
  • 126. JFace / Viewers : Tri Exemple : tri avec indicateur sur une colonne public class TableViewerOneColumnSorterExample { private boolean isSorted = false; public TableViewerOneColumnSorterExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); Button myButton = new Button(shell, SWT.CHECK); myButton.setText("Trier les noms"); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { isSorted = !isSorted; If (isSorted) { viewer.setComparator(new MyViewerComparer()); Affichage d’une flèche myTable.setSortColumn(myTable.getColumn(0)); vers le haut si trier myTable.setSortDirection(SWT.UP); } else { viewer.setComparator(null); myTable.setSortColumn(null); myTable.setSortDirection(SWT.NONE); } viewer.refresh();keulkeul.blogspot.com } }); } ... } TableViewerOneColumnSorterExample.java du projet SortExamples JFace I - M. Baron - Page 126
  • 127. JFace / Viewers : Tri Exemple : tri avec indicateurs sur une colonne cliquable public class TableViewerOneBisColumnSorterExample { ... private int direction = NONE; public TableViewerOneBisColumnSorterExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); ... table.getColumn(0).addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { Table myTable = viewer.getTable(); if (direction == NONE) { viewer.setComparator(new MyViewerComparer()); Cliquer directement myTable.setSortColumn(myTable.getColumn(0)); sur l’en-tête de la myTable.setSortDirection(SWT.UP); direction = ASC; colonne } else if (direction == ASC) { ... } else { viewer.setComparator(null); myTable.setSortColumn(null);keulkeul.blogspot.com myTable.setSortDirection(SWT.NONE); direction = NONE; } viewer.refresh(); } }); ... } TableViewerOneBisColumnSorterExample.java } du projet SortExamples JFace I - M. Baron - Page 127
  • 128. JFace / Viewers : Tri Exemple : tri avec indicateurs sur colonnes cliquables Tri sur la première Tri sur la deuxième colonne colonnekeulkeul.blogspot.com Tri sur la troisième colonne TableViewerSeveralColumnSorterExample.java du projet SortExamples JFace I - M. Baron - Page 128
  • 129. JFace / Viewers : Tri Exemple (suite) : tri avec indicateurs sur colonnes cliquables public class TableViewerSeveralColumnSorterExample { ... private int direction = NONE; public TableViewerSeveralColumnSorterExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); ... TableViewerColumn refNameColumn = new TableViewerColumn(viewer, SWT.NONE); refNameColumn.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { Person currentPerson = (Person)element; Autant de return currentPerson.getName(); } TableViewerColumn }); qu’il y a de colonnes refNameColumn.getColumn().setText("Nom"); ColumnSorter refCS = new ColumnSorter(viewer, refNameColumn) { public int columnCompare(Viewer viewer, Object e1, Object e2) { Person p1 = (Person) e1; Person p2 = (Person) e2; return p1.getName().compareToIgnoreCase(p2.getName());keulkeul.blogspot.com } }; ... } } TableViewerSeveralColumnSorterExample.java du projet SortExamples JFace I - M. Baron - Page 129
  • 130. JFace / Viewers : Tri Exemple (suite) : tri avec indicateurs sur colonnes cliquables public class ColumnSorter extends ViewerComparator { private ColumnViewer refViewer; private TableViewerColumn column; Placer un écouteur sur public static final int ASC = 1; la sélection de la ... private int direction = 0; colonne public ColumnSorter(ColumnViewer pViewer, TableViewerColumn pColumn) { this.refViewer = pViewer; this.column = pColumn; this.column.getColumn().addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (ColumnSorter.this.refViewer.getComparator() != null) { if (ColumnSorter.this.refViewer.getComparator() == ColumnSorter.this) { int tdirection = ColumnSorter.this.direction; if (tdirection == ASC) { setSorter(ColumnSorter.this, DESC); } else if (tdirection == DESC) { setSorter(ColumnSorter.this, NONE); } } else {keulkeul.blogspot.com setSorter(ColumnSorter.this, ASC); } } else { setSorter(ColumnSorter.this, ASC); } } ColumnSorter.java du projet }); } SortExamples JFace I - M. Baron - Page 130
  • 131. JFace / Viewers : Tri Exemple (suite) : tri avec indicateurs sur colonnes cliquables public class ColumnSorter extends ViewerComparator { ... public void setSorter(ColumnSorter sorter, int direction) { if (direction == NONE) { column.getColumn().getParent().setSortColumn(null); column.getColumn().getParent().setSortDirection(SWT.NONE); refViewer.setComparator(null); } else { column.getColumn().getParent().setSortColumn(column.getColumn()); sorter.direction = direction; if (direction == ASC) { column.getColumn().getParent().setSortDirection(SWT.DOWN); } else { column.getColumn().getParent().setSortDirection(SWT.UP); } if (refViewer.getComparator() == sorter) { refViewer.refresh(); } else { refViewer.setComparator(sorter); }keulkeul.blogspot.com } ColumnSorter.java du projet } SortExamples public int compare(Viewer viewer, Object e1, Object e2) { return direction * columnCompare(viewer, e1, e2); } public abstract int columnCompare(Viewer viewer, Object e1, Object e2); } JFace I - M. Baron - Page 131
  • 132. Bilan … Premières impressions … La version Eclipse 3.3 apporte la gestion des colonnes Approche par modèles très souple Dommage de devoir utiliser directement les objets natifs pour effec- tuer certains traitements Le nom des colonnes (TableColumn) Le tri, … Le rendu des éléments et le rendu des éditeurs ne sont pas aussi souples qu’avec la boite à outils Swingkeulkeul.blogspot.com Les choses non étudiées, prochainement … Approfondir par de nombreux exemples Synchronisation de valeurs entre objets avec JFace Data Binding JFace I - M. Baron - Page 132