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

Eclipse : composants de visualisation (Viewer) avec JFace

Eclipse : composants de visualisation (Viewer) avec JFace

Ce support de cours s'intéresse à présenter les composants de visualisation (Viewer) de la bibliothèque JFace pour Eclipse : la partie modèle d'un Viewer via ContentProvider, le modèle graphique avec LabelProvider, gestion des colonnes via ViewerColumn, tous les composants Viewers (TableViewer, TreeViewer, TableTreeViewer, ListViewer, ComboViewer), le modèle de sélection via ISelection, les composants d'édition, la mise en place d'un CellEditor personnalisé, techniques de tri et de filtre.

Mickael BARON

January 26, 2013
Tweet

More Decks by Mickael BARON

Other Decks in Programming

Transcript

  1. Développement de clients
    riches : Plateforme Eclipse
    Mickaël BARON - 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. 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, …)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 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 !!

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  24. 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)

    View Slide

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

    View Slide

  26. 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)

    View Slide

  27. 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é

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. 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[]

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  46. 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  56. 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)

    View Slide

  57. 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é

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  93. 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  116. 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é

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  123. 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide