Composants de visualisation (Viewer) avec JFace

7 953 vues

Publié le

0 commentaire
2 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
7 953
Sur SlideShare
0
Issues des intégrations
0
Intégrations
2 308
Actions
Partages
0
Téléchargements
413
Commentaires
0
J’aime
2
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Composants de visualisation (Viewer) avec JFace

  1. 1. Développement de clients riches : Plateforme Eclipse Mickaël BARON - 2007 (Rév. Janvier 2009) mailto:baron.mickael@gmail.com ou mailto:baron@ensma.fr @mickaelbaron Composants de Visualisation (Viewer) avec JFace Chapitre 2 : Boîtes à outils
  2. 2. 2JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron Creative Commons Contrat Paternité Partage des Conditions Initiales à l'Identique 2.0 France http://creativecommons.org/licenses/by-sa/2.0/fr Licence
  3. 3. 3JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 † Edition † Techniques de Tri et de Filtre Tous les exemples du cours sont disponibles directement à l’adresse mbaron.developpez.com/eclipse/jface1 Des informations complémentaires peuvent être trouvées sur mon blog keulkeul.blogspot.com
  4. 4. 4JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 SWT † 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, …)
  5. 5. 5JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 boîte à outils connectée aux composants natifs L’extension et l’encapsulation de SWT La plateforme Eclipse s’appuie sur JFace et SWT
  6. 6. 6JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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.3 † 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)
  7. 7. 7JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 † Les ressources : org.eclipse.jface.resource † Les assistants : org.eclipse.jface.wizard † Les sources sont également fournies avec la distribution 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) Pour SWT, il faut télécharger l’archive sur le site d’Eclipse
  8. 8. 8JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 Java 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
  9. 9. 9JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace : configuration … (suite) † Etape 2 : ajout des dépendances aux librairies JFace Les librairies ajoutées dans le chemin de construction ne sont pas exhaustives. Il s’agit d’un minimum pour utiliser une TableViewer † org.eclipse.core.commands † org.eclipse.equinox.app † org.eclipse.jface † org.eclipse.swt
  10. 10. 10JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 de 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
  11. 11. 11JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : introduction M † 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 Document (En Java le vue et le contrôleur ne sont pas dissociés) La partie Modèle (Notification des vues après modification) V C
  12. 12. 12JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 liste † 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 Table
  13. 13. 13JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 liste † 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
  14. 14. 14JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : introduction TableViewer TreeViewer TableTreeViewer (TreeViewer avec colonnes)
  15. 15. 15JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : introduction ListViewer ComboViewer CheckboxTreeViewer CheckboxTableViewer
  16. 16. 16JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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) † 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 JFace
  17. 17. 17JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 TableColumn † 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
  18. 18. 18JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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çable † 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
  19. 19. 19JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); for (int i = 0; i < 3; i++) { TableColumn column = new TableColumn(table, SWT.NONE); column.setWidth(100); column.setText("Colonnne " + i); column.setMoveable(true); column.setResizable(true); } ... } ... } Construction de trois colonnes TableColumnExample.java du projet TableExamples Fixe la largeur Les colonnes sont déplaçables et redimensionnables Il manque les cellules !!
  20. 20. 20JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 cellule † 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
  21. 21. 21JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Table † Exemple : une table, ses colonnes et ses lignes public class TableRowColumnExample { public TableRowColumnExample() { ... for (int i = 0; i < 50; i++) { new TableItem(table, SWT.NONE); } 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); } } ... } ... } Construction de 50 lignes Couleur de fond des cellules différente selon la « parité » Modification du contenu de la cellule de la ligne i de la colonne j TableRowColumnExample.java du projet TableExamples
  22. 22. 22JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 colonnes † 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
  23. 23. 23JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Table † Exemple (suite) : une table, ses colonnes et ses lignes public class AdvancedTableRowColumnExample { public AdvancedTableRowColumnExample() { ... Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION); ... table.setHeaderVisible(true); table.setLinesVisible(true); table.setTopIndex(20); int[] selectedIndex = {22, 25}; table.setSelection(selectedIndex); table.clear(23); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } ... } AdvancedTableRowColumnExample du projet TableExamples Positionner la ligne 20 en haut de la table Active la sélection multiple et la sélection de la ligne complète Sélectionne les lignes 22 et 25 Efface le contenu de la ligne 23 (suppression du texte)
  24. 24. 24JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 TreeColumn † 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
  25. 25. 25JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Tree † La classe TreeColumn décrit une colonne et possède les mêmes fonctionnalités que la classe TableColumn † 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é » Plusieurs colonnes Un arbre contenant des noeuds sur la colonne 1 Chaque item désigne une ligne (1 nœud + plusieurs cellules)
  26. 26. 26JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 le 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é
  27. 27. 27JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Tree † Exemple : un arbre et ses noeuds public class TreeExample { public TreeExample() { ... 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); 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); } } shell.open(); ... } ... } Les nœuds parents x4 Les sous nœuds parents x3 TreeExample du projet TreeExamples
  28. 28. 28JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); ... 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); subCurrent.setText(1, "valeur 1 " + j); subCurrent.setText(2, "valeur 2 " + j); } } shell.open(); ... } ... } TreeColonneExample du projet TreeExamples Création des colonnes
  29. 29. 29JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 table † 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
  30. 30. 30JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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++) { ... } } myTree.setTopItem(myTree.getItem(5)); myTree.setSelection(myTree.getItem(5)); myTree.getItem(5).setExpanded(true); shell.open(); ... } ... } TreeColonneSelectionExample du projet TreeExamples Déplier le nœud 5 Afficher le nœud 5 en haut du Tree Modifier la sélection sur le nœud 5
  31. 31. 31JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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é † LabelProvider † 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
  32. 32. 32JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Viewer Input Person - name : String - firstName : String - … + getName() : String + getFirstName() : String + … List<Person> myList ContentProvider LabelProvider Table TableViewer Concept stockant les données à afficher Les données à afficher par la table List<Person> myList Transmission des données à l’Input (Initialisation) 1 2 Les données sont transmises pour structuration getElements(myList) 3 Les données sont structurées : Person[] 4 Pour chaque ligne et chaque colonne transmission d’un objet Person et de l’indice de colonne concerné getColumnText(Person, i) 5 Retour pour appel à getColumnText(…) d’une chaîne à afficher dans la cellule : String Transmission pour chaque TableItem de la table d’une chaîne de caractères 6 IStructuredContentProvider ITableLabelProvider Le viewer centralise les appels aux différents concepts Person,0 "Dupont" "Dupont" List<Person> Person[]
  33. 33. 33JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Viewer Viewer TextViewer ContentViewer En charge de gérer le LabelProvider, le ContentProvider et l’Input …StructuredViewer En charge de gérer le tri et le filtre AbstractListViewer ComboViewer ListViewer Classe qui décrit le comportement de viewers de type Liste ColumnViewer AbstractTableViewer AbstractTreeViewer En charge des Viewers contenant des colonnes (new 3.3) En charge des viewers de type Arbre (new 3.3) En charge des viewers de type Table (new 3.3) † Hiérarchie des principaux Viewers TableViewer TreeViewer Gestion des composants de texte. Non étudiés dans ce cours
  34. 34. 34JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : un exemple pour débuter † Exemple : TableViewer et ses trois concepts Cinq colonnes Un objet Person contenant un nom, un prénom, un sport, un age et une habitude alimentaireTableViewerExample.java du projet TableViewerExamples
  35. 35. 35JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : un exemple pour débuter † Exemple (suite) : TableViewer et ses trois concepts public class Person { private String name; private String firstName; 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; } public void setName(String name) { this.name = name; } ... } Cinq propriétés Cinq modifieurs et accesseurs Person.java du projet TableViewerExamples
  36. 36. 36JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); 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++) { table.getColumn(i).setWidth(100); } shell.open(); ... }... Concept : Input La description détaillée de TableViewer sera réalisée dans la suite du cours TableViewerExample.java du projet TableViewerExamples
  37. 37. 37JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); } } 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(); 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 ""; } } public Image getColumnImage(Object element, int columnIndex) { return null; } } Concept : LabelProvider Concept : ContentProvider TableViewerExample.java du projet TableViewerExamples
  38. 38. 38JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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é † 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
  39. 39. 39JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron † 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 information † 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 / Viewers : ContentProvider
  40. 40. 40JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 † … † 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
  41. 41. 41JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : ContentProvider † Hiérarchie des principales interfaces ContentProvider IContentProvider ILazyTreeContentProviderILazyContentProvider IStructuredContentProvider ITreeContentProviderITreePathContentProvider … Et pleins d’autres encore … Permet de connaître le nombre d’éléments (lignes, racines, …) Quand le nombre d’éléments est inconnu Quand le nombre d’éléments d’un arbre est inconnu Lazy pour Lazy Loading signifie que l’élément considéré n’est chargé qu’au moment où il est effectivement utilisé Permet de connaître la relation entre élément et son père et vice-et-versa
  42. 42. 42JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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éthode † Object[] getElements(Object inputElement) : retourne toutes les lignes à afficher † Le paramètre inputElement est donné par l’objet input du composant viewer
  43. 43. 43JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); ... } static class MyStructuredContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { ArrayList<Person> localInputElement = (ArrayList<Person>)inputElement; return localInputElement.toArray(); } } ... } L’input est de type List<Person> L’input est transmis en paramètre de getElements(…)En retour de cette méthode, il faut transmettre les lignes du tableau qui seront affichées TableViewerExample.java du projet TableViewerExamples
  44. 44. 44JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 † 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 Colonne d’un TableViewer Rendu de la cellule obtenu par un label (Image + Texte) Ici un label sans l’affichage de l’image
  45. 45. 45JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 IBaseLabelProvider ILabelProvider ITableLabelProvider ITreePathLabelProvider IViewerLabelProvider Utilisée pour les viewers de type StructuredViewer comme TreeViewer sauf TableViewer LabelProvider adapté pour les composants de type TableViewer Ajoute une méthode updateLabel spécialiser dans la mise à jour d’élément (à voir plus tard) Ajoute une méthode updateLabel spécialiser dans la mise à jour de chemin pour un TreeViewer (à voir plus tard)
  46. 46. 46JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 par 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
  47. 47. 47JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 de l’attribut adéquate de l’objet Person † La méthode getColumnImage(…) sera appelée autant de fois qu’il y a de lignes
  48. 48. 48JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 pour toutes les colonnes, ColumnViewer fournit une méthode † setLabelProvider(IBaseLabelProvider p) : associer un LabelProvider à toutes les colonnes
  49. 49. 49JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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()); ... } ... class MyTableLP extends BaseLabelProvider implements ITableLabelProvider { public String getColumnText(Object element, int columnIndex) { Person currentPerson = (Person)element; switch(columnIndex) { case 0 : return currentPerson.getName(); 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 ""; } } public Image getColumnImage(Object element, int columnIndex) { return null; } }} Implémentation par défaut de IBaseLabelProvider N’affiche pas d’image Selon la valeur de columnIndex on sélectionne l’attribut à afficher TableViewerExample.java du projet TableViewerExamples
  50. 50. 50JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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++) { table.getColumn(i).setWidth(100); } ... } ... } TableViewerExample.java du projet TableViewerExamples Nécessite de construire des TableColumn pour paramétrer chaque en-tête de colonne
  51. 51. 51JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 colonne † setEditingSupport(EditingSupport es) : modification de l’éditeur (à voir plus tard) † CellLabelProvider, qui hérite de BaseLabelProvider, est une nouveauté 3.3
  52. 52. 52JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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ême † Nous détaillerons donc TableViewerColumn puis pour TreeViewerColumn nous donnerons simplement des exemples
  53. 53. 53JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 TableViewer † 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
  54. 54. 54JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 colonne † 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
  55. 55. 55JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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() { ... } column.getColumn().setText("Nom"); column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { ... } column.getColumn().setText("Sport"); ... viewer.setInput(myPersonList); Table table = viewer.getTable(); table.setLayoutData(new GridData(GridData.FILL_BOTH)); ... } } TableViewerColumnExample.java du projet TableViewerExamples Nécessite toujours de manipuler le composant natif Table Modification de l’en- tête de la colonne Un LabelProvider par colonne (à voir après)
  56. 56. 56JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron † 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’aides natives doivent être utilisées † Pour utiliser les bulles d’aides il faut les activer … JFace / Viewers : LabelProvider ColumnViewerToolTipSupport.enableFor(myViewer, ToolTip.NO_RECREATE) Activation des bulles d’aides pour un viewer donné
  57. 57. 57JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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’avant † Font getFont(Object element) : la fonte † Image getImage(Object element) : l’image (si null = d’image) † String getText(Object element) : le texte
  58. 58. 58JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 autres TableViewerColumnExample.java du projet TableViewerExamples
  59. 59. 59JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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; return currentPerson.getName(); } } column.getColumn().setText("Nom"); column = new TableViewerColumn(viewer, SWT.NONE); column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { Person currentPerson = (Person)element; return currentPerson.getFirstName(); } } column.getColumn().setText("Sport"); ... } } Retourne le texte à afficher dans la cellule Modifie la couleur de fond de la première colonne TableViewerColumnExample.java du projet TableViewerExamples
  60. 60. 60JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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) { return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); } public String getToolTipText(Object element) { return "Ceci est un exemple de bulle d’aide"; } public boolean useNativeToolTip(Object object) { return false; } }); column.getColumn().setText("Végétarien"); ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE); } } Gestion des bulles d’aides par colonne TableViewerColumnExample.java du projet TableViewerExamples N’oubliez pas d’activer les bulles d’aides via ColumnViewerToolTipSupport
  61. 61. 61JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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élection † 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
  62. 62. 62JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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; int height = event.gc.textExtent(currentPerson.getName()).y + 5; int width = event.gc.textExtent(currentPerson.getName()).x; event.setBounds(new Rectangle(0,0, width, height)); } protected void paint(Event event, Object element) { // La suite dans le slide suivant ... } } column.getColumn().setText("Nom"); ... // Traitement des autres colonnes OwnerDrawLabelProvider.setUpOwnerDraw(viewer); } } OwnerDrawLabelExample.java du projet TableViewerExamples Style, couleur et fonte différents dans un même label Précise la dimension du label
  63. 63. 63JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); TextLayout layout = new TextLayout(display); layout.setText(currentPerson.getName()); TextStyle plain = new TextStyle(JFaceResources .getFont(JFaceResources.DEFAULT_FONT), display .getSystemColor(SWT.COLOR_LIST_FOREGROUND), null); TextStyle italic = new TextStyle(JFaceResources.getFontRegistry() .getItalic(JFaceResources.DEFAULT_FONT), display .getSystemColor(SWT.COLOR_BLUE), null); Font newFont = new Font(display, "Arial", 9, SWT.BOLD); TextStyle font = new TextStyle(newFont, display .getSystemColor(SWT.COLOR_WHITE), display .getSystemColor(SWT.COLOR_BLACK)); layout.setStyle(plain, 0, 2); layout.setStyle(italic, 3, 5); layout.setStyle(font, 6, currentPerson.getName().length() - 1); layout.draw(event.gc, event.x, event.y); } La cellule la plus grande fixe la taille de toutes les autres dimensions d’une même colonne OwnerDrawLabelExample.java du projet TableViewerExamples Précise les différents styles Utilisation d’un TextLayout pour faciliter l’agencement du texte dans la cellule
  64. 64. 64JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron † 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) † Particulièrement le style SWT.VIRTUAL permet d’utiliser le ContentProvider ILazyContentProvider JFace / Viewers : TableViewer Si le style est SWT.VIRTUAL utilisez obligatoirement ILazyContentProvider au risque de lever une exception
  65. 65. 65JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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és 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
  66. 66. 66JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 index 12 objets ont été chargés dans la TableViewer
  67. 67. 67JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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()); ... } static class MyLazyContentProvider implements ILazyContentProvider { private AbstractTableViewer ref; private ArrayList<Person> myPersonList; private MyLazyContentProvider(AbstractTableViewer pRef) { this.ref = pRef; } public void updateElement(int index) { ref.replace(myPersonList.get(index), index); } public void inputChanged(Viewer view, Object oldInput, Object newInput) { this.myPersonList = (ArrayList<Person>)newInput; } public void dispose() {} } } Précise le nombre de ligne dans la table Ajoute un objet à la position index LazyContentProviderExample.java du projet TableViewerExamples
  68. 68. 68JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 TreeViewerColumn † 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
  69. 69. 69JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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é † 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
  70. 70. 70JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : TreeViewer † Exemple : TreeViewer et ITreeContentProvider public class Job { private List<Person> myPerson; private String job; 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; ... } public String getName() { return name; } public void setParent(Job pJob) { this.parent = pJob; } ... } Person.java du projet TreeViewerExamples Job.java du projet TreeViewerExamples
  71. 71. 71JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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>(); Job currentWork = new Job("Informaticien"); currentWork.addPerson(new Person("Robert Glan", "Nancy", "25", "Voiture", "1600")); currentWork.addPerson(new Person(...)); viewer.setInput(myPersonWork); ... } static class MyTreeContentProvider implements ITreeContentProvider { public Object[] getElements(Object element) { final Object[] currentPersonWorks = ((List<Job>) element).toArray(); return currentPersonWorks; } public void dispose() { } public void inputChanged(Viewer v, Object belement, Object aelement) { } ... } } Construction d’un ContentProvider Transformation des données de l’Input TreeViewerExample.java du projet TreeViewerExamples
  72. 72. 72JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : TreeViewer † Exemple (suite) : TreeViewer et ITreeContentProvider static class MyTreeContentProvider implements ITreeContentProvider { ... public Object[] getChildren(Object element) { final Job currentPersonWork = (Job) element; return currentPersonWork.getPersons().toArray(); } public Object getParent(Object element) { if (element instanceof Person) { return ((Person)element).getParent(); } else { return null; } } public boolean hasChildren(Object element) { if (element instanceof Job) { Job current = (Job) element; return !current.isPersonEmpty(); } else return false; } } } TreeViewerExample.java du projet TreeViewerExamples Le nœud courant comporte-il des sous noeuds Retourne le parent du nœud element Retourne les nœuds enfants
  73. 73. 73JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 TreePath † 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
  74. 74. 74JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 chemin † 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
  75. 75. 75JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : TreeViewer † Exemple : TreeViewer et ITreePathContentProvider static class MyTreePathContentProvider implements ITreePathContentProvider { ... public Object[] getChildren(TreePath parentPath) { Object lastSegment = parentPath.getLastSegment(); final Job currentPersonWork = (Job) lastSegment; return currentPersonWork.getPersons().toArray(); } public TreePath[] getParents(Object element) { TreePath[] refParents = new TreePath[1]; Person currentJob = (Person)element; Object[] segmentTab = {currentJob.getParent()}; refParents[0] = new TreePath(segmentTab); return refParents; } public boolean hasChildren(TreePath path) { Object lastSegment = path.getLastSegment(); if (lastSegment instanceof Job) { Job current = (Job)lastSegment; return !current.isPersonEmpty(); } else { return false; } } } } Le nœud courant comporte-il des sous noeuds Retourne les parents du nœud element Retourne les nœuds enfants TreeViewerWithPathExample.java du projet TreeViewerExamples
  76. 76. 76JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); } else { return element.toString(); } } } ... } TreeViewerExample.java du projet TreeViewerExamples
  77. 77. 77JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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=4 Chargement progressif de 10 noeuds
  78. 78. 78JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : TreeViewer † Exemple (suite) : Ouverture progressive d’un nœud public class DeferredTreeContentManagerView extends ViewPart { private TreeParent invisibleRoot; 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; private TreeObject parent; public TreeObject(String pName) { this.name = pName; } public void setParent(TreeObject pParent) { this.parent = parent; } } ... } DeferredTreeContentManagerView.java du projet TreeViewerExamples Nœud acceptant un nœud parent C’est du LazyLoading
  79. 79. 79JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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; private ArrayList<TreeObject> children; public TreeParent(String name) { super(name); 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); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public boolean hasChildren() { return children.size() > 0; } } } DeferredTreeContentManagerView.java du projet TreeViewerExamples Partie progressive … Indique si cet objet peut avoir des enfants
  80. 80. 80JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); } public Object getParent(Object element) { if (element instanceof TreeObject) { return ((TreeObject) element).getParent(); } return null; } public boolean hasChildren(Object element) { return manager.mayHaveChildren(element); } } } DeferredTreeContentManagerView.java du projet TreeViewerExamples Si parentElement est un « deferred element », il y a création d’un thread Y a t il potentiellement des nœuds enfants ? C’est du LazyLoading
  81. 81. 81JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 TableTreeViewer † 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
  82. 82. 82JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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; } public String getName() { return name; } public String getAddress() { return address; } ... } Person.java du projet TreeViewerExamples
  83. 83. 83JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 } } } column.getColumn().setText("Métier / Nom"); ... // Address, Old, vehicule et salaire même principe } } TreeViewerColumnExample.java du projet TreeViewerExamples
  84. 84. 84JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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. 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
  85. 85. 85JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 { return ""; } } } ... } ListViewerExample.java du projet OtherViewersExamples Affichage du texte
  86. 86. 86JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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) { Person currentPerson = (Person)element; return currentPerson.getName(); } public int getToolTipDisplayDelayTime(Object object) { return 500; } public int getToolTipTimeDisplayed(Object object) { return 5000; } public String getToolTipText(Object element) { return "Ceci est un exemple de bulle d'aide"; } public boolean useNativeToolTip(Object object) { return false; } }); ColumnViewerToolTipSupport.enableFor(viewer,ToolTip.NO_RECREATE); ... } } ListViewerWithTableViewerExample.java du projet OtherViewersExamples Possibilité d’ajouter des images Possibilité d’affiner le paramétrage des bulles d’aides
  87. 87. 87JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); ... } ... } ComboViewerExample.java du projet OtherViewersExamples
  88. 88. 88JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 changement † addCheckStateListener(ICheckStateListener listener) : ajoute un écouteur † ICheckStateListener#checkStateChanged(CheckStateChangedEvent) : notifie un changement d’état
  89. 89. 89JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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())); } } }); Tree myTree = viewer.getTree(); GridData gridData = new GridData(GridData.FILL_BOTH); myTree.setLayoutData(gridData); ... } ... } CheckBoxTreeViewerExample.java du projet OtherViewersExamples Si sélection du nœud parent sélection de tous les sous noeuds
  90. 90. 90JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); ... } ... } CheckBoxTableViewerExample.java du projet OtherViewersExamples
  91. 91. 91JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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’elle 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
  92. 92. 92JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(), … † 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)
  93. 93. 93JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 clavier Modification de la sélection de manière programmatique NativeTableViewerSelectionExample.java du projet SelectionExamples
  94. 94. 94JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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()); Button myButton = new Button(shell, SWT.FLAT); 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) { System.out.println(viewer.getTable().getSelectionIndex()); } } ... } } Récupération de la sélection courante NativeTableViewerSelectionExample.java du projet SelectionExamples
  95. 95. 95JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 Person † 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
  96. 96. 96JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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é quand une sélection a changé † addSelectionChangedListener(ISelectionChangeListener) : abonne- ment sur un écouteur de changement de sélection
  97. 97. 97JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 ISelection construit en fonction du type de viewer † S’il s’agit d’une TableViewer il faudra construire un objet de type StructuredSelection
  98. 98. 98JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 construire un nouvel objet StructuredSelection Les classes TreeSelection et TextSelection seront utilisées ultérieurement
  99. 99. 99JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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()); ... Button myButton = new Button(shell, SWT.FLAT); myButton.addSelectionListener(new SelectionAdapter() { 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); } } }); ... } } TableViewerSelectionExample.java du projet SelectionExamples Identifier le type de ISelection
  100. 100. 100JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : sélection (StructuredSelection) † Exemple : notification du changement de sélection La sélection de la second table est « reliée » à la première table BothTableViewerSelectionExample.java du projet SelectionExamples
  101. 101. 101JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); } } }); } } BothTableViewerSelectionExample.java du projet SelectionExamples
  102. 102. 102JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 courantes † TreePath[] getPaths() : retourne les chemins de la sélection † TreePath[] getPathsFor(Object element) : retourne les chemins dont le dernier segment est équivalent à element
  103. 103. 103JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : sélection (TreeSelection) † Exemple : manipulation de TreeSelection TreeViewerSelectionExample.java du projet SelectionExamples Affichage de la sélection Modification de la sélection
  104. 104. 104JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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); Object[] tabObject = {firstJob, firstJob.getPersons().get(0)}; TreePath path = new TreePath(tabObject); viewer.setSelection(new TreeSelection(path)); } }); } ... } TreeViewerSelectionExample.java du projet SelectionExamples
  105. 105. 105JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 les ViewerColumn † Nous étudierons l’édition pour le viewer dans sa globalité puis de façon locale à chaque colonne
  106. 106. 106JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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é † 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
  107. 107. 107JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 dialogue † 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
  108. 108. 108JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 colonnes † void setCellEditors(CellEditor[] editors) : défini le tableau d’éditeurs Pour chaque propriété un éditeur est défini
  109. 109. 109JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 ... } } TableViewerEditorExample.java du projet EditorExamples
  110. 110. 110JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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; Person currentPerson = (Person)currentItem.getData(); if (property.equals("NOM")) { currentPerson.setName((String)value); } else ... // Modifier le reste des attributs. viewer.refresh(currentPerson); } } } } TableViewerEditorExample.java du projet EditorExamples Nécessaire pour mettre à jour la vue
  111. 111. 111JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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) : retourne 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 l’Input
  112. 112. 112JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); } }); column.getColumn().setText("Nom"); column.setEditingSupport(new MyEditingSupport(viewer)); viewer.setInput(myPersonList); ... } } Création d’un éditeur pour la colonne « Nom » TableViewerColumnEditorExample.java du projet EditorExamples
  113. 113. 113JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Edition † Exemple (suite) : édition de cellules d’un TableViewerColumn public class TableViewerColumnEditorExample { ... static class MyEditingSupport extends EditingSupport { private CellEditor editor; private Viewer myViewer; 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(); } protected void setValue(Object element, Object value) { Person current = (Person)element; current.setName((String)value); myViewer.refresh(); } } } TableViewerColumnEditorExample.java du projet EditorExamples Utilisation d’un composant prédéfini par l’API pour l’édition de texte
  114. 114. 114JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 édition † 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
  115. 115. 115JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Edition † Exemple : un CellEditor personnalisé public class TableViewerColumnCustomEditorExample { ... static class MyEditingSupport extends EditingSupport { private CellEditor editor; private Viewer myViewer; public MyEditingSupport(ColumnViewer viewer) { super(viewer); myViewer = viewer; editor = new MyCustomCellEditor((Composite)viewer.getControl()); } ... } } TableViewerColumnCustomEditorExample.java du projet EditorExamples Création d’un composant d’édition personnalisé
  116. 116. 116JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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) { super(parent, style); } 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) { MyCustomCellEditor.this.fireApplyEditorValue(); } }); return myComposite; } ... // La suite dans le prochain transparent } MyCustomCellEditor.java du projet EditorExamples Création d’un Composite avec un Label et un Text
  117. 117. 117JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Edition public class MyCustomCellEditor extends CellEditor { ... // Suite dans le précédent transparent protected Object doGetValue() { return myText.getText(); } protected void doSetFocus() { myText.setFocus(); myText.selectAll(); } protected void doSetValue(Object element) { if (element instanceof String) { myText.setText((String)element); } } } † Exemple (suite) : un CellEditor personnalisé MyCustomCellEditor.java du projet EditorExamples Pour retourner le contenu après la fin de l’édition Avant l’édition, le focus est placé sur le champ de texte et le texte présent est sélectionné Modification du champ de texte avant l’édition
  118. 118. 118JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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’Input † Possibilité de transmettre plusieurs filtres à un composant StructuredViewer † void setFilters(ViewerFilter[] p) : applique les filtres
  119. 119. 119JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Filtre † Exemple : filtrer le contenu d’un TableViewer Filtre non appliqué Filtre appliqué sur les personnes végétaiens
  120. 120. 120JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Filtre † Exemple : filtrer le contenu d’un TableViewer public class TableViewerFilterExample { private boolean isFiltred; public TableViewerFilterExample() { ... 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(); } }); viewer.setInput(myPersonList); ViewerFilter current = new ViewerFilter() { public boolean select(Viewer viewer, Object parentElement, Object element) { if (isFiltred) { return ((Person)element).isVegetarian(); } else { return true; } } }; ViewerFilter[] viewerFilterTab = new ViewerFilter[1]; viewerFilterTab[0] = current; viewer.setFilters(viewerFilterTab); } } TableViewerFilterExample.java du projet FilterExamples Nécessaire pour re-déclencher le filtre
  121. 121. 121JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 cours † L’activation du tri est obtenu par un ViewerComparator non null † Pour désactiver le tri, le ViewerComparator doit être null
  122. 122. 122JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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 à e2 † 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)
  123. 123. 123JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Tri † Exemple : tri croissant sur une colonne TableViewerGlobalSorterExample.java du projet SortExamples Désactivation du tri Activation du tri
  124. 124. 124JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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(); } }); } private static class MyViewerComparer extends ViewerComparator { 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 Activation du tri Désactivation du tri
  125. 125. 125JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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, SWT.DOWN et SWT.NONE) † Pour désactiver l’affichage du tri, mettre à null la colonne à trier et mettre à NONE la direction du tri
  126. 126. 126JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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()); myTable.setSortColumn(myTable.getColumn(0)); myTable.setSortDirection(SWT.UP); } else { viewer.setComparator(null); myTable.setSortColumn(null); myTable.setSortDirection(SWT.NONE); } viewer.refresh(); } }); } ... } Affichage d’une flèche vers le haut si trier TableViewerOneColumnSorterExample.java du projet SortExamples
  127. 127. 127JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron 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()); myTable.setSortColumn(myTable.getColumn(0)); myTable.setSortDirection(SWT.UP); direction = ASC; } else if (direction == ASC) { ... } else { viewer.setComparator(null); myTable.setSortColumn(null); myTable.setSortDirection(SWT.NONE); direction = NONE; } viewer.refresh(); } }); ... } } TableViewerOneBisColumnSorterExample.java du projet SortExamples Cliquer directement sur l’en-tête de la colonne
  128. 128. 128JFace I - M. Baron - Page keulkeul.blogspot.com@mickaelbaron JFace / Viewers : Tri † Exemple : tri avec indicateurs sur colonnes cliquables TableViewerSeveralColumnSorterExample.java du projet SortExamples Tri sur la première colonne Tri sur la deuxième colonne Tri sur la troisième colonne

×