Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

4 JFace I - M. Baron - Page mickael-baron.fr 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 mickael-baron.fr/eclipse/intro-jface1 Des informations complémentaires peuvent être trouvées sur mon blog mickael-baron.fr

Slide 5

Slide 5 text

5 JFace I - M. Baron - Page mickael-baron.fr 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, …)

Slide 6

Slide 6 text

6 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 7

Slide 7 text

7 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 8

Slide 8 text

8 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 9

Slide 9 text

9 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 10

Slide 10 text

10 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 11

Slide 11 text

11 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 12

Slide 12 text

12 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 13

Slide 13 text

13 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 14

Slide 14 text

14 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 15

Slide 15 text

15 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : introduction TableViewer TreeViewer TableTreeViewer (TreeViewer avec colonnes)

Slide 16

Slide 16 text

16 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : introduction ListViewer ComboViewer CheckboxTreeViewer CheckboxTableViewer

Slide 17

Slide 17 text

17 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 18

Slide 18 text

18 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 19

Slide 19 text

19 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 20

Slide 20 text

20 JFace I - M. Baron - Page mickael-baron.fr 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 !!

Slide 21

Slide 21 text

21 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 22

Slide 22 text

22 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 23

Slide 23 text

23 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 24

Slide 24 text

24 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 25

Slide 25 text

25 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 26

Slide 26 text

26 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 27

Slide 27 text

27 JFace I - M. Baron - Page mickael-baron.fr 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é

Slide 28

Slide 28 text

28 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 29

Slide 29 text

29 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 30

Slide 30 text

30 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 31

Slide 31 text

31 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 32

Slide 32 text

32 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 33

Slide 33 text

33 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : Viewer Input Person - name : String - firstName : String - … + getName() : String + getFirstName() : String + … List myList ContentProvider LabelProvider Table TableViewer Concept stockant les données à afficher Les données à afficher par la table List 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[]

Slide 34

Slide 34 text

34 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 35

Slide 35 text

35 JFace I - M. Baron - Page mickael-baron.fr 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 alimentaire TableViewerExample.java du projet TableViewerExamples

Slide 36

Slide 36 text

36 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 37

Slide 37 text

37 JFace I - M. Baron - Page mickael-baron.fr 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 myPersonList = new ArrayList(); 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

Slide 38

Slide 38 text

38 JFace I - M. Baron - Page mickael-baron.fr 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 localInputElement = (ArrayList)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

Slide 39

Slide 39 text

39 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 40

Slide 40 text

40 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 41

Slide 41 text

41 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 42

Slide 42 text

42 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : ContentProvider † Hiérarchie des principales interfaces ContentProvider IContentProvider ILazyTreeContentProvider ILazyContentProvider IStructuredContentProvider ITreeContentProvider ITreePathContentProvider … 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

Slide 43

Slide 43 text

43 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 44

Slide 44 text

44 JFace I - M. Baron - Page mickael-baron.fr 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 myPersonList = new ArrayList(); myPersonList... viewer.setInput(myPersonList); ... } static class MyStructuredContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { ArrayList localInputElement = (ArrayList)inputElement; return localInputElement.toArray(); } } ... } L’input est de type List 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

Slide 45

Slide 45 text

45 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 46

Slide 46 text

46 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 47

Slide 47 text

47 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 48

Slide 48 text

48 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 49

Slide 49 text

49 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 50

Slide 50 text

50 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 51

Slide 51 text

51 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 52

Slide 52 text

52 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 53

Slide 53 text

53 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 54

Slide 54 text

54 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 55

Slide 55 text

55 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 56

Slide 56 text

56 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 57

Slide 57 text

57 JFace I - M. Baron - Page mickael-baron.fr 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é

Slide 58

Slide 58 text

58 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 59

Slide 59 text

59 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 60

Slide 60 text

60 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 61

Slide 61 text

61 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 62

Slide 62 text

62 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 63

Slide 63 text

63 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 64

Slide 64 text

64 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 65

Slide 65 text

65 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 66

Slide 66 text

66 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 67

Slide 67 text

67 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 68

Slide 68 text

68 JFace I - M. Baron - Page mickael-baron.fr 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 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)newInput; } public void dispose() {} } } Précise le nombre de ligne dans la table Ajoute un objet à la position index LazyContentProviderExample.java du projet TableViewerExamples

Slide 69

Slide 69 text

69 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 70

Slide 70 text

70 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 71

Slide 71 text

71 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : TreeViewer † Exemple : TreeViewer et ITreeContentProvider public class Job { private List myPerson; private String job; public void addPerson(Person pPerson) { myPerson.add(pPerson); pPerson.setParent(this); } public List 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

Slide 72

Slide 72 text

72 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : TreeViewer † Exemple (suite) : TreeViewer et ITreeContentProvider public class TreeViewerExample { private List myPersonWork; public TreeViewerExample() { ... TreeViewer viewer = new TreeViewer(shell, SWT.FULL_SELECTION); viewer.setContentProvider(new MyTreeContentProvider()); myPersonWork = new ArrayList(); 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) 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

Slide 73

Slide 73 text

73 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 74

Slide 74 text

74 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 75

Slide 75 text

75 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 76

Slide 76 text

76 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 77

Slide 77 text

77 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : TreeViewer † Exemple : TreeViewer et LabelProvider public class TreeViewerExample { private List 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

Slide 78

Slide 78 text

78 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 79

Slide 79 text

79 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 80

Slide 80 text

80 JFace I - M. Baron - Page mickael-baron.fr 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 children; public TreeParent(String name) { super(name); children = new ArrayList(); } 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

Slide 81

Slide 81 text

81 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 82

Slide 82 text

82 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 83

Slide 83 text

83 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 84

Slide 84 text

84 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : TableTreeViewer † Exemple (suite) : TableTreeViewer public class TreeViewerColumnExample { private List 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

Slide 85

Slide 85 text

85 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 86

Slide 86 text

86 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : ListViewer † Exemple : ListViewer en action … public class ListViewerExample { private java.util.List myPerson = new ArrayList(); 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

Slide 87

Slide 87 text

87 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 88

Slide 88 text

88 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 89

Slide 89 text

89 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 90

Slide 90 text

90 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 91

Slide 91 text

91 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 92

Slide 92 text

92 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 93

Slide 93 text

93 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 94

Slide 94 text

94 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 95

Slide 95 text

95 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 96

Slide 96 text

96 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 97

Slide 97 text

97 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 98

Slide 98 text

98 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 99

Slide 99 text

99 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 100

Slide 100 text

100 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 101

Slide 101 text

101 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 102

Slide 102 text

102 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 103

Slide 103 text

103 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 104

Slide 104 text

104 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 105

Slide 105 text

105 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 106

Slide 106 text

106 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 107

Slide 107 text

107 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 108

Slide 108 text

108 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 109

Slide 109 text

109 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 110

Slide 110 text

110 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 111

Slide 111 text

111 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 112

Slide 112 text

112 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 113

Slide 113 text

113 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 114

Slide 114 text

114 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 115

Slide 115 text

115 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 116

Slide 116 text

116 JFace I - M. Baron - Page mickael-baron.fr 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é

Slide 117

Slide 117 text

117 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 118

Slide 118 text

118 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 119

Slide 119 text

119 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 120

Slide 120 text

120 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : Filtre † Exemple : filtrer le contenu d’un TableViewer Filtre non appliqué Filtre appliqué sur les personnes végétaiens

Slide 121

Slide 121 text

121 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 122

Slide 122 text

122 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 123

Slide 123 text

123 JFace I - M. Baron - Page mickael-baron.fr 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)

Slide 124

Slide 124 text

124 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : Tri † Exemple : tri croissant sur une colonne TableViewerGlobalSorterExample.java du projet SortExamples Désactivation du tri Activation du tri

Slide 125

Slide 125 text

125 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 126

Slide 126 text

126 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 127

Slide 127 text

127 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 128

Slide 128 text

128 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 129

Slide 129 text

129 JFace I - M. Baron - Page mickael-baron.fr 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

Slide 130

Slide 130 text

130 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : Tri † Exemple (suite) : tri avec indicateurs sur colonnes cliquables public class TableViewerSeveralColumnSorterExample { ... private int direction = NONE; public TableViewerSeveralColumnSorterExample() { ... final TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION); ... TableViewerColumn refNameColumn = new TableViewerColumn(viewer, SWT.NONE); refNameColumn.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { Person currentPerson = (Person)element; return currentPerson.getName(); } }); refNameColumn.getColumn().setText("Nom"); ColumnSorter refCS = new ColumnSorter(viewer, refNameColumn) { public int columnCompare(Viewer viewer, Object e1, Object e2) { Person p1 = (Person) e1; Person p2 = (Person) e2; return p1.getName().compareToIgnoreCase(p2.getName()); } }; ... } } TableViewerSeveralColumnSorterExample.java du projet SortExamples Autant de TableViewerColumn qu’il y a de colonnes

Slide 131

Slide 131 text

131 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : Tri † Exemple (suite) : tri avec indicateurs sur colonnes cliquables public class ColumnSorter extends ViewerComparator { private ColumnViewer refViewer; private TableViewerColumn column; public static final int ASC = 1; ... private int direction = 0; public ColumnSorter(ColumnViewer pViewer, TableViewerColumn pColumn) { this.refViewer = pViewer; this.column = pColumn; this.column.getColumn().addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (ColumnSorter.this.refViewer.getComparator() != null) { if (ColumnSorter.this.refViewer.getComparator() == ColumnSorter.this) { int tdirection = ColumnSorter.this.direction; if (tdirection == ASC) { setSorter(ColumnSorter.this, DESC); } else if (tdirection == DESC) { setSorter(ColumnSorter.this, NONE); } } else { setSorter(ColumnSorter.this, ASC); } } else { setSorter(ColumnSorter.this, ASC); } } }); } Placer un écouteur sur la sélection de la colonne ColumnSorter.java du projet SortExamples

Slide 132

Slide 132 text

132 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron JFace / Viewers : Tri † Exemple (suite) : tri avec indicateurs sur colonnes cliquables public class ColumnSorter extends ViewerComparator { ... public void setSorter(ColumnSorter sorter, int direction) { if (direction == NONE) { column.getColumn().getParent().setSortColumn(null); column.getColumn().getParent().setSortDirection(SWT.NONE); refViewer.setComparator(null); } else { column.getColumn().getParent().setSortColumn(column.getColumn()); sorter.direction = direction; if (direction == ASC) { column.getColumn().getParent().setSortDirection(SWT.DOWN); } else { column.getColumn().getParent().setSortDirection(SWT.UP); } if (refViewer.getComparator() == sorter) { refViewer.refresh(); } else { refViewer.setComparator(sorter); } } } public int compare(Viewer viewer, Object e1, Object e2) { return direction * columnCompare(viewer, e1, e2); } public abstract int columnCompare(Viewer viewer, Object e1, Object e2); } ColumnSorter.java du projet SortExamples

Slide 133

Slide 133 text

133 JFace I - M. Baron - Page mickael-baron.fr mickaelbaron Bilan … † Premières impressions … † La version Eclipse 3.3 apporte la gestion des colonnes † Approche par modèles très souple † Dommage de devoir utiliser directement les objets natifs pour effec- tuer certains traitements † Le nom des colonnes (TableColumn) † Le tri, … † Le rendu des éléments et le rendu des éditeurs ne sont pas aussi souples qu’avec la boite à outils Swing † Les choses non étudiées, prochainement … † Approfondir par de nombreux exemples † Synchronisation de valeurs entre objets avec JFace Data Binding