I. Eclipse 4

I-1. Qu'est-ce que Eclipse 4 ?

Eclipse 4 introduit un ensemble de technologies visant à faciliter le développement de plug-ins. La version simultanée d'Eclipse dénommée Juno, sortie en juin 2012 a été basée sur Eclipse 4.2.

Eclipse 3.8 est sortie en même temps qu'Eclipse 4.2, mais la série Eclipse 3.x sera suspendue après la version 3.8, autrement dit il n'y aura pas de version 3.9. Eclipse 3.8 recevra des correctifs durant une année avec des versions révisées (service release).

Eclipse 4 a été l'opportunité de rationaliser le meilleur de l'API l'Eclipse 3.x et de fixer les insuffisances de développement d'Eclipse 3.x. Durant l'évolution d'Eclipse 3.x de sa version 3.0 à 3.8, de rudes expériences ont été vécues sur les difficultés et le manque de flexibilité de l'API.

Les développeurs d'Eclipse 3.x trouvent que la plupart des concepts qu'ils connaissent sont retransmis et on les retrouve dans Eclipse 4.

Les améliorations majeures d'Eclipse 4 par rapport à Eclipse 3.x sont les suivantes :

  • l'application Eclipse est décrite par une structure bien définie appelée modèle d'application ;
  • le modèle d'application peut être modifié durant le développement ou en cours d'exécution ;
  • le modèle d'application est extensible ;
  • Eclipse 4 supporte l'injection de dépendances ;
  • les Widgets Eclipse peuvent être stylés par le biais de fichiers CSS externes, à la manière de ce qui se fait avec les pages Web  ;
  • le modèle d'application est dissocié de son apparence, par exemple, différentes bibliothèques graphiques telles que SWT ou JavaFX, peuvent être utilisées pour le rendu du modèle.

Eclipse 4 fournit une couche de compatibilité qui permet aux plug-ins d'Eclipse 3.x de fonctionner sans qu'ils soient modifiés.

Les amélioration introduites par Eclipse 4 sont principalement concentrées sur le développement basé sur Eclipse. L'utilisateur d'Eclipse en tant qu'IDE, par exemple un développeur web ou Swing, ne profite qu'indirectement de ces améliorations, vue la simplicité avec laquelle s'écrivent les plugins et les outils Eclipse. Cela permet aux développeurs Eclipse de créer de meilleurs outils destinés aux utilisateurs de IDE.

I-2. Projet de la plate-forme Eclipse 4

Le projet de la plate-forme Eclipse fournit le cadre de base et les services sur lesquels se fondent toutes applications basées sur Eclipse. Il fournit également l'environnement d'exécution dans lequel les composants Eclipse sont chargés, intégrés et exécutés.

L'objectif principal du projet de la plate-forme est de permettre à d'autres développeurs de créer facilement des applications et des outils intégrés.

I-3. Qu'est-ce que le projet Eclipse e4 ?

Eclipse e4 est le nom donné pour le projet d'incubateur de la plate-forme Eclipse. Celui-ci est utilisé pour des projets préparatoires relatifs à l'amélioration de la plate-forme. La nouvelle plate-forme Eclipse 4 a été développée à l'origine au sein de l'incubateur et le nom de l'incubateur est devenu synonyme de la nouvelle plate-forme Eclipse. Aujourd'hui, le terme e4 n'est que le nom du projet.

Le projet e4 comprend plusieurs évaluations de technologie. Certaines d'entre elles ont été portées vers le Framework de base d'Eclipse. Toutes les fonctionnalités décrites dans ce tutoriel font partie de la version officielle d'Eclipse 4 à l'exception du projet Eclipse e4 tooling.

Le sous-projet Eclipse e4 tooling fournit des outils de développement d'applications Eclipse 4. Ils sont très utiles, mais ils n'ont pas été ajoutés à la version finale d'Eclipse, car ils ne sont pas aussi accomplis que les autres composants.

Des projets tels que XWT, TM ou OpenSocial Gadgets, qui font également partie du projet e4 d'Eclipse, ne sont pas inclus dans la plate-forme de base standard d'Eclipse 4.2 et ne sont pas décrits dans le présent document.

I-4. API provisoire

Actuellement, l'interface de programmation d'application (APIApplication programming interface) pour Eclipse 4 est encore marquée comme provisoire, c'est-à-dire, que l'API peut être amenée à être modifiée à l'avenir.

Eclipse 4.2 gère déjà l'IDE Eclipse au complet, donc il est peu probable que des changements importants surviennent à l'avenir.

Il est donc relativement sûr de commencer à utiliser l'API dès maintenant, mais néanmoins vous devez être préparé à l'éventualité de faire quelques ajustements à vos applications.

II. Architecture Eclipse 4

II-1. Applications basées sur Eclipse

Une application Eclipse est constituée de composants logiciels individuels. L'IDE Eclipse peut être considéré comme une application Eclipse spéciale destinée à supporter le développement de logiciels.

Les composantes de l'IDE Eclipse sont principalement les suivantes. Veuillez noter que le graphique ne représente que le concept, les relations ne sont pas d'une précision à 100 %.

Image non disponible

OSGi est une spécification qui décrit une approche modulaire pour les applications Java. Equinox est une implémentation de l'OSGi et elle est utilisée par la plate-forme Eclipse. L'environnement d'exécution Equinox fournit l'environnement nécessaire pour exécuter une application Eclipse modulaire.

SWT est la bibliothèque de composants d'interface utilisateur standard utilisée par Eclipse. JFace fournit des API pratiques plus avancées qui s'appuient sur SWT. Le Workbench fournit le cadre pour l'application. Le Workbench est responsable de l'affichage des autres composants de l'interface utilisateur.

En plus de ces éléments de base, l'IDE Eclipse ajoute des composants qui sont aussi importants pour l'IDE, par exemple les outils de développement Java (JDTJava development tools) ou le support de contrôle de version (EGIT).

Eclipse 4 dispose d'un modèle de programmation différent de celui d'Eclipse 3.x. Eclipse 4 fournit une couche de compatibilité 3.x qui se charge de mapper l'API 3.x à l'API 4.0. Ceci permet aux composants basés sur Eclipse 3.x de s'exécuter sans modification sur Eclipse 4.

Les applications basées sur Eclipse qui ne sont pas essentiellement destinées à être utilisées comme outils de développement de logiciels sont appelées applications Eclipse RCP. Une application Eclipse 4 RCP utilise généralement les composants de base de la plate-forme Eclipse auxquels s'additionnent des composants supplémentaires spécifiques à l'application.

Image non disponible

Le modèle de programmation d'OSGiOpen Services Gateway initiative (Equinox) vous permet de définir des composants logiciels dynamiques, à savoir les services OSGiOpen Services Gateway initiative, qui peuvent aussi faire partie d'une application basée sur Eclipse.

II-2. Terminologie

Une application Eclipse est constituée de plusieurs composants Eclipse. Un composant logiciel Eclipse est appelé un plug-in. Un composant logiciel dans OSGiOpen Services Gateway initiative est appelé un bundle. Les deux termes peuvent être utilisés indifféremment.

Ce tutoriel utilise les termes « application basée sur Eclipse », « application Eclipse », « application Eclipse 4 » et « application Eclipse RCP » indifféremment pour faire référence à une application qui est basée sur le Framework Eclipse 4.

Si un certain concept se réfère à Eclipse 3.x, il sera explicitement indiqué.

II-3. Fichiers de configuration importants

Un Plug-in Eclipse dispose des principaux fichiers de configuration suivants :

  • MANIFEST.MF : contient les informations de configuration OSGiOpen Services Gateway initiative ;
  • plugin.xml : contient des informations sur les mécanismes des extensions spécifiques d'Eclipse.

Un plug-in Eclipse définit son API à travers le fichier MANIFEST.MF, par exemple, les packages Java qui peuvent être utilisés par d'autres plug-ins et de leurs dépendances, par exemple les packages ou les plug-ins qui sont requis par le plug-in.

Le fichier plugin.xml offre la possibilité de définir les points d'extension et les extensions. Les points d'extension définissent les interfaces pour d'autres plug-ins afin de contribuer aux fonctionnalités. Les extensions contribuent aux fonctionnalités de ces interfaces. Ces fonctionnalités peuvent être du code et non basées sur du code.

Dans Eclipse 4, l'utilisation des extensions et des points d'extension est très limitée. Ils sont principalement utilisés pour définir des indications vers d'autres fichiers de configuration Eclipse 4.

III. Tutoriel : installer l'IDE Eclipse pour le développement RCP

III-1. Prérequis

Ce qui suit suppose que vous avez installé la version 1.6 de Java au minimum.

III-2. Télécharger et installer Eclipse 4.3

La description dans ce tutoriel est basé sur Eclipse version 4.3. Téléchargez la dernière version officiel d'Eclipse SDK disponible à partir du lien suivant.

Image non disponible Eclipse Project 4.x Stream Downloads Eclipse Project 4.x Stream Downloads

Image non disponible

Le téléchargement est un fichier zip, qui est une archive compressée de plusieurs fichiers. La plupart des systèmes d'exploitation peuvent extraire les fichiers zip, dans leur gestionnaire de fichiers. Par exemple, si vous utilisez Windows 7 comme système d'exploitation, clic droit sur le fichier dans l'explorateur et sélectionner « extraire tout … » dans le menu contextuel. Si vous hésitez sur la façon de décompresser, recherchez dans Google comment décompresser un fichier sur … , En remplaçant « … » avec votre système d'exploitation.

Ne décompressez pas Eclipse dans un dossier avec un chemin qui contient des espaces, car cela pourrait entraîner des problèmes dans le fonctionnement d'Eclipse.

Après avoir extrait le fichier zip, double-cliquez sur eclipse.exe sous Windows ou le fichier eclipse sous Linux (ou l'icône de l'exécutable spécifique à votre plate-forme) pour lancer Eclipse.

Afin d'éviter tout conflit avec le travail existant, sélectionnez un répertoire vide comme workspace pour ce tutoriel.

III-3. Installer Eclipse 4 tooling

Le téléchargement d'Eclipse SDK n'inclut pas le e4 tooling d'Eclipse, qui permet de créer des applications Eclipse 4 plus facilement. Ces outils fournissent des assistants pour créer des artefacts Eclipse 4 et l'éditeur spécialisé pour le modèle d'application.

L'auteur de ce document fournit une version récente des outils e4 pour l'Eclipse version 4.3 sous l'URL suivante.

Image non disponible http://download.vogella.com/kepler/e4tools

Vous pouvez installer les outils par le biais du menu Help → Install New Software et en entrant l'URL ci-dessus.

Sur ce site de mise à jour, installez uniquement le E4 CSS Spy et Eclipse e4 tools. Les autres entrées ne sont pas utilisées dans ce tutoriel et peuvent conduire un résultat différent.

Image non disponible

III-4. Site de mise à jour officiel

Le site de mise à jour ci-dessus a été créé pour garantir un lien stable pour le lecteur de ce tutoriel. La même base de code est utilisée par Eclipse.org pour créer un site de mise à jour officiel pour Eclipse e4 tools.

Malheureusement, le lien de ce site de mise à jour change de temps en temps, mais il peut être trouvé sur le site suivant :

Image non disponible Eclipse.org e4tools siteEclipse.org e4tools site

Si vous cliquez sur une version « Build Name », vous trouverez également le lien du site de mise à jour. Les captures d'écran suivantes illustrent le cas d'un build particulier d'e4 tools. Veuillez noter que le site pourrait changer au fil du temps.

Image non disponible
Image non disponible

IV. Tutoriel : application Eclipse 4 à l'aide de l'assistant

IV-1. Vue d'ensemble

Le projet d'Eclipse 4 tooling fournit un assistant de génération de projet qui vous permet de créer une application RCP opérationnelle basée sur Eclipse 4.

IV-2. Créer un projet

Sélectionnez  File → New → Others → Eclipse 4 → Eclipse 4 Application Project 

Créez un projet nommé com.example.e4.rcp.wizard en utilisant les paramètres par défaut. Cela devrait être similaire aux captures d'écran suivantes.

Image non disponible
Image non disponible

Sélectionnez les options « Enable development mode for application model » et « Create sample content » dans la dernière page de l'assistant. L'option mode de développement ajoute la propriété clearPersistedState au fichier de configuration du product, pour s'assurer que les changements opérés dans la structure de votre application en phase de développement soient toujours visibles à l'exécution. Avec l'option « Create sample content » vous définissez si une application Eclipse RCP minimal doit être générée ou si certains éléments supplémentaires devraient être ajoutés à celle-ci, comme une vue avec du contenu à titre d'exemple.

Image non disponible

L'assistant crée tous les fichiers nécessaires pour exécuter votre application. Le fichier essentiel pour lancer votre application est le fichier « .product », créé dans le dossier de votre projet.

IV-3. Exécuter

Ouvrez votre fichier de configuration du product com.example.e4.rcp.wizard.product en double-cliquant dessus dans l'explorateur de packages.

Image non disponible

Basculez sur l'onglet « Overview » et lancez votre product à l'aide du lien «  Launch an Eclipse application ». Cela devrait démarrer l'application Eclipse générée.

Image non disponible
Image non disponible

V. Configuration de l'exécution

V-1. vue d'ensemble

Une configuration d'exécution dans Eclipse définit l'environnement général dans lequel l'exécution aura lieu. Par exemple, elle définie les arguments de la machine virtuelle Java (VM), les dépendances du plug-in (classpath) etc. Parfois, une configuration d'exécution est appelée configuration de démarrage.

Si vous démarrez votre application Eclipse, en utilisant le lien dans le fichier product, une configuration d'exécution sera automatiquement créée.

Vous pouvez utiliser la configuration d'exécution créée directement pour ré-exécuter votre application. Les changements dans le fichier de configuration du product ne seront pas considérés.

Vous pouvez mettre à jour la configuration d'exécution en démarrant à nouveau l'application à partir de la définition du product.

Pour voir et modifier votre configuration d'exécution, sélectionnez le fichier de configuration de votre product, faites un clic droit dessus et sélectionnez Run As → Run Configuration...

Sur l'onglet principal « Main », dans le champ « Location », vous définissez l'emplacement où l'IDE Eclipse va créer tous les fichiers nécessaires pour démarrer votre application basée sur Eclipse.

Image non disponible

V-2. Paramètres d'exécution

La configuration d'exécution vous permet d'ajouter des paramètres supplémentaires pour votre application sur l'onglet « Arguments ». Par défaut, le paramètre -consoleLog est inclus. Cela va écrire les messages d'erreur de l'instance d'application en cours d'exécution dans la vue console de votre IDE Eclipse.

Image non disponible

La tableau ci-dessous énumère les paramètres d'exécution utiles

Tableau 1. Paramètres d'exécution
Paramètre Description
consoleLog Les messages d'erreur de l'application Eclipse en cours d'exécution sont écrits dans la vue console de l'IDE Eclipse depuis le début de l'exécution de cette application.
nl Spécifie la langue d'exécution de votre application. Par exemple, « -nl en » va démarrer votre application en langue anglaise. Très utile pour tester des traductions.
Console donne accès à une console OSGi où vous pouvez suivre le statut de votre application.
noExit Maintient la console OSGi ouverte même si l'application se plante.
clearPersistedState Supprime les modifications du modèle d'application survenues lors de l'exécution.

VI. Problèmes de configuration d'exécution communs

VI-1. Problème d'exécution n° 1 : plug-ins manquants

Les erreurs dans la configuration d'exécution des applications RCP sont fréquemment la source de problèmes.

Le problème le plus courant est que certains plug-ins requis sont manquants dans votre product. Si vous utilisez les «features » , vous devez vous assurer que tous les plug-ins y afférant mentionnés dans le fichier MANIFEST.MF sont également inclus dans vos «features ».

Eclipse peut vérifier pour vous les dépendances manquantes automatiquement avant chaque démarrage. Dans l'onglet Plug-ins, cochez l'option « Validate plug-ins prior to launching ». Cela va vérifier si vous avez tous les plug-ins requis dans votre configuration d'exécution.

Si cette vérification mentionne que certains plug-ins sont manquants, essayez de cliquer sur le bouton « Add Required Plug-Ins ». Assurez-vous aussi d'ajouter toutes les dépendances dans votre product.

Image non disponible

Ensuite, vous devez ajouter le plug-in manquant à vos features ou votre product (si le product n'est pas basé sur les features).

VI-2. Liste des problèmes communs

Le tableau ci-dessous liste les problèmes potentiels et leurs solutions.

Tableau 2. Problèmes de la configuration d'exécution
Problèmes examiner
Lors du démarrage vous obtenez des messages d'erreur tels que « One or more bundles are not resolved because the following root constraints are not resolved  » ou « java.lang.RuntimeException: No application id has been found.  » Vérifiez que tous les plug-ins sont inclus dans votre configuration d'exécution. Assurez-vous que votre produit définit les dépendances à tous les plug-ins ou les features.
Les bundles peuvent aussi exiger une certaine version de la machine virtuelle Java, par exemple, un bundle peut exiger Java 1.6 et ne sera donc pas chargé dans une machine virtuelle Java 1.5. Vérifiez quelle est la version java requise dans le fichier MANIFEST.MF sur l'onglet « Overview » et dans la section Environnements d'Exécution.
Comportement étrange, mais aucun message d'erreur. Vérifiez si votre configuration d'exécution contient le paramètre -consoleLog . Cette option vous permet de voir les erreurs de l'application basée sur Eclipse dans la console de votre IDE Eclipse.
Souvent des plug-ins sont manquants dans la Configuration d'exécution Assurez-vous que votre product ou votre feature(s) comprend toutes les dépendances nécessaires.
Un changement dans les dépendances du product, par exemple un nouveau plug-in a été ajouté mais il n'a pas été inclus dans la configuration d'exécution. Un product met à jour une configuration d'exécution existante seulement si vous exécutez le produit directement à partir du fichier de définition du product. Si vous sélectionnez la configuration d'exécution directement, il ne sera pas mis à jour.
Les changements du modèle d'application ne sont pas pris en compte dans l'application Eclipse 4 Eclipse 4 sauvegarde les modifications de l'utilisateur dans le modèle d'application. Au cours du développement cela peut conduire à des situations où les changements du modèle ne sont pas appliqués correctement au modèle en mode exécution. Par exemple vous définissez un nouvel élément dans le menu et celui-ci n'est pas affiché dans votre application. Soit vous cochez l'option « Clear » sur l'onglet « Main » dans votre configuration d'exécution ou vous ajoutez le paramètre -clearPersistedState dans le fichier de configuration de votre product ou de la configuration d'exécution.
Les raccourcis clavier et la sélection ne fonctionnent pas dans l'application Eclipse 4 Veillez à ce que chaque partie implémente correctement @Focus. Eclipse 4.2 exige qu'un seul contrôle ait le focus. Eclipse 4.3 corrige cela.
Les éléments de menu sont désactivés dans Eclipse 4.3 build. Eclipse 4.3 introduit un nouveau modèle addon que vous devez enregistrer avec votre modèle d'application. Si vous utilisez Eclipse 4.3, assurez-vous que votre modèle d'application dispose d'une entrée pointant vers la classe HandlerProcessingAddon dans le package org.eclipse.e4.ui.internal.workbench.addons. Le nom symbolique du bundle est org.eclipse.e4.ui.workbench.
Application "org.eclipse.ant.core.antRunner" could not be found in the registry ou Application "" could not be found in the registry. Assurez-vous que vous avez appuyé sur le bouton « New » dans le fichier de configuration du product et sélectionnez la E4Application comme application à lancer. Vous pouvez vérifier les paramètres actuels dans le fichier plugin.xml sur l'onglet Extensions et dans les détails de l'extension org.eclipse.core.runtime.products.

VII. Modèle d'application Eclipse 4

VII-1. Qu'est-ce que le modèle d'application

La partie visuelle d'une application Eclipse se compose de perspectives, de parts (vues et éditeurs), menus, barres d'outils, etc. Une application Eclipse comprend également des composants non-visuels, par exemple les Handlers, les commandes et les raccourcis clavier.

Eclipse 4 utilise une description abstraite, appelée modèle d'application, pour décrire la structure d'une application. Ce modèle d'application contient les éléments visuels ainsi que certains éléments non-visuels de l'application Eclipse 4.

Chaque élément du modèle possède des attributs qui décrivent son état actuel, par exemple la taille et la position pour une fenêtre. Les éléments du modèle pourraient être dans un ordre hiérarchique, par exemple les vues et éditeurs peuvent être regroupés sous une perspective.

Le modèle d'application définit la structure de l'application, il ne décrit pas le contenu particulier des composants de l'interface utilisateur.

Par exemple, le modèle d'application décrit quelles sont les parts disponibles. Il décrit également les propriétés de celles-ci, par exemple si une part peut être fermée, son titre, ID, etc.

Mais il ne décrit pas le contenu de la part elle-même, par exemple, les labels, les champs texte et boutons qui la composent. Le contenu de la part est toujours défini avec du code source.

Si le modèle d'application était une maison, il décrirait les chambres disponibles (parts) et leurs dispositions (Perspectives, PastStacks, PartSashContainer), mais pas le mobilier dans les chambres. Cela est illustré par l'image ci-dessous.

Image non disponible

VII-2. Où le modèle d'application est-il défini ?

Le modèle d'application est extensible. La base de ce modèle est généralement définie comme un fichier statique. Le nom par défaut de ce fichier est Application.e4xmi et l'emplacement par défaut est le répertoire principal de votre application plug-in.

Vous pouvez modifier le nom par défaut et l'emplacement par le point d'extension de org.eclipse.core.runtime.products. Avec le paramètre applicationXMI, vous spécifiez l'emplacement et le nom de fichier du modèle. Voir l'annexe pour une description détaillée de cette procédure.

Le fichier XMI est lu au lancement de l'application et le modèle d'application initial est construit à base de cette image.

VII-3. Comment le modèle est-il relié à mes classes Java ?

Les éléments du modèle d'application peuvent faire référence à des classes Java par le biais d'identifiants de ressources uniformes (URI).

L'URI définit l'emplacement de la classe Java. La première partie de cet URI est le plug-in, la deuxième le package et la dernière la classe.

Par exemple, une description du modèle pour une part contient des attributs tels que des libellés, des info-bulles et les URIs des icônes. Il contient également un URI qui pointe vers une classe Java pour cet élément. Cette classe fournit le comportement de la part, à l'aide de l'exemple maison/chambres cité plus haut, la classe est chargée de définir les meubles et leurs agencements dans la pièce et la façon dont les objets interactifs se comportent.

Si les éléments du modèle sont activés, cette classe va s'instancier.

Les objets créés basés sur le modèle d'application sont appelés des « objets de modèle ».

VII-4. URI dans le modèle

Les URIs suivent l'un des deux schémas, l'un pour l'identification des ressources et l'autre pour l'identification des classes. Le tableau suivant décrit ces deux schémas. L'exemple suppose que le bundle est appelé test.

Tableau 3. Schéma d'URI
Schéma Description
bundleclass://Bundle-SymbolicNam/package.nom-classe
Exemple:
bundleclass://test/test.parts.MySavePart
Utilisé pour identifier les classes Java. Il se compose des éléments suivants: «bundleclass://» est un schéma, Bundle-SymbolicNam fixe tel que défini dans le fichier MANIFEST.MF, et le nom qualifié complet de classe.
platform:/plugin/Bundle-SymbolicNam/ chemin/nom-du-fichier.extension
Exemple:
platform:/plugin/test/icons/save_edit.gif
Identifiant pour une ressource dans le plug-in. "platform:/plugin/» est un schéma fixe, suivie par le Bundle-SymbolicNam du fichier MANIFEST.MF, suivi par le chemin d'accès au fichier et du nom du fichier.

VII-5. Éditeur du modèle d'application

Le projet Eclipse tooling fournit un éditeur qui rend plus facile la tâche de travailler sur un modèle d'application.

Pour ouvrir l'éditeur de modèle double-cliquez sur le fichier Application.e4xmi (clique-droit sur le fichier et sélectionnez Open With → Eclipse 4 model editor

Image non disponible

L'éditeur de modèle dispose de plusieurs réglages de préférences accessibles depuis Window → Preferences → Model Editor. La capture d'écran ci-dessous montre la page des préférences.

Image non disponible

VII-6. Accès au modèle lors de l'exécution

Le modèle d'application est également disponible en mode exécution. L'application peut accéder au modèle et le modifier par l'intermédiaire d'une API bien définie.

Ajouter le plug-in org.eclipse.e4.tools.emf.liveeditor et ses dépendances à votre configuration d'exécution, pour rendre l'éditeur de modèle utilisable dans votre application.

Ensuite, vous pouvez ouvrir l'éditeur de modèle dans votre application en cours d'exécution avec la combinaison de touches Alt + Maj + F9. Ceci fonctionne également pour l'IDE 'Eclipse 4 lui-même.

Pour ouvrir l'éditeur directement dans votre application Eclipse 4, il faudrait au préalable configurer les raccourcis clavier dans votre application.

Vous pouvez modifier le modèle de votre application directement à l'exécution en utilisant l'éditeur de modèle. La plupart des changements sont immédiatement appliqués, par exemple si vous changez l'orientation d'une PartSashContainer. Votre interface utilisateur se mettra à jour automatiquement. Si vous modifiez le modèle de l'IDE Eclipse vous devez être prudent, car cela pourrait mettre l'instance de IDE eclipse en cours d'exécution dans un mauvais état.

Dans l'éditeur de modèle temps réel (live editor), vous pouvez sélectionner un élément de la part. Faites un clic droit dessus et sélectionnez Show Control pour voir la part en surbrillance.

VII-7. Méta-modèle du modèle d'application

La structure possible du modèle d'application est défini par un méta-modèle créé avec l'Eclipse Modeling Framework (EMF). Un méta-modèle décrit la structure d'un modèle de données, par exemple, il définit les propriétés que possède une part.

EMF est un Framework de modélisation très populaire destiné à un usage général. Il est à la base de plusieurs projets basés sur Eclipse. EMF permet de générer des classes Java à partir d'un méta-modèle.

Eclipse EMF utilise un fichier .ecore pour définir le méta-modèle.

Le méta-modèle de l'application Eclipse 4 est stocké dans le plug-in org.eclipse.e4.ui.model.workbench qui se trouve dans le dossier du modèle. La définition du modèle de base peut être trouvée dans le fichier UIElements.ecore. Les classes du modèle d'Eclipse 4 sont générées sur la base de ce modèle.

Si vous voulez scruter ce modèle, vous pouvez installer EMF tools à l'aide du gestionnaire de mise à jour d'Eclipse et importer la définition du plug-in dans votre espace de travail. Pour importer un plug-in à partir de votre actuelle plate-forme prévue (par défaut c'est l'IDE 'Eclipse) dans votre espace de travail, utilisez la vue Plug-ins, cliquez-droit sur un plug-in et sélectionnez Import As → Source Project.

Le fichier Application.e4xmi, qui décrit le modèle d'application Eclipse, est une version persistante d'un modèle EMF.

VII-8. Création du modèle d'application d'exécution

Lors du démarrage, l'environnement d'exécution Eclipse crée le modèle d'application en se basant sur le fichier Application.e4xmi et instancie les classes mentionnées dans le modèle si nécessaire.

Le cycle de vie de chaque objet du modèle est donc contrôlé par l'environnement d'exécution d'Eclipse. Celui-ci instancie et détruit les objets du modèle.

VIII. Attributs persistants du modèle

VIII-1. Tags

L'onglet Supplementray dans l'éditeur de modèle permet de saisir des informations additionnelles sur un élément du modèle.

Tous les éléments du modèle nous donnent la possibilité de leur attribuer des tags. Ces tags peuvent être utilisés par la plateforme Eclipse pour sélectionner les éléments du modèle apparentés à l'aide du ModelService. Par défaut Eclipse utilise des tags prédéfinis pour déterminer l'état de certains éléments du modèle. Par exemple, les tags shellMaximized et shellMinimized dans une fenêtre sont utilisés par Eclipse afin de déterminer si la fenêtre doit être maximisée ou minimiserée.

La capture d'écran ci-dessous montre comment définir une fenêtre maximiser.

Image non disponible

Un autre tag qui est fréquemment utilisé est NoAutoCollapse que vous pouvez ajouter à un conteneur PartStack. Avec cette option le PartStack ne va pas se réduire, même si vous supprimez toutes ses parts.

Image non disponible

Les tags sont automatiquement rendus persistants par l'environnement d'exécution d'Eclipse entre les redémarrages de l'application et ils sont représentés comme une collection de chaînes.

Consultez l'annexe de ce tutoriel pour plus de tags

VIII-2. État persistant

Les éléments du modèle peuvent aussi avoir un état persistant. Si vous retrouvez l'élément du modèle, vous pouvez avoir et définir son état persistant.

 
Sélectionnez
// modelObject est l'objet du model 
// retrouvé à l'aide de l'injection de dépendance (ex. an MPart)

// Avoir l'état avec la clé "yourKey"
String state = modelObject.getPersistedState().get(yourKey);

// sauvegarder l'état
modelObject.getPersistedState().put(yourKey, state) ;

Les données persistantes pour les éléments du modèle sont automatiquement restaurées par l'application Eclipse entre les redémarrages de celle-ci et permet de stocker les paires clés/valeurs sous forme de chaînes.

IX. Vue d'ensemble des éléments de modèle disponibles

Les éléments de modèle ont des classes Java qui leur sont associées. Comme le modèle est interactif, vous pouvez utiliser ces éléments de modèle pour modifier leurs attributs ou ceux de leurs enfants.

Le tableau ci-dessous énumère les éléments de modèle importants basés sur leurs classes Java. Ces éléments de modèle peuvent également être obtenus par injection.

Tableau 4. Élément du modèle
Élément de modèle Description
MApplication Décrit l'objet application. Il peut être utilisé par exemple pour ajouter de nouvelles fenêtres à votre application.
MWindow Représente une fenêtre dans votre application.
MTrimmedWindow Représente une fenêtre dans votre application. La fenêtre SWT sous-jacente a été créée avec l'attribut SWT.SHELL_TRIM qui signifie qu'elle a un titre et les boutons minimiser, maximiser et redimensionner.
MPerspective Objet pour l'élément de modèle perspective.
MPart Représente l'élément du modèle Part, par ex. ça peut être une vue ou d'un éditeur.
MDirtyable Propriété de MPart qui peut être injectée. Si elle est définie à vrai, cette propriété indique à la plate-forme Eclipse que cette part contient des données qui ne doivent pas être sauvegardées (brouillon). Dans un handler vous pouvez interroger cette propriété pour déclencher une sauvegarde.
MPartDescriptor MPartDescriptor est un gabarit pour les nouvelles parts. Vous définissez un PartDescriptor dans votre modèle d'application. Une nouvelle part basée sur ce PartDescriptor peut être créée via le EPartService et affichée par sa méthode showPart ().
Snippets Les Snippets peuvent être utilisés pour pré-configurer les parts du modèle que vous souhaitez créer à partir de votre programme. Vous pouvez utiliser EcoreUtil.copy pour copier un Snippet et l'affecter à un autre élément du modèle. Par exemple, sur un MSash vous pouvez ajouter un MStack nouvellement copié appelé copie, avec getChildren().add(copie). Aussi le service du modèle a des méthodes pour créer et cloner un Snippet.

X. Identifiants pour les éléments du modèle

X-1. Identifiants pour les éléments du modèle

Chaque élément du modèle vous permet de lui définir un ID. Cet identifiant est utilisé par le Framework Eclipse pour identifier cet élément de modèle. Assurez-vous d'attribuer toujours un ID pour tous les éléments du modèle et que ces identifiants sont uniques.

Par conséquent, assurez-vous que tous vos éléments de modèle ont un ID qui leur est assigné.

X-2. Bonnes pratiques pour les conventions de nommage

Ce qui suit évoque les bonnes pratiques pour les conventions de nommage, qui sont également utilisées dans ce tutoriel.

Tableau 5. Convention de nommage
Objet Description
Noms de projet Le nom du projet plug-in est le même que le nom du package de haut niveau.
Package Pour un plug-in qui contient beaucoup de composants d'interface utilisateur utiliser des sous-packages basés sur l'usage principal des composants. Par exemple, le package com.exemple peut avoir les sous-packages com.exemple.parts et com.example.handler.
noms de classes pour les éléments du modèle Utilisez le mot définissant l'usage principal de l'élément de modèle comme suffixe dans le nom de la classe. Par exemple, une classe qui représente une part qui affiche les objets Todo, pourrait être appelée TodoOverviewPart.
IDs Définir des règles claires pour nommer les IDs dans le fichier plugin.xml.
Les IDs devraient toujours commencer par le package de haut niveau. Le cas échéant, utilisez le sous-package qui implémente la classe. Le reste de l'ID doit être évocateur de l'usage du composant. Par exemple: «com.exemple.parts.todolist".
l'ID devrait être en minuscules (certains projets Eclipse utilisent camelCase pour la dernière partie de l'ID).

XI. Features et Products

La description suivante utilise les projets « features » et les products, veuillez consulter Feature projects et Eclipse Products and Deployment pour une description bien détaillée de ces sujets.

Les deux articles auxquels fait référence ce chapitre seront incessamment traduits.

XII. Tutoriel : Créer un plug-in Eclipse

Dans Eclipse sélectionnez File → New Project → Plug-in Development → Plug-in Project.

Image non disponible

Donnez à votre plug-in le nom com.example.e4.rcp.todo.

Image non disponible

Cliquez sur Suivant et effectuez les réglages suivants. Sélectionnez Non à la question Would you like to create a rich client application et décochez This plug-in will make contributions to the UI. Décochez l'option Generate an activator, a Java class that controls the plug-ins life-cycle.

Image non disponible

Appuyez sur le bouton Finish ; nous n'utiliserons pas de gabarit.

XII-1. Valider le résultat

Ouvrez le projet et vérifiez si des classes Java ont été créées. Vous ne devriez pas avoir de classes dans le dossier source (src).

Ouvrez le fichier MANIFEST.MF et basculez sur l'onglet Extensions. Confirmez que la liste des extensions est vide.

XIII. Tutoriel : d'un Plug-in à une application Eclipse 4

Dans ce chapitre, nous allons convertir le plug-in en application Eclipse 4.

XIII-1. Créer une configuration product

Créez un nouveau projet appelé com.example.e4.rcp.todo.product de type projet → Général .

Image non disponible

Faites un clic droit sur ce projet et sélectionnez New → Product Configuration. Créez un fichier de configuration de product todo.product.

Image non disponible
Image non disponible

Appuyez sur le bouton New de l'onglet Overview de l'éditeur du product.

Image non disponible

Entrez to-do comme nom, defining plug-in est votre plug-in et utilisez le nom product comme ID. Sélectionnez comme application la classe E4Application

Image non disponible

XIII-2. Créer un projet feature

Créez un nouveau projet feature appelé com.example.e4.rcp.todo.feature.

Image non disponible

Inclure le plug-in com.example.e4.rcp.todo dans ce feature dans le fichier feature.xml.

Image non disponible

XIII-3. Entrer les dépendances des features dans le product

Modifiez le fichier de configuration de votre product pour utiliser les features. Pour ce, ouvrez le fichier de configuration de votre product et sélectionnez l'option features sur l'onglet Overview dans l'éditeur du product.

Image non disponible

Sélectionnez l'onglet Dependencies et ajoutez les features org.eclipse.e4.rcp et com.example.e4.rcp.todo.feature comme des dépendances avec le bouton Add.

Image non disponible

Cliquez sur le bouton Add Required. Cela ajoutera aux dépendances les fetaures org.eclipse.emf.common et org.eclipse.emf.ecore.

Veillez à ce que, après cette étape, vous ayiez un total de quatre features dans le fichier de configuration de votre product. Si vous ne pouvez pas ajouter des features à votre product, assurez-vous que vous ayiez changé votre product pour qu'il soit basé sur les features.

XIII-4. Retirer la dépendance de version depuis les features dans le product

Pour éviter les problèmes de dépendance avec les différentes versions du plug-in org.eclipse.e4.rcp, supprimez le numéro de version de vos features. Vous pouvez le faire avec le bouton Properties dans l'onglet Dependencies de l'éditeur du fichier de configuration du product.

Image non disponible
Image non disponible

XIII-5. Créer le modèle d'application

Sélectionnez File → New → Other... → Eclipse 4 → Model → New Application Model pour ouvrir l'assistant. Entrez votre application comme conteneur et le nom de fichier suggéré par l'assistant.

Image non disponible

Cela va créer le fichier Application.e4xmi et l'ouvrir avec l'éditeur du modèle d'application.

XIII-6. Ajouter des éléments dans le modèle d'application

Ajoutez une fenêtre à votre modèle d'application pour avoir un composant visuel.

Sélectionnez le nœud Windows, puis appuyez sur le bouton Add pour TrimmedWindow.

Image non disponible

Entrez un ID, la position et la taille de la fenêtre et un libellé comme indiqué sur la capture d'écran ci-dessous.

Image non disponible

XIII-7. Démarrer l'application

Ouvrez le fichier product et basculez sur l'onglet Overview. Cliquez sur le lien Launch an Eclipse application dans la section Testing.

Image non disponible

Vérifiez que votre application démarre. Elle devrait se présenter comme une fenêtre vide, qui peut être déplacée et fermée.

XIII-8. Ajouter les dépendances du plug-in

Dans les exercices à venir, vous allez utiliser les fonctionnalités des autres plug-ins Eclipse. Cela nécessite que vous définissiez une dépendance à ces plug-ins dans votre application. Les détails exacts de cette approche modulaire seront abordés dans un chapitre ultérieur.

Ouvrez votre fichier META-INF/MANIFEST.MF et sélectionnez l'onglet Dependencies. Utilisez le bouton Add dans la section Required Plug-ins pour ajouter les plug-ins suivants comme dépendances.

  • org.eclipse.core.runtime
  • org.eclipse.swt
  • org.eclipse.e4.core.di
  • org.eclipse.e4.ui.workbench
  • org.eclipse.e4.ui.di
  • org.eclipse.e4.core.di.extensions

XIII-9. Ajouter les dépendances aux packages

Ajoutez également javax.annotation et javax.inject comme dépendances de packages.

Image non disponible

Assurez-vous qu'en général les packages ajoutés comme dépendances javax.annotation, ainsi que javax.inject, soient tous les deux d'une version 1.0.0 au minimum. Sinon, votre application ne fonctionnera pas correctement dans les exercices ultérieurs.

XIII-10. Ajustez votre fichier .projet pour le product

Vous pouvez également ajouter la nature pde Plug-in Development Environment à votre projet dans lequel vous avez placé le fichier de configuration du product, si vous voulez être en mesure de démarrer votre product directement avec un clic-droit sur le product et en sélectionnant Run As → Eclipse Application

 
Sélectionnez
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
  <name>com.example.e4.rcp.todo.product</name>
  <comment></comment>
  <projects>
  </projects>
  <buildSpec>
    <buildCommand>
      <name>org.eclipse.pde.ManifestBuilder</name>
      <arguments>
      </arguments>
    </buildCommand>
    <buildCommand>
      <name>org.eclipse.pde.SchemaBuilder</name>
      <arguments>
      </arguments>
    </buildCommand>
  </buildSpec>
  <natures>
    <nature>org.eclipse.pde.PluginNature</nature>
  </natures>
</projectDescription> 

La vue Explorateur de package peut avoir un ensemble de filtres pour *.Ressources. Vous pouvez modifier ce filtre par le menu d'affichage comme le montre la capture d'écran ci-dessous.

Image non disponible

XIV. Éléments de modèle importants dans l'Interface utilisateur

Les éléments de modèle suivants sont les éléments de base que vous utiliserez pour créer l'interface utilisateur de votre application.

XIV-1. Fenêtres (Windows)


Une application Eclipse consiste en une ou plusieurs fenêtres. Généralement, une application a une seule fenêtre, mais vous n'êtes pas limité à cela, par exemple, si vous souhaitez gérer un affichage multiple sur deux moniteurs.

Image non disponible

XIV-2. Les Vues et éditeurs (Parts)

Les parts sont des composants d'interface utilisateur qui vous permettent de naviguer et modifier les données. Les parts sont généralement divisées en vues (views) et éditeurs (editors).

La distinction entre les vues et les éditeurs n'est pas fondée sur des différences techniques, mais sur le concept d'utilisation et d'agencement qui est différent.

Une vue est généralement utilisée pour travailler sur un ensemble de données, qui pourraient être une structure hiérarchique. Si des données sont modifiées par la vue, ce changement est généralement appliqué directement à la structure de données. Une vue vous permet parfois d'ouvrir un éditeur pour les données sélectionnées.

L'exemple-type d'une vue est l‘explorateur de package, qui vous permet de parcourir les fichiers des projets Eclipse. Si vous modifiez des données dans l'explorateur de packages, par exemple le changement du nom d'un fichier, cette opération se répercute directement sur le système de fichiers.

Les éditeurs sont usuellement utilisés pour modifier un seul élément de données, par exemple un fichier ou un objet de données. Pour appliquer les modifications apportées par l'éditeur à la structure de données, l'utilisateur doit explicitement sauvegarder le contenu de l'éditeur.

Les éditeurs et les vues peuvent être positionnés librement dans l'interface utilisateur.

Par exemple, l'éditeur de code Java est utilisé pour modifier les fichiers sources. Les modifications apportées au fichier source sont appliquées une fois que l'utilisateur sélectionne la commande Enregistrer. Un éditeur modifié est marqué d'un astérisque.

XIV-3. Perspective

Une perspective est un conteneur visuel pour un ensemble de parts. Vous pouvez basculer entre différentes perspectives dans votre application Eclipse RCP avec le service EPartService.

XIV-4. PartStacks et PartSashContainers

Les parts peuvent être directement assignées à une fenêtre ou à une perspective. Si vous souhaitez regrouper et organiser les parts, vous pouvez utiliser PartStacks et PartSashContainers.

Les PartStacks contiennent une pile de parts dont une seule est visible à la fois, les parts peuvent être sélectionnées à l'aide d'onglets. Les PartSashContainer affichent tous ses enfants en même temps en mosaïque horizontale ou verticale.

La capture d'écran suivante montre une application Eclipse avec une disposition simple qui utilise deux PartSashContainers et quelques PartStacks.

Image non disponible

Dans le niveau supérieur de cette disposition, il y a un PartSashContainer horizontal qui contient un autre PartSashContainer et quelques PartStacks. La structure est représentée dans le graphique suivant.

Image non disponible

XV. Configurer la suppression des données persistantes du modèle

Eclipse 4 sauvegarde certaines modifications effectuées par l'utilisateur dans votre application. Durant le développement, cela peut conduire à des situations où les changements ne sont pas correctement appliqués à l'affichage. Par exemple, vous définissez un nouvel élément de menu et celui-ci ne s'affiche pas dans votre application.

Soit vous mettez l'option clear sur l'onglet Principal dans votre configuration d'exécution, soit vous ajoutez le paramètre clearPersistedState au fichier de configuration de votre product ou de la configuration d'exécution.

La capture d'écran ci-dessous montre ce paramètre dans le fichier de configuration du product.

Image non disponible

Il est recommandé de définir cela pendant votre phase de développement afin d'éviter tout comportement inattendu. Veuillez noter que les paramètres doivent être précédés par le signe -, par exemple, -clearPersistedState.

Si vous ignorez cette étape, les changements dans le modèle d'application ne sont pas visibles au redémarrage de votre application, car Eclipse restaure le dernier état de votre application.

XVI. Tutoriel : Modélisation d'une interface utilisateur

XVI-1. Objectif

Cette section donne une description sommaire des étapes que vous allez faire dans ce tutoriel, qui consiste en la création d'une interface utilisateur modélisée de votre application Eclipse 4.

L'objectif est de créer l'interface utilisateur suivante.

Image non disponible

La description qui suit est juste un bref exposé. Les étapes détaillées seront approfondies dans les sections qui suivent.

Cela nécessite la création de plusieurs PartSashContainer et PartStacks. Chaque PartStacks contient actuellement une seule part.

Bien que ce ne soit pas un élément de modèle obligatoire, vous pouvez aussi ajouter une perspective à votre modèle d'application afin que vous puissiez facilement ajouter d'autres perspectives.

XVI-2. Créer les éléments conteneurs du modèle

Ouvrez le fichier Application.e4xmi. Accédez à votre fenêtre to-do et sélectionnez le nœud Controls. Ajoutez un PerspectiveStack. Appuyez sur le bouton Add pour créer un élément Perspective.

Entrez la valeur de To-Do dans le champ Label et com.example.e4.rcp.todo.perspective pour le champ ID.

Image non disponible

Sélectionnez Controls en-dessous de la perspective qui vient d'être créée et ajoutez un PartSashContainer. Changez son attribut Orientation à Horizontal.

Image non disponible

Dans la liste déroulante du PartSashContainer, sectionnez PartStack et appuyez sur le bouton Add.

Sélectionnez à nouveau le PartSashContainer parent et ajoutez un autre PartSashContainer. Maintenant, ajoutez deux PartStacks au deuxième PartSashContainer.

Après ces changements, votre modèle d'application devrait ressembler à la capture d'écran ci-dessous.

Image non disponible

XVI-3. Création des parts

Ajoutez un composant Part à chaque PartStack. Comme ID, utilisez le préfixe com.example.e4.rcp.todo.part suivi des suffixes énumérés dans le tableau suivant.

Tableau 6. Libellé et ID des parts
Suffixe Label
*.todooverview To-Dos
*.tododetails Details
*.playground Playground

La capture d'écran ci-dessous montre les données d'une Part.

Image non disponible

Démarrez votre product et assurez-vous que l'interface utilisateur ressemble à ce qui est prévu. Réaffectez vos Parts à d'autres PartStacks, si nécessaire. L'éditeur de modèle prend en charge le glisser-déplacer pour la réaffectation.

Notez que vous n'avez pas encore créé de classes Java pour votre application.

XVI-4. Création des classes Java et connexion au modèle

Vous allez maintenant créer des objets Java et les relier au modèle d'application.

Créez le package com.example.e4.rcp.todo.parts.

Créez trois classes Java appelées TodoOverviewPart, TodoDetailsPart et PlaygroundPart dans ce package. Ces classes n'étendent pas d'autres classes et n'implémentent aucune interface.

Le code suivant montre la classe TodoDetailsPart.

TodoDetailsPart
Sélectionnez
package com.example.e4.rcp.todo.parts;

public class TodoDetailsPart {
}

Ouvrez le fichier Application.e4xmi et connectez les classes avec les objets de modèle correspondants. Vous pouvez le faire via la propriété de la Class URI de l'élément de modèle Part.

Le tableau suivant donne un aperçu des éléments qui doivent être connectés.

Tableau 7.Connexion des classes Java avec les éléments du modèle
Classes Suffixe de la Part
TodoOverviewPart *.todooverview
TodoDetailsPart *.tododetails
PlaygroundPart *.playground

L'éditeur de modèle d'Eclipse 4 vous permet de rechercher une classe existante via le bouton Find... . La liste initiale est vide, commencez à taper le nom d'une classe pour voir les résultats.

Image non disponible

XVI-5. Test

Exécutez votre application. Elle devrait démarrer, mais vous ne verrez aucune différence dans votre interface utilisateur.

Pour s'assurer que les objets du modèle ont été créés par le runtime d'Eclipse, créez un constructeur sans arguments pour l'une des classes et ajoutez une instruction System.out.println(). Vérifiez ensuite que le constructeur est appelé, une fois que vous avez lancé votre application.

XVI-6. Mise en page

Utilisez la propriété Container Data du modèle pour attribuer une largeur relative de 40 pour le conteneur de gauche et 60 à celui de droite.

Image non disponible

En conséquence, le conteneur gauche devrait utiliser 40% de l'espace disponible.

Image non disponible

XVII. Tutoriel: Utiliser le widget navigateur SWT

XVII-1. Implémentation

Dans ce tutoriel vous allez afficher une carte Google dans le widget navigateur SWT.

Cet exercice ne fonctionne pas toujours sous le système Linux

Changez la classe PlaygroundPart de sorte que la part ressemble à la capture d'écran ci-dessous.

Image non disponible

XVII-2. Solution

AU final, votre classe Playground devrait ressembler au code suivant.

 
Sélectionnez
package com.example.e4.rcp.todo;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.annotation.PostConstruct;

import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

public class PlaygroundPart {
  private Text text;
  private Browser browser;

  @PostConstruct
  public void createControls(Composite parent) {
    parent.setLayout(new GridLayout(2, false));

    text = new Text(parent, SWT.BORDER);
    text.setMessage("Enter City");
    text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

    Button button = new Button(parent, SWT.NONE);
    button.setText("Search");
    button.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        String city = text.getText();
        if (city == null || city.length() == 0) {
          return;
        }
        try {
          browser.setUrl("http://maps.google.com/maps?q="
              + URLEncoder.encode(city, "UTF-8")
              + "&output=embed");
        } catch (UnsupportedEncodingException e1) {
          e1.printStackTrace();
        }
      }
    });

    browser = new Browser(parent, SWT.NONE);
    browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));

  }

  @Focus
  public void onFocus() {
    text.setFocus();
  }
} 

XVIII. Injections de dépendances et annotations

XVIII-1. Qu'est-ce que l'injection de dépendances

Le concept général de l'injection de dépendances est appelé inversion de contrôle. Une classe ne doit pas configurer ses dépendances, mais doit être configurée de l'extérieur.

L'injection de dépendances est un concept qui ne se limite pas à Java. Mais nous nous pencherons sur l'injection de dépendances d'un point de vue Java.

Une classe Java a une dépendance à une autre classe si elle utilise une instance de cette classe, par exemple, par l'appel du constructeur ou par l'appel d'une méthode statique. Par exemple, une classe qui accède à un service logger a une dépendance sur la classe de ce service.

Idéalement, les classes Java doivent être indépendantes, dans la mesure du possible, des autres classes Java. Cela augmente la possibilité de leur réutilisation et le pouvoir de les tester indépendamment des autres classes, par exemple pour les tests unitaires.

Si une classe Java instancie directement une autre classe à l'aide de l'opérateur new, elle ne peut pas être utilisée et testée de façon indépendante à partir de cette classe.

Pour découpler les classes Java, leurs dépendances doivent être définies de l'extérieur. Une classe Java doit tout simplement définir ses exigences, comme on peut le voir dans l'exemple suivant :

 
Sélectionnez
public class MyPart {
  
  @Inject private Logger logger;
  // DatabaseAccessClass voudrait appeler DB
  @Inject private DatabaseAccessClass dao;
  
  @Inject
  public void init(Composite parent) {
    logger.info("UI will start to build");
    Label label = new Label(parent, SWT.NONE);
    label.setText("Eclipse 4");
    Text text = new Text(parent, SWT.NONE);
    text.setText(dao.getNumber());
  }

} 

Une autre classe peut lire ces dépendances et créer une instance de la classe, en injectant des objets dans la dépendance définie. Cela peut se faire avec la fonctionnalité de réflexion Java. Cette classe est généralement appelée le conteneur de dépendance et elle est une classe cadre (framework class).

De cette façon, la classe Java n'a aucune dépendance dure, c'est-à-dire qu'elle ne repose pas sur une instance d'une classe quelconque. Par exemple, si vous voulez tester une classe qui utilise un autre objet interrogeant directement une base de données, vous pouvez injecter un objet mock.

Les objets mock sont des objets qui agissent comme s'ils étaient des objets réels, mais ils ne font que simuler leurs comportements. Mock est un vieux mot anglais qui signifie « mimer » ou « imiter ».

Si l'injection de dépendances est utilisée, une classe Java peut être testée d'une manière isolée, ce qui est bon.

L'injection de dépendances peut se produire sur :

  • le constructeur de la classe (injection de construction) ;
  • une méthode (injection de méthode) ;
  • un champ (injection de champ) .

L'injection de dépendances peut se produire sur les champs et méthodes statiques, ainsi que les non statiques.

XVIII-2. Définir des dépendances dans Eclipse

Eclipse 4 supporte l'injection sur le constructeur, une méthode et sur les champs. Il utilise les annotations standard de Java @Inject et @Named, qui ont été définies dans la Java Specification Requests 330 (JSR330). En plus de ces annotations standard, Eclipse déclare l'annotation @Optional .

Le tableau suivant donne un aperçu des annotations d'injection de dépendances (DI).

Annotation Description
@javax.inject.Inject Marque un champ, un constructeur ou une méthode. Le framework Eclipse va tenter d'injecter le paramètre.
@javax.inject.Named Définit le nom de la clé pour la valeur qui doit être injectée. Par défaut, le nom qualifié complet de la classe est utilisé comme clé. Plusieurs valeurs par défaut sont définies comme constantes dans l'interface IServiceConstants.
@Optional Marque une valeur injectée comme facultative. Si elle ne peut pas être résolue, Null est injecté. Sans @Optional le Framework génère une exception.
Le comportement spécifique dépend de l'utilisation de @Optional :
  • pour les paramètres : une valeur nulle sera injectée ;
  • pour les méthodes : les appels de la méthode seront ignorés ;
  • pour les champs : les valeurs ne seront pas injectées.

Tableau 8. Annotation pour l'injection de dépendance

En plus de ces annotations de base, Eclipse contient plusieurs annotations à des fins spéciales, par exemple pour la propagation des événements ou le travail avec des préférences.

XVIII-3. Comment fonctionne l'injection de dépendances dans Eclipse 4

L'environnement Eclipse 4 crée des objets pour les classes Java désignés par le modèle d'application. Au cours de cette instanciation, l'environnement Eclipse parcourt la définition de classe à la recherche d'annotations.

Sur la base de ces annotations, le Framework Eclipse effectue l'injection. L'injection du constructeur est effectuée dans un premier temps et après l'injection des champs et de méthodes.

Les constructeurs sont appelés avant l'injection des champs. L'accès à un champ injecté dans le constructeur entraînera une exception levée par le Framework.

Le Framework Eclipse surveille également les valeurs injectées et si elles changent, il peut réinjecter les nouvelles valeurs. Cela signifie que les applications peuvent être dispensées d'avoir à installer (et supprimer) les listeners.

Par exemple, vous pouvez définir le fait que vous voulez injecter la sélection courante. Si la sélection change, le framework Eclipse va injecter la nouvelle valeur.

XIX. Portée de l'injection

XIX-1. Qu'est ce qui peut être injecté ?

Nous avons vu la façon dont fonctionne l'injection de dépendances et quelles sont les annotations à utiliser pour définir le comportement des classes Java. Mais nous n'avons pas encore abordé la portée de l'injection, autrement dit, ce que vous pouvez injecter dans vos classes de modèle.

L'environnement Eclipse crée un contexte dans lequel les valeurs injectables peuvent être stockées. Ce contexte peut être modifié, par exemple l'application et le Framework peuvent ajouter des éléments au contexte.

Le contexte Eclipse contient :

  • tous les objets associés au modèle d'application ;
  • tous les autres objets qui ont été explicitement ajoutés au contexte ;
  • Toutes les préférences - les paires clés / valeurs qui sont généralement utilisées pour configurer l'application ;
  • Les Services OSGi - composants logiciels qui peuvent être consommés de façon dynamique.

Les applications peuvent définir aussi leurs propres fournisseurs d'injection.

Dans le cadre de ce tutoriel, tous les éléments du contexte seront appelés éléments de contexte.

XIX-2. Paires clés / valeurs et variables de contexte

Les objets peuvent être mis dans le contexte avec le nom de la classe ou par l'intermédiaire d'une chaîne. Si la clé est une chaîne, cette paire clé / valeur est appelée variable de contexte.

Les paires clé / valeur ou les variables de contexte peuvent être présentes à différents niveaux dans la hiérarchie du contexte.

Les variables de contexte et les paires clé/ valeur dans le contexte permettent de séparer l'état recherché de la source de l'état. Par exemple, dans l'IDE Eclipse beaucoup de composants utilisent l'éditeur actif pour gérer leurs vues, mais cela signifie que leurs vues sont couplées à l'éditeur actif. L'éditeur pourrait plutôt définir une variable de contexte de leur état et les vues réagiront aux changements des variables.

La plate-forme Eclipse met plusieurs paires clé / valeur et variables de contexte dans le contexte. Plusieurs clés de variables de contexte sont définies dans l'interface IserviceConstants.

XIX-3. Comment les objets sont recherchés ?

Toutes les valeurs possibles pour l'injection de dépendances sont accessibles par l'intermédiaire du contexte.

Le contexte contient des objets Java qui peuvent être accessibles par le biais des clés. Celles-ci peuvent se présenter sous deux formes : des chaînes de caractères ou des objets de classes.

Si une chaîne de caractères est utilisée comme clé, la paire clé /valeur correspondante est appelée une variable de contexte.

L'accès au contexte fonctionne d'une manière similaire à l'accès à une map de structure de données Java.

Le contexte n'est pas une structure plane comme une map. Il est hiérarchique et peut également calculer dynamiquement des valeurs pour les clés recherchées.

Un contexte peut être local à un objet et peut avoir un contexte parent.

Les éléments de modèle qui implémentent l'interface MContext ont un contexte local. Ceux-ci sont pour le moment MApplication, MWindow, MPerspective, MPart et MpopupMenu.

Le contexte principal est créé par le framework Eclipse et tous les objets de contexte des éléments du modèle sont hiérarchiquement reliés à l'objet principal du contexte.

Les objets du modèle qui implémentent l'interface MContext ont leur propre contexte local. Par exemple, c'est le cas pour MWindow et MPart. Chaque contexte d'un élément du modèle contient une référence à l'objet modèle lui-même.

Par exemple, si une part demande un objet par une clé quelconque du contexte, Eclipse va d'abord rechercher cet objet dans le contexte local de la part. S‘il ne trouve pas la clé dans le contexte local, il va rechercher dans le contexte parent. Ce processus se poursuit jusqu'à ce que le contexte principal ait été atteint. À ce stade, le Framework devrait vérifier les services OSGi adéquats dans le registre OSGi.

Le graphique ci-dessous visualise la hiérarchie du contexte.

Image non disponible

Le contexte est hiérarchique pour éviter les collisions entre les valeurs injectées et accroître l'isolement des classes en fonction de ce dont elles ont besoin. Par exemple, une part a besoin d'un objet composite unique pour créer ses interfaces utilisateur. Étant donné que les parts ont différents contextes locaux, leur @Inject obtient l'implémentation nécessaire dans le contexte actuel.

La recherche se passe de manière transparente pour l'appelant de l'injection.

XIX-4. Quelles sont les classes et les interfaces concernées

L'interface de l'objet de contexte est l'interface IEclipseContext.

La plate-forme Eclipse utilise la classe OSGiContextStrategy à la recherche de services OSGi si le Framework Eclipse ne trouve pas la clé recherchée dans la hiérarchie des objets IEclipseContext.

XIX-5. Qui crée le contexte pour les éléments du modèle ?

Eclipse 4 dispose d'un Framework de rendu flexible. Pour chaque élément du modèle, le Framework détermine une classe de rendu qui est responsable de la création de l'objet Java associé à l'élément du modèle. Cette classe de rendu crée, si nécessaire, le contexte local de l'élément du modèle par l'intermédiaire de la classe EclipseContextFactory et relie ce contexte local à la hiérarchie de contexte.

Par exemple, la classe ContributedPartRenderer est chargée de créer les objets Java pour les parts du modèle. L'interface des parts est MPart.

ContributedPartRenderer crée un composite pour chaque part et injecte celui-ci dans le contexte local de la part.

Un autre exemple est la classe de WBWRenderer qui est responsable de la création des fenêtres. Cette classe met une instance de la IWindowCloseHandler et l'interface ISaveHandler dans le contexte de la fenêtre. Le premier est responsable du comportement de la fenêtre pendant la fermeture, l'autre pour la sauvegarde. Par exemple, le IWindowCloseHandler par défaut vous demandera si vous souhaitez enregistrer les parts qui indiquent qu'elles ont un contenu pouvant être sauvegardé via l'attribut de modèle MDirtyable. Vous pouvez modifier cette implémentation de IWindowCloseHandler par défaut via l'objet de modèle MWindow. Comme montré dans l'exemple suivant.

 
Sélectionnez
@Execute
public void execute(final Shell shell, EModelService service, 
  MWindow window) {
  IWindowCloseHandler handler = new IWindowCloseHandler() {
    @Override
    public boolean close(MWindow window) {
      return MessageDialog.openConfirm(shell, 
      "Close", 
      "You will loose data. Really close?");
    }
  };
window.getContext().set(IWindowCloseHandler.class, handler);
} 

XX. Annotations de comportement

XX-1. Définition de l'API par l'héritage

En général, chaque Framework définit une interface de programmation d'application (API).

Si vous utilisez un Framework, vous devez avoir une convention définissant quelles sont les méthodes appelées, à quel moment de l'exécution de votre programme. Par exemple, si une classe Java est chargée de traiter le clic d'un bouton de barre d'outils, le Framework doit savoir quelle est la méthode de cette classe qu'il devra appeler.

La manière «traditionnelle» de la définition d'une API se fait par héritage. Cette approche nécessite que vos classes étendent ou implémentent des classes et interfaces du Framework. C'est ainsi que Eclipse 3.x définit son API.

Le Framework définit par une classe abstraite quelles sont les méthodes qui doivent être implémentées. Dans cet exemple, la méthode pourrait s'appeler execute() et le Framework sait que cette méthode doit être appelée une fois si le bouton de la barre d'outils est cliqué.

Par exemple, dans Eclipse 3.x, la classe d'une vue va étendre la classe abstraite ViewPart. Cette classe définit la méthode createPartControl ().

Le Framework Eclipse 3.x sait que createPartControl () est responsable de la création de l'interface utilisateur et appelle cette méthode une fois la vue visible.

La définition d'API via l'héritage est un moyen simple de définir une API, mais il lie également les classes étroitement au Framework. Par exemple, tester la classe sans le Framework devient difficile. Il rend également difficile l'extension ou la mise à jour du Framework.

XX-2. Définition d'API par annotations

Eclipse ne fournit pas des classes du Framework que vous pouvez étendre. Pour identifier les méthodes qui devrait être appelées à un certain moment, la plate-forme Eclipse utilise des annotations pour identifier les méthodes qui devraient être appelées à un moment donné.

Ces annotations sont appelées des annotations de comportement.

Les annotations de comportement sont utilisées pour indiquer que certaines méthodes devraient être appelées lors d'événements donnés. Les tableaux qui suivent énumèrent les annotations de comportement utilisables pour les parts.

Annotation Description
@PostConstruct Est appelée après la construction de la classe et dès que les champs et méthodes d'injection ont été effectués.
@PreDestroy Est appelée avant que la classe ne soit détruite. Peut être utilisée pour nettoyer les ressources.
@Focus Indique que cette méthode doit être appelée, une fois que la part obtient le focus. Il est nécessaire de mettre le focus sur un contrôle de l'interface utilisateur, autrement certaines fonctionnalités du workbench ne fonctionneront pas.
@Persist Est appelée si une requête de sauvegarde sur la part est déclenchée. Peut être utilisée pour sauvegarder les données de la part.
@PersistState Est appelée avant que l'objet du modèle ne soit disposé, de sorte que la part peut sauvegarder son état.

Toutes ces annotations vont également déclencher des injections de dépendances. Par conséquent, vous n'avez pas besoin d'ajouter l'annotation @Inject si vous utilisez ces annotations.

Tableau 9. Annotations du cycle de vie d'une part

Les annotations @PostConstruct et @PreDestroy sont incluses dans le package javax.inject.

Eclipse définit également d'autres annotations pour les autres composants. Le tableau suivant en présente quelques-une, mais vous avez aussi des annotations pour les commandes qui sont couvertes dans le chapitre commandes.

Annotation Description
@GroupUpdates indique que les mises à jour pour cet @Inject devraient être groupées. Si vous modifiez de tels objets dans le IEclipseContext la mise à jour sera déclenchée par la méthode processWaiting () sur IEclipseContext.
@EventTopic et @UIEventTopic Permet de vous abonner à des événements envoyés par le service EventAdmin.

Tableau 10. Autres annotations de comportement

@Persiste, @PersistState et @Focus font partie du package org.eclipse.e4.ui.di.

XXI. Tutoriel: Utiliser l'injection de dépendances

XXI-1. Obtenir un composite

Dans le tutoriel suivant, nous allons développer nos classes afin d'utiliser l'injection de dépendances.

Changez la classe TodoOverviewPart par ce qui suit:

 
Sélectionnez
package com.example.e4.rcp.todo.parts;

import javax.inject.Inject;

import org.eclipse.swt.widgets.Composite;

public class TodoOverviewPart {
  
  @Inject 
  public TodoOverviewPart(Composite parent) {
    
  // En supposant que l'injection de dépendance fonctionne
  // le parent ne sera jamais null
  System.out.println("Woh! Got Composite via DI.");
  
  // A-t-il un gestionnaire de mise en page?
  System.out.println("Layout: " + parent.getLayout().getClass());
  }
} 

XXI-2. Validation

Exécutez votre application et vérifiez dans la console de votre IDE Eclipse pour voir si le paramètre Composite a été injecté. Notez la classe Layout pour laquelle le composite est assigné, si elle n'est pas nulle.

XXII. Exercice : Définir le cycle de vie d'une part

XXII-1. Vue d'ensemble

Il est possible de créer l'interface utilisateur d'une part dans le constructeur, mais l'injection pour les champs et méthodes ne se fait pas à ce niveau.

Par conséquent, il est recommandé que l'interface utilisateur soit créée dans une méthode @PostConstruct.

Ccréer l'interface utilisateur dans une méthode annotée avec @PostConstruct exige que les méthodes @Inject sachent que l'interface utilisateur n'a pas encore été créée.

XXII-2. Utilisation de @PostConstruct et @PreDestroy

Ajoutez la méthode suivante à vos classes TodoOverviewPart, TodoDetailsPart et PlaygroundPart.

 
Sélectionnez
// Declare a field label, required for @Focus
Label label;

@PostContruct
public void createControls(Composite parent) {
  label = new Label(parent,SWT.NONE);
  label.setText("A text....");
} 

Retirez tous les constructeurs de vos classes.

XXII-3. @Focus

Implémentez une méthode @Focus pour chaque part. La définition du focus sur l'un des contrôles SWT est obligatoire dans Eclipse 4.2. Cela devient optionnel dans Eclipse 4.3.

 
Sélectionnez
@Focus
private void setFocus() {
  label.setFocus();
} 

XXII-4. Validation

Exécutez votre application et vérifiez que la méthode @PostConstruct a été appelée. Utilisez soit le débogage ou une instruction System.out.println (). Chaque part doit mettre le focus sur l'un de ses contrôles, sinon certains services ne fonctionneront pas. C'est pourquoi nous avons ajouté SWT Label pour être le contrôle qui recevra le focus. Même si le champ Label ne peut pas prendre le focus, il déclenche l'événement SWT.ACTIVATE, ce qui est suffisant pour que les services Eclipse fonctionnent correctement.

Si SWT vous est familier, ajoutez d'autres contrôles sur votre interface utilisateur.

Si la méthode @PostConstruct n'est pas déclenchée, vérifiez que vous avez défini la dépendance au package java.annotation version 1.0.0. Voir http://wiki.eclipse.org/Eclipse4/RCP/FAQ pour plus de détails sur cette question.

XXIII. Commandes, gestionnaires , menus, barres d'outils

XXIII-1. Définition des éléments de menu et barres d'outils

Le modèle d'application Eclipse peut comporter des commandes et des handlers.

Une commande dans Eclipse est une description déclarative d'une action abstraite qui peut être exécutée, par exemple enregistrer, modifier ou copier. Une commande est indépendante de ses détails d'implémentation.

Le comportement d'une commande est défini par un handler. Le handler définit une classe par son attribut contributionURI. Cet attribut est affiché en étant Class URI dans l'éditeur de modèle.

Le handler peut être global à l'application, ou porté sur une fenêtre ou une part. Cela signifie que vous pouvez définir par exemple un handler de copie global pour votre application, mais aussi définir des handlers de copie spécifiques pour certaines parts. Eclipse utilise le plus détaillé.

XXIII-2. Annotations de comportement pour les classes de handler

Les annotations de comportement pour les classes de handler sont décrites dans le tableau suivant.

Annotation Description
@Execute Marque la méthode à exécuter dans une classe de handler. Une seule méthode dans un handler doit être annotée avec @Execute
@CanExecute Marque une méthode pour être visitée par le Framework de Commande pour vérifier si un handler est activé.

Tableau 11. Autres annotations de comportement

Cette classe utilise l'annotation @Execute pour définir quelle méthode est appelée une fois le gestionnaire est exécuté. L'annotation @CanExecute définit la méthode qui évalue si le gestionnaire est actuellement actif. Si le gestionnaire doit toujours s'éxecuter, il n'est pas nécessaire d'implémenter une méthode @CanExecute.

 
Sélectionnez
package com.example.e4.rcp.todo.handlers;

// Imports statements cut out
// ..

public class ExitHandler {
  @Execute
  public void execute(IWorkbench workbench) {
    workbench.close();
  }

  // Default to true if not implemented
  @CanExecute
  public boolean canExecute() {
    // TODO ajouter ici quelques tests logiques
    return true;
  }

} 

@CanExecute est appelée par le Framework lorsque l'événement SWT.SHOW se produit. Cet événement est par exemple déclenché si une nouvelle part est affichée. Également, si vous ajoutez des éléments à la barre d'outils, un minuteur est automatiquement initié par le Framework Eclipse qui, au moment de la rédaction de ce document, s'exécute toutes les 400 millisecondes. Ce temporisateur vérifie le @CanExecute pour activer ou désactiver les éléments de la barre d'outils connexes.

Dans la classe du handler, vous pouvez déterminer l'ID de la commande si celle-ci a été déclenchée par le biais de l'interface utilisateur. La résolution de l'ID est impossible, si elle a été déclenchée par le service de commande. Le code suivant montre comment obtenir l'ID de commande.

 
Sélectionnez
@Execute
public void execute(MHandledItem item) {
  MCommand command = item.getCommand();
  // Afficher l'ID de la commande
  System.out.println(command.getElementId());
} 

XXIII-3. Commandes par défaut

Si vous êtes familier Eclipse 3.x, vous êtes probablement la recherche des commandes prédéfinies que vous pouvez réutiliser. La plate-forme Eclipse 4 essaie d'être aussi légère que possible.

Eclipse 4 ne comprend aucune des commandes standard. Vous devez définir toutes vos commandes.

XXIII-4. Menus et barres d'outils

Vous pouvez ajouter des menus et barres d'outils dans le modèle d'application pour la fenêtre et les parts. Le menu et les éléments de barre d'outils contiennent des références aux commandes. Si une commande est sélectionnée, l'environnement d'exécution déterminera les handlers de commande associés.

Pour les cas simples, vous pouvez également utiliser « Direct MenuItem » ou un «  Direct ToolItem », qui vous permettent de définir une classe qui sera exécutée directement. Ceci est utile si vous voulez juste répondre à un clic utilisateur sur un élément de menu ou de la barre d'outils.

Utilisation des commandes avec handler vous donne plus de flexibilité. Par exemple, vous pouvez avoir différents gestionnaires pour différents périmètres (applications ou vues) et vous pouvez définir des raccourcis clavier pour les commandes associées aux handlers.

Les barres d'outils dans l'application sont encapsulées dans le modèle d'application avec l'élément de modèle trimbar. Le trimbar peut être défini pour une fenêtre. Via son attribut, vous définissez si le trimbar doit être placé dans la bordure supérieure, gauche, droite ou en bas de la fenêtre.

La commande associée est affectée à l'élément de menu ou de barre d'outils. Les menus et les barres d'outils permettent l'ajout de séparateurs. Les menus peuvent avoir des sous-menus.

Pour rendre les menus plus accessibles, le libellé du menu peut faire usage d'un moyen mnémotechnique. Un mnémonique apparaît comme une lettre soulignée dans le menu lorsque l'utilisateur maintient la touche Alt enfoncée et il sert comme un moyen pour naviguer facilement à travers les menus par le biais du clavier. Définir des mnémoniques est aussi simple que précéder la lettre destinée à être le mnémonique avec un & dans la définition du libellé. Par exemple, le libellé &Enregistrer apparaît comme Enregistrer avec le E souligné lorsque la touche Alt est enfoncée.

XXIII-5. Portée des handlers

Chaque commande ne peut avoir qu'un seul handler valide pour une portée donnée. Le modèle d'application vous permet de définir un handler pour l'application, pour une fenêtre ou une part.

Si vous définissez plus d'un handler pour une commande, Eclipse va sélectionner le gestionnaire le plus spécifique à l'élément de modèle.

Par exemple, si vous définissez un handler pour la commande "Copier" pour votre fenêtre et si vous définissez un autre handler "Copier" pour votre part, le runtime sélectionne les handlers les plus proches de l'élément de modèle.

Une fois le handler sélectionné, @CanExecute est appelé, ainsi le handler peut déterminer s'il peut exécuter la commande dans un contexte donné. Si elle retourne false, il permettra de désactiver tous les menus et éléments de barre d'outils qui sont associés avec cette commande.

XXIII-6. Plusieurs méthodes avec @Execute

La documentation java de @Execute définit que dans un handler, une seule méthode est autorisée à être annotée avec @Execute.

Par conséquent, c'est une erreur d'annoter plus d'une méthode avec @Execute

XXIII-7. Schéma d'appellation des IDs de commandes et gestionnaire

Une bonne convention est de commencer l'ID avec le plus haut niveau du nom du package de votre projet et de n'utiliser que des minuscules.

Les IDs des commandes et handler devraient refléter leur relation. Par exemple, si vous implémentez une commande avec l'ID com.example.contacts.commands.show, vous devez utiliser comme ID com.example.contacts.handler.show pour le handler. Si vous avez plus d'un handler à définir, ajoutez un suffixe décrivant son but, par exemple, com.example.contacts.handler.show.details.

Dans le cas où vous implémentez des commandes couramment utilisées, par exemple, enregistrer, copier, vous devez utiliser les IDs existants de la plate-forme, comme certaines contributions d'Eclipse, excepté les IDs qui suivent. Une liste plus complète d'ID de commande est disponible dans org.eclipse.ui.IWorkbenchCommandConstants.

Commande ID
Enregistrer org.eclipse.ui.file.save
Enregistrer tout org.eclipse.ui.file.saveAll
Annulé org.eclipse.ui.edit.undo
Refaire org.eclipse.ui.edit.redo
Couper org.eclipse.ui.edit.cut
Copier org.eclipse.ui.edit.copy
Coller org.eclipse.ui.edit.paste
Supprimer org.eclipse.ui.edit.delete
Importer org.eclipse.ui.file.import
Exporter org.eclipse.ui.file.export
Sélectionner tout org.eclipse.ui.edit.selectAll
A propos org.eclipse.ui.help.aboutAction
Préférences org.eclipse.ui.window.preferences
Quitter org.eclipse.ui.file.exit

Tableau 12. ID par défaut pour les commandes fréquemment utilisées

XXIV. Vue, menus contextuels et les paramètres de commandes

XXIV-1. menus de vues

Un menu dans une part peut être défini comme un menu de vue. Veuillez noter que vous pouvez définir qu'un seul menu au maximum comme menu de vue.

Pour ajouter un élément menu de vue, sélectionnez l'entrée des menus sous notre part, sélectionnez ViewMenu et appuyez sur le bouton Add.

Image non disponible

XXIV-2. Définir un popup menu (menu contextuel)

Vous pouvez également définir un menu contextuel pour les contrôles SWT. Pour cela, vous définissez un menu contextuel pour votre part dans le modèle d'application.

Image non disponible
Image non disponible

Vous pouvez ensuite l'assigner via la classe EMenuService avec le registerContextMenu (contrôle, ID) à un contrôle SWT. Le paramètre id de la méthode de registerContextMenu doit être l'ID de votre élément menu contextuel du modèle.

Le code suivant montre un exemple pour l'enregistrement.

 
Sélectionnez
package com.example.e4.rcp.todo.parts;

import javax.annotation.PostConstruct;

import org.eclipse.e4.ui.workbench.swt.modeling.EMenuService;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

public class TodoDetailsPart {

  @PostConstruct
  public void createUi(Composite parent, EMenuService service) {
    final Text text = new Text(parent, SWT.BORDER);
    text.setText("Hello");
    // soyez certain d'utiliser le bon ID 
    // de votre modèle d'application
    service.registerContextMenu(text, 
        "com.example.e4.rcp.todo.popupmenu.table");
  }
} 

Si vous utilisez un Viewer Jface, vous avez à utiliser des contrôles SWT.

 
Sélectionnez
package com.example.e4.rcp.todo.parts;

import javax.annotation.PostConstruct;

import org.eclipse.e4.ui.workbench.swt.modeling.EMenuService;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

public class TodoDetailsPart {

  @PostConstruct
  public void createUi(Composite parent, EMenuService service) {
    // encore du code...
    TableViewer viewer = new TableViewer(parent, SWT.FULLSELECTION | SWT.MULTI);
    
    // encore du code
    
    /enregistrer le menu contextuel dans votre table
    menuService.registerContextMenu(viewer.getTable(), 
        "com.example.e4.rcp.todo.popupmenu.table");
  }
} 

Si vous souhaitez mettre en œuvre cet exemple, vous devez également avoir une dépendance au plugin org.eclipse.e4.ui.workbench.swt dans votre application.

XXIV-3. Passer des paramètres aux commandes

Vous pouvez également passer des paramètres aux commandes.

Pour définir une commande qui accepte un paramètre, sélectionnez votre commande et appuyez sur le bouton Ajouter dans la section Paramètres.

L'ID est l'identifiant que vous pouvez utiliser pour obtenir le paramètre via l'annotation @Named.

Image non disponible
Image non disponible

L'obtention du paramètre via l'annotation @Named dans votre handler est illustrée dans l'exemple de code suivant.

 
Sélectionnez
package com.example.e4.rcp.todo.handlers;

import javax.inject.Named;

import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.di.annotations.Execute;

public class TestHandler {
  @Execute
  public void execute(@Named("com.example.e4.rcp.todo" +
      ".commandparameter.input") String param) {
    System.out.println(param);
  }


} 

Dans votre menu ou barre d'outils, le champ Name doit être égal à ID donné dans le paramètre que vous avez défini dans votre commande. La donnée du champ Value est passée à la commande.

Image non disponible

l'ID du paramètre est très important. Cet id de paramètre doit être injecté avec l'annotation @Named et utilisé comme Nom (deuxième champ) lors de la définition du menu ou de la barre d'outils. Cela est mis en évidence dans l'image ci-dessous.

Image non disponible

XXV. Core expressions

XXV-1. Utilisation des core expressions

La visibilité des menus, barres d'outils et leurs entrées peut être restreinte par les Core expressions. Vous pouvez ajouter l'attribut correspondant dans le modèle d'application de l'ID défini par le point d'extension org.eclipse.core.expressions.definitions dans le fichier plugin.xml.

Pour ajouter ce point d'extension à votre application, ouvrez le fichier plugin.xml et sélectionnez l'onglet Dependencies dans l'éditeur. Ajoutez le plug-in org.eclipse.core.expressions dans la section Required Plug-ins.

Ensuite, sélectionnez l'onglet Extensions, appuyez sur le bouton Add et ajoutez l'extension org.eclipse.core.expressions.definitions. Vous définissez un ID par lequel la Core expression peut être désignée dans le modèle d'application.

Avec un clic droit sur l'extension vous pouvez commencer à construire votre expression.

Vous pouvez attribuer cette Core expression pour votre élément de menu dans le modèle d'application. La capture d'écran ci-dessous montre cela pour l'élément de menu Test.

L'exemple suivant peut être utilisé pour restreindre la visibilité d'un élément de menu en fonction du type de la sélection en cours. Vous pourrez ensuite apprendre à configurer la sélection en cours. Veuillez noter que la variable de sélection est actuellement appelée org.eclipse.ui.selection. Dans Eclipse 3.x cette variable s'appelait Selection.

 
Sélectionnez
<extension
      point="org.eclipse.core.expressions.definitions">
  <definition
            id="com.example.e4.rcp.todo.selectionset">
      <with variable="org.eclipse.ui.selection">
    <iterate ifEmpty="false" operator="or">
      <instanceof value="com.example.e4.rcp.todo.model.Todo">
      </instanceof>
    </iterate>
      </with>
  </definition>
</extension> 

Cette expression peut être utilisée pour limiter la visibilité des éléments de modèle.

Image non disponible
Image non disponible

Cette approche est similaire à la définition des Core expressions dans Eclipse 3.x.

Les valeurs disponibles pour Eclipse 3.x sont documentées dans le Wiki Eclipse sous le lien suivant: Core Expressions et contenues dans l'interface ISources. Eclipse 4 n'appuie pas toujours les mêmes variables, mais le wiki pourrait toujours être utile.

XXV-2. Évaluez vos propres valeurs dans les Core expressions

Vous pouvez également placer des valeurs dans IEclipseContext de votre application et les utiliser pour votre évaluation de visibilité.

Plus tard, vous en apprendrez plus sur la modification d'IEclipseContext mais le code suivant est un exemple d'un handler qui met la valeur de la clé myactivePartId dans le contexte.

 
Sélectionnez
@Execute
public void execute(IEclipseContext context) {
// mettre une valeur exemple dans le context  context.set("myactivePartId", 
  "com.example.e4.rcp.ui.parts.todooverview");
} 

L'exemple suivant montre une core expression qui est évaluée à vrai si une clé myactivePartId avec la valeur com.example.e4.rcp.ui.parts.todooverview est trouvée dans le contexte.

Cette core expression peut être assignée à un élément de menu et de contrôler sa visibilité.

 
Sélectionnez
<extension
         point="org.eclipse.core.expressions.definitions">
      <definition
            id="com.example.e4.rcp.todo.todooverviewselected">
         <with
               variable="myactivePartId">
            <equals
                  value="com.example.e4.rcp.ui.parts.todooverview">
            </equals>
         </with>
      </definition>
   </extension> 
Image non disponible

XXVI. Tutoriel: Définition et utilisation des commandes et des handlers

XXVI-1. Vue d'ensemble

Vous allez maintenant définir des commandes et des gestionnaires pour votre application. Nous allons définir nos gestionnaires pour l'ensemble de l'application.

XXVI-2. Définition de commandes

Ouvrez le fichier Application.e4xmi et sélectionnez Commands.

Image non disponible

Avec le bouton Add, vous pouvez créer de nouvelles commandes. Le nom et l'ID sont les champs les plus importants. Créez les commandes suivantes.

ID Nom
org.eclipse.ui.file.saveAll Enregistrer
org.eclipse.ui.file.exit Quitter
com.example.e4.rcp.todo.new Nouveau Todo
com.example.e4.rcp.todo.remove Supprimer Todo
com.example.e4.rcp.todo.test Pour test

Tableau 13. Les Commandes

XXVI-3. Définition des classes gestionnaire

Créez le package com.example.e4.rcp.todo.handlers pour vos classes de traitement.

Toutes les classes de handler mettront en œuvre la méthode execute ().

 
Sélectionnez
package com.example.e4.rcp.todo.handlers;

import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.di.annotations.Execute;

public class SaveAllHandler {
  @Execute
  public void execute() {
    System.out.println("Called");
  }
} 

En utilisant le modèle ci-dessus pour toutes les classes, créez les classes suivantes :

  • SaveAllHandler
  • ExitHandler
  • NewTodoHandler
  • RemoveTodoHandler
  • TestHandler

XXVI-4. Définition des gestionnaires dans votre modèle

Sélectionnez l'élément Handlers dans le modèle de votre application et créez les gestionnaires du tableau ci-dessous pour vos commandes. Pour la définition des gestionnaires, l'ID, la commande et la classe sont des informations pertinentes.

Utilisez le préfixe de com.example.e4.rcp.todo.handlers pour tous les IDs des gestionnaires.

ID handler Commande - Classe
*.save Enregistrer - SaveAllHandler
*.exit Quitter - ExitHandler
*.new Nouveau Todo - NewTodoHandler
*.remove Supprimer Todo - RemoveTodoHandler
*.test Pour test - TestHandler

Tableau 14. Les handlers

L'éditeur de modèle d'application montre à la fois le nom et l'ID de la commande. L'URI de la classe suit le schéma bundleclass :// le tableau définit uniquement le nom de la classe pour le rendre plus lisible. Par exemple, pour le gestionnaire de sauvegarde cela ressemble à ce qui suit :

 
Sélectionnez
bundleclass://com.example.e4.rcp.todo/[CONTINUE...]
com.example.e4.rcp.todo.handlers.SaveAllHandler 
Image non disponible

XXVI-5. Ajout d'un Menu

Vous allez maintenant ajouter un menu à votre modèle d'application.

Sélectionnez le fichier Application.e4xmi. Pour ajouter un menu à une fenêtre, sélectionnez votre entrée TrimmedWindow dans le modèle et cochez l'option Main Menu.

Image non disponible

Attribuez l'ID org.eclipse.ui.main.menu à votre menu principal.

Ajoutez deux menus, l'un avec le nom Fichier et l'autre avec le nom Edition dans l'attribut label.

Également, définissez l'ID org.eclipse.ui.file.menu pour le menu Fichier et com.example.e4.rcp.todo.menu.edit comme ID pour le menu Edition.

Image non disponible

Ajoutez un HandledMenuItem au menu Fichier. Cet élément doit pointer sur la commande Enregistrer via l'attribut Command.

Image non disponible

Ajoutez un séparateur après l'élément de menu Enregistrer et ajoutez après une entrée pour la commande exit.

Ajoutez toutes les autres commandes dans le menu Edition.

XXVI-6. Ajout d'une barre d'outils

Sélectionnez le nœud TrimBars sous votre entrée Window et appuyez sur le bouton Add. L'attribut latéral doit être réglé sur Top, de sorte que toutes les barres attribuées à ce TrimBar apparaissent en haut de l'application.

Ajoutez une barre d'outils pour votre TrimBar. Ajoutez un ToolItem Handled à cette barre d'outils, qui pointe sur la commande org.eclipse.ui.file.saveAll.

Définissez le Label pour cette entrée pour Enregistrer.

Image non disponible

XXVI-7. Fermeture de l'application

Pour tester si votre handler fonctionne, modifiez la classe de votre ExitHandler, de sorte qu'il va fermer votre application.

 
Sélectionnez
package com.example.e4.rcp.todo.handler;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.workbench.IWorkbench;

public class ExitHandler {
  @Execute
  public void execute(IWorkbench workbench) {
    workbench.close();
  }
} 

XXVI-8. Simuler enregistrement

Modifiez votre classe SaveAllHandler, de sorte que System.out.println écrit le message suivant sur la console: « SaveAllHandler est appelé »

XXVII. Raccourcis clavier

XXVII-1. Vue d'ensemble

Il est également possible de définir des combinaisons de touches (raccourcis clavier) pour votre application Eclipse. Cela nécessite deux étapes. D'abord, vous devez entrer des valeurs pour le nœud BindingContext de votre modèle d'application.

Ensuite, vous devez saisir les combinaisons de touches pour le BindingContextappropriée dans le nœud BindingTable de votre modèle d'application. Une BindingTable est toujours assignée à un BindingContext spécifique. Le BindingContext peut avoir plusieurs BindingTables qui lui sont assignées.

Les BindingContexts sont définis de façon hiérarchique, de sorte que les raccourcis clavier dans les BindingContexts enfants dominent sur les raccourcis clavier similaires dans le BindingContext parent.

XXVII-2. Entrées BindingContext utilisées par Jface

Le BindingContext est définie par son ID. Le BindingContext peut s'assigner à une fenêtre ou une part dans le modèle d'application. Cela définit les raccourcis clavier applicables pour la fenêtre ou la part

Eclipse JFace utilise des identifiants de BindingContext prédéfinis qui sont définis dans la classe org.eclipse.jface.contexts.IContextIds. JFace distinction entre les raccourcis applicables sur les boites de dialogues, les fenêtres ou sur les deux.

Ce qui suit donne un aperçu des ID pris en charge et la validité des raccourcis clavier définis par référence à cet ID de contexte.

ID de contexte Description
org.eclipse.ui.contexts.dialogAndWindow Les raccourcis clavier valides pour les dialogues et fenêtres
org.eclipse.ui.contexts.dialog Les raccourcis clavier valides pour les boites de dialogues
org.eclipse.ui.contexts.window Les raccourcis clavier valides pour les fenêtres

Tableau 15. Les valeurs BindingContext par défaut

Par exemple, Ctrl + C (Copier) serait défini dans dialogAndWindows, car il est applicable partout, mais F5 (Rafraîchir) ne peut être défini que pour une fenêtre et non pas pour une boite de dialogue.

XXVII-3. Définir des raccourcis clavier

Le nœud BindingTable dans le modèle d'application vous permet de définir des raccourcis pour un BindingContext spécifique.

Pour définir un raccourci, vous allez créer un nouveau nœud pour le BindingTable et définir une référence pour l'ID du contexte.

Dans votre raccourci clavier, vous définissez la séquence de touches et la commande associée à ce raccourci.

Image non disponible

Les touches Control ne sont pas les mêmes pour les différentes plate-formes, comme ça peut être le cas pour un Mac et un système Linux. Par exemple, vous pouvez utiliser la touche Ctrl mais ce serait figé. Il est préférable d'utiliser les metakeys M1-M4.

Touches de contrôle Mapping pour Windows et Linux Mapping pour Mac
M1 Ctrl Command
M2 Shift Shift
M3 Alt Alt
M4 Non définie Ctrl

Tableau 16.Correspondance des touches

Ces valeurs sont définies dans la classe SWTKeyLookup.

XXVII-4. Raccourcis clavier pour une part

Vous pouvez attribuer un BindingContext spécifique pour être actif lorsqu‘une part est activée.

Image non disponible

XXVII-5. Activation des raccourcis

S'il y a plusieurs combinaisons de touches définies, la classe ContextSet est chargée de déterminer celle par défaut. ContextSet utilise la hiérarchie BindingContext pour déterminer l'ordre de recherche. Le BindingContext est plus spécifique en fonction du nombre d'ancêtres qui sont entre celui-ci et le BindingContext racine (le nombre de niveaux qu'il y a). Le BindingContext le plus spécifique est considéré comme étant le premier et le BindingContext racine est considéré comme le dernier.

Vous pouvez également utiliser le service EContextService qui vous permet d'activer et de désactiver explicitement un BindingContext à l'aide des méthodes activateContext () et deactivateContext ().

XXVII-6. Difficultés avec les raccourcis clavier

La mise en œuvre des raccourcis exige que toutes les parts implémentent @Focus. Eclipse exige qu'un contrôle détienne le focus.

XXVIII. Modifications du modèle d'application lors de l'exécution

XXVIII-1. Création d'éléments de modèle

Comme le modèle est interactif, vous pouvez le changer durant l'exécution. Par exemple, vous pouvez modifier la taille de la fenêtre active, ajouter des parts à votre application ou supprimer des éléments de menu.

Pour ajouter de nouveaux éléments au modèle de votre l'application, vous pouvez utiliser le ModelService ou récupérer des éléments existants injectés.

XXVIII-2. Modification des éléments de modèle existants

Vous pouvez également obtenir les éléments de modèle injectés et changer leurs attributs.

XXIX. Exemple pour changer le modèle d'application

XXIX-1. Exemple : créer dynamiquement une nouvelle fenêtre

Pour créer de nouveaux objets de modèle, vous pouvez utiliser la classe MBasicFactory.INSTANCE. Il s'agit d'une fabrique utilisée pour créer de nouveaux objets de modèle via des méthodes typées create*(). Par exemple, vous pouvez créer une nouvelle fenêtre lors de l'exécution, comme indiqué dans le code suivant.

 
Sélectionnez
// Cérer une nouvelle fenêtre et définir sa taille
MWindow window = MBasicFactory.INSTANCE.createTrimmedWindow();
window.setWidth(200);
window.setHeight(300);

// Ajouter la nouvelle fenêtre à l'application
application.getChildren().add(window); 

XXIX-2. Exemple : créer dynamiquement une nouvelle part

Par exemple, le code suivant ajoute une nouvelle part à la fenêtre active.

 
Sélectionnez
package testing.handlers;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.model.[CONTINUE...]
    .application.descriptor.basic.MPartDescriptor;
import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;

public class AddPartHandler {
  @Execute
  public void execute(MWindow window) {
    MPart part = MBasicFactory.INSTANCE.createPart();
    part.setElementId("mynewid");
    part.setLabel("A new Part");
    part.setContributionURI("bundleclass://com.example." +
        "e4.rcp.todo/com.example.e4.rcp.todo.parts.TodoOverviewPart");
    window.getChildren().add(part);
  }
} 

XXX. Les addon du modèle

XXX-1. Vue d'ensemble

Eclipse 4 essaie de garder le Framework aussi léger que possible. L'objet addon du modèle peut être ajouté globalement sur le modèle d'application et peut améliorer l'application avec une fonctionnalité supplémentaire. Les addons sont des objets Java normaux.

Les Addons utilisent la convention bundleclass://URI dans le modèle d'application pour se référer aux objets Java.

Avoir ces addons enregistrés leur permet d'être améliorés ou remplacés par l'équipe de la plate-forme Eclipse ou par une mise en œuvre spécifique du client en cas de besoin.

XXX-2. Les addons du Framwork

Pour le moment, les addons standard suivants sont utiles pour les applications Eclipse. Leurs noms de classe donnent une indication de leurs fonctionnalités. Consultez leur Javadoc pour avoir une brève description de leurs utilités.

  • CommandServiceAddon
  • ContextServiceAddon
  • BindingServiceAddon
  • CommandProcessingAddon
  • ContextProcessingAddon
  • BindingProcessingAddon

XXX-3. Les addons SWT supplémentaires

Des addons supplémentaires sont disponibles, par exemple pour le support du glisser-déplacer des Parts dans votre application.

Pour gérer le glisser-déplacer pour les parts, vous avez besoin d'ajouter le plug-in org.eclipse.e4.ui.workbench.addons.swt dans le fichier de configuration de votre product. Ensuite, vous pouvez utiliser DnDAddon et CleanupAddon à partir de ce bundle comme addon dans votre modèle d'application. Ce plug-in contient aussi le MinMax addon qui ajoute les fonctionnalités minimiser et maximiser à votre application.

Le plug-in org.eclipse.e4.ui.workbench.addons.swt fait participer ces plug-ins à votre modèle d'application via des processeurs, par exemple, une classe Java qui modifie le modèle d'application. Si vous supprimez le plug-in de votre product alors ces addons ne seront plus disponibles.

XXX-4. Relations avec les autres services

Les Addon sont créés avant que le moteur de rendu ne rende le modèle et après la création de la fonction EventAdmin.

Cela permet aux addons de modifier l'interface utilisateur produite par le moteur de rendu. Par exemple, l'addon min/max change le conteneur d'onglets créé pour MPartStacks pour avoir des boutons min/max dans le coin.

Les services d'EventAdmin fournissent les notifications sur les événements Eclipse, par exemple, si une part est activée. l'Addon peut aussi s'abonner à des événements de la plate-forme Eclipse.

XXXI. L'accès et l'extension du contexte Eclipse

XXXI-1. Accès au contexte

Pour accéder à un contexte existant, vous pouvez utiliser l'injection de dépendances, si l'objet en question est géré par le runtime Eclipse, par exemple, si vous utilisez un objet de modèle.

 
Sélectionnez
package com.example.e4.rcp.todo.handlers;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Execute;

public class ShowMapHandler {
  @Execute
  public void execute(IEclipseContext context) {
    // Ajoute des objets au contexte local de ce handler
    // ...
  }

Alternativement, si votre objet de modèle étend MContext vous pouvez utiliser ID pour obtenir l'objet de modèle injecté et utiliser la méthode getContext () pour accéder à son contexte. Par exemple MPart, MWindow, MApplication et MPerspective étendent Mcontext.

 
Sélectionnez
package com.example.e4.rcp.todo.parts;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.swt.widgets.Composite;

// Récupération du contexte de l'application
// avec l'objetMApplication

public class TodoDetailsPart {
  
  @PostConstruct
  public void createControls(Composite parent, 
    MApplication application) {
    IEclipseContext context = application.getContext();
    // Ajoute ou accède à l'objet depuis et vers le contexte d'application 
    // ...
  }

} 

Si vous êtes à l'extérieur de l'objet de modèle, vous pouvez toujours accéder au contexte OSGi comme ce qui suit :

 
Sélectionnez
public Object start() {
  // Récupérer les informations du bundle
  Bundle bundle = FrameworkUtil.getBundle(getClass());
  BundleContext bundleContext = bundle.getBundleContext();
  IEclipseContext eclipseCtx =   
      EclipseContextFactory.getServiceContext(bundleContext);

  // remplir le contexte avec des informations en utilisant set(String,Object)
  // ....
  
  // instanciation de la classe 
  ContextInjectionFactory.make(MyPart.class, eclipseCtx);
} 

XXXI-2. Les services OSGi

Vous pouvez ajouter des objets au contexte à travers des services OSGi. Ils sont automatiquement disponibles dans le contexte. Mais ils sont globaux au Framework. Ils ne peuvent pas accéder au modèle du Workbench ou de son contexte.

XXXI-3. Objets et variables de contexte

Vous pouvez ajouter des paires clé / valeur directement à IEclipseContext, par exemple un objet todo sous la clé active. L'ajout d'objets dans un contexte peut être fait par la méthode set () sur IEclipseContext. L'exemple suivant crée un nouveau contexte avec la méthode de fabrique EclipseContextFactory.create() et lui ajoute quelques objets.

 
Sélectionnez
@Inject
public void addingContext(IEclipseContext context) {
  // Nous avons besoin d'ajouter un objet au contexte

  // Création de l'instance de la classe
  IEclipseContext myContext = EclipseContextFactory.create();

  // Ajout de quelques valeurs
  myContext.set("mykey1", "Hello1");
  myContext.set("mykey2", "Hello2");

  // Ajout de la relation au parent
  myContext.setParent(context);

  // Alternativement vous pouvez aussi 
  // établir une relation parent/enfant 
  // avec l'appel de la méthode  
  // context.createChild()
  
} 

Une variable de contexte peut être déclarée comme étant modifiable par l'appel de la méthode declareModifiable(key).

 
Sélectionnez
@Inject
public void addingContext(IEclipseContext context) {
  // Ajout de quelques valeurs
  context.set("mykey1", "Hello1");
  context.set("mykey2", "Hello2");
  
  // Marquer la valeur nommée comme étant modifiable 
  // par les descendants de ce contexte. si la valeur n'existe pas
  // dans ce contexte, une valeur null est ajoutée à ce nom.
  context.declareModifiable("mykey1");

} 

Les variables de contexte modifiables sont ajoutées à des niveaux particuliers de la hiérarchie IEclipseContext et peuvent également être modifiées à l'aide de la méthode modify() plutôt que la méthode set() d'IEclipseContext.

La méthode modify() recherche dans la chaîne pour trouver le contexte définissant la variable. Si aucun contexte de la chaîne parente ne contient la valeur définie pour le nom, la valeur sera définie dans ce contexte. Si la clé existe déjà dans ce contexte, modify() exige que la clé soit définie comme étant modifiable avec la méthode declareModifiable(). Sinon, la méthode lève une exception.

Vous pouvez ajouter des paires clés/valeurs et des variables de contexte à différents niveaux de la hiérarchie du contexte pour alimenter votre application avec différents objets.

XXXI-4. Addons de modèle

Vous pouvez ajouter des addons au modèle d'application. Ces addons contiennent une référence à des classes Java, qui peuvent étendre le contexte ou d'interagir avec d'autres services de la plate-forme Eclipse, par exemple le EventAdmin.

Par exemple, vous pouvez enregistrer un addon de modèle pour ajouter quelques valeurs dans le contexte.

Image non disponible

Le code suivant montre un exemple d'implémentation de l'addon.

 
Sélectionnez
package com.example.e4.rcp.todo.addons;

import javax.annotation.PostConstruct;

import org.eclipse.e4.core.contexts.IEclipseContext;

public class MyModelAddon {
  @PostConstruct
  public void init(IEclipseContext context) {
    context.set("test1", "Hello");
  }
} 

XXXI-5. RunAndTrack

IEclipseContext vous permet d'enregistrer un objet de type RunAndTrack avec la méthode runAndTrack().

Un RunAndTrack est essentiellement un Runnable qui a accès au contexte. Si le runnable accède à n'importe quelle valeur dans ce contexte, au cours de son exécution, le runnable sera exécuté à nouveau si une de ces valeurs change.

La méthode runAndTrack() permet à un client de garder un état externe synchronisé avec une ou plusieurs valeurs de ce contexte.

Le runnable n'a pas besoin d'être explicitement désinscrit dans le contexte lorsqu'il n'est plus concerné par le suivi des modifications. Si aucune invocation ultérieure de ce runnable n'a eu accès à une des valeurs de ce contexte, il est automatiquement désinscrit du suivi des modifications dans ce contexte.

XXXI-6. Fonctions de contexte

Si le Framework de l'injection de dépendances d'Eclipse ne trouve pas un objet dans le contexte actuel, il interroge les fonctions de contexte définies pour voir si une classe a été enregistrée pour la créer.

Les fonctions de contexte implémentent l'interface IContextFunction ou étendent la classe abstraite ContextFuntion et vous permettent de créer un objet par instanciation paresseuse (par nécessité).

Dans Eclipse 4, vous avez a étendre la classe ContextFunction afin de recevoir IEclipseContext comme entrée de la méthode compute().

Les fonctions de contexte sont apportées comme services OSGi. Elle implémente l'interface IContextFunction du package org.eclipse.e4.core.contexts. L'environnement Eclipse 4 ajoute les fonctions de contexte par défaut au contexte de l'application.

Par le biais de la propriété service.context.key, elles définissent leur clé avec laquelle elles sont ajoutées au contexte.

XXXII. Utilisation de l'injection de dépendance pour vos propres objets Java

XXXII-1. Vue d'ensemble

L'utilisation de l'injection de dépendances pour vos propres objets Java a deux approches. D'abord, vous voulez que le conteneur de dépendance d'Eclipse crée vos propres objets et ensuite les injecte dans vos objets de modèle. Deuxièmement, vous voulez créer des objets qui déclarent leurs dépendances avec @Inject et vous voulez créer via l'injection de dépendance.

Les deux approches sont décrites ici.

XXXII-2. Utilisation de l'injection de dépendance pour obtenir vos propres objets

Si vous voulez que le framework Eclipse crée vos objets pour vous, annotez-les avec @Creatable. De cette façon, vous demandez au conteneur ID Eclipse qu'il crée une nouvelle instance de cet objet s'il ne trouve pas une autre instance dans le contexte.

Le conteneur de l'Injection de Dépendance d'Eclipse va utiliser le constructeur de cette classe ayant le plus grand nombre de paramètres pour lesquels le conteneur de l'injection de dépendance Eclipse peut trouver des valeurs dans le contexte Eclipse. Vous pouvez également utiliser @Inject sur le constructeur pour indiquer à Eclipse qu'il devrait essayer d'exécuter l'injection de dépendance aussi pour ce constructeur.

Par exemple, supposons que vous ayez le modèle de domaine suivant.

 
Sélectionnez
@Creatable
class Todo {
 @Inject
 public Todo(Dependent depend, YourOSGiService service) {
     // placeholder
 }
}
 
@Creatable
class Dependent {
 public Dependent() {
 // placeholder
 }
} 

Si aucun constructeur approprié n'est trouvé, le Framework Eclipse va lever une exception.

En supposant que vous ayez défini le service YourOSGiService dans votre application, vous pouvez obtenir une instance de votre modèle de données Todo injecté dans la part.

 
Sélectionnez
// Injection de champ
@Inject Todo todo 

XXXII-3. Utilisation de l'injection de dépendances pour créer des objets

L'utilisation de l'injection de dépendances ne se limite pas aux objets créés par le runtime Eclipse. Vous pouvez utiliser @Inject dans une classe Java et utiliser le Framework d'injection de dépendance pour créer votre classe.

 
Sélectionnez
// instanciation de la classe
ContextInjectionFactory.make(MyJavaObject.class, context); 

La méthode ContextInjectionFactory.make () crée l'objet. Vous pouvez aussi le mettre dans le contexte. Si vous voulez récupérer l'objet du contexte, vous pouvez utiliser la clé que vous avez spécifiée.

Pour cela, vous pouvez soit utiliser un contexte existant tel que décrit dans la dernière section ou un nouveau contexte. Utiliser un nouveau contexte est préférable afin d'éviter les collisions de clés et d'isoler vos modifications dans un contexte local.

 
Sélectionnez
IEclipseContext context = EclipseContextFactory.create();

// Ajoute vos objets Java au contexte
context.set(MyDataObject.class.getName(), data);
context.set(MoreStuff.class, moreData); 

XXXIII. Tags applicables dans le modèle d'application

Le tableau ci-dessous énumère les tags les plus importants pour les éléments du modèle applications d'Eclipse 4.

Des tags supplémentaires sont définis dans la classe IPresentationEngine. C'est à la mise en œuvre du rendu et aux addons du modèle d'interpréter ces tags. Le moteur de rendu peut également définir des tags supplémentaires. Vous trouverez également plus d'informations sur les tags disponibles dans le Wiki Eclipse 4 (voir Ressources pour le lien).

Tag Élément de modèle Description
shellMaximized Window or Trimmed Window La fenêtre est maximisée au lancement de l'application
shellMinimized Window or Trimmed Window La fenêtre est minimisée au lancement de l'application
NoAutoCollapse PartStack Permet d'éviter que l'addon MinMax minimise ce PartStack si toutes les parts ont été retirées.
FORCE_TEXT ToolItem Force l'affichage du texte et de l'image d'un élément de barre d'outils
NoMove Part Empêche l'utilisateur de déplacer la part (sur la base du DndAddON).

Tableau 17. Tags applicable aux éléments de modèle d'application

XXXIV. Eclipse 4 les bonnes pratiques

Les bonnes pratiques ont tendance à être subjectives. Si vous contestez certaines d'entre elles, n'hésitez pas à utiliser votre propre approche.

XXXIV-1. Extension du contexte Eclipse

L'application peut utiliser le contexte Eclipse pour fournir des fonctionnalités, de la communication et modifier le comportement d'Eclipse. Vous avez plusieurs options pour contribuer au contexte : services OSGi, les fonctions de contexte, les éléments de contexte, les variables de contexte et addons du modèle.

Le mode de programmation d'Eclipse 4 rend relativement facile d'utilisation des services OSGi, par rapport à Eclipse 3.x. Les services OSGi sont des singletons et n'ont pas accès au contexte d'application Eclipse. Les services OSGi sont une bonne approche pour les services d'infrastructure qui sont des singletons.

Les fonctions de contexte sont des services OSGi qui sont généralement stockés au niveau de l'application et ils ont accès au contexte d'application Eclipse. Si cela est nécessaire, ils peuvent être utilisés à la place des services OSGi typiques.

Les éléments de contexte sont utiles, si des valeurs doivent être stockées à de certains endroits de la hiérarchie du contexte Eclipse. Remplacer les implémentations de la plate-forme Eclipse est également un bon motif d'utilisation des éléments de contexte, par exemple, pour modifier le handler par défaut qui ferme une fenêtre.

Les fonctions de contexte et les variables de contexte sont utiles dans les situations où les variables doivent changer et sont différentes pour les différents niveaux de la hiérarchie du contexte Eclipse.

Les addons du modèle vous permettent de faire participer des objets Java dans le contexte de l'application. L'avantage des addons du modèle est qu'ils font partie du modèle de l'application. Par conséquent, ils sont des éléments très visibles. Un addon de modèle peut s'inscrire lui-même aux événements ou contribuer à nouveau au contexte Eclipse.

XXXIV-2. Communication de l'application

Pour la communication portée sur l'interface utilisateur, il est recommandé d'utiliser des variables de contexte ou le service EventAdmin pour communiquer l'état.

Le service EventAdmin est un bon choix, s‘il n'y pas de périmètre associé dans la communication. Les points forts d'EventAdmin sont que des listeners arbitraires peuvent écouter les événements et que le mécanisme de publication/abonnement est relativement simple.

XXXIV-3. Modèle d'application statique vs dynamique

Si votre modèle d'application est essentiellement statique, vous devez le définir statiquement, de même que ce modèle statique vous offre une bonne visibilité de votre application durant le développement.

Si nécessaire, ajoutez un comportement dynamique. Ces parts dynamiques peuvent être évaluées à l'exécution avec l'éditeur de modèle temps réel.

XXXV. Développement basé sur les composants

Eclipse et OSGi supportent le développement basé sur les composants.

L'interface utilisateur apparentée et les fonctionnalités de base devraient être séparées en différents plug-ins.

Le modèle de données de l'application doit être tenu dans son propre plug-in. Pratiquement tous les plug-ins dépendront de ce plug-in, donc maintenez-le aussi léger que possible.

XXXV-1. Utilisation de vos propres points d'extension

Le modèle de programmation d'Eclipse 4 a réduit le recourt aux points d'extension, mais ils restent toujours utiles dans certains cas.

Si vous avez plusieurs plug-ins qui doivent prendre part à une API définie, vous pouvez toujours définir et utiliser vos propres points d'extension.

XXXV-2. Définition d'API

Les plug-ins Eclipse déclarent explicitement leur API avec leurs packages exportés. Publiez uniquement les packages sensés être utilisés par d'autres plug-ins. De cette façon, vous pouvez par la suite modifier votre API interne sans affecter les autres plug-ins. Évitez d'exporter des packages juste pour des tests.

XXXV-3. Dépendances par package vs Plug-in

OSGi permet de définir des dépendances par le biais de plug-ins ou de packages.

Les dépendances à base de packages expriment une dépendance d'API, car ils vous permettent d'échanger l'implémentation de plug-in. La dépendance à base de plug-ins implique une dépendance sur une implémentation.

Utilisez les dépendances de package à chaque fois que vous avez l'intention d'échanger la mise en œuvre du plug-in.

Les dépendances de package ajoutent de la complexité a la configuration habituelle, vous avez plus de package que de plug-ins.

Par conséquent, utiliser la dépendance de plug-in, s'il n'y a qu'une seule implémentation de plug-in et un échange de ce plug-in, est peu probable dans un avenir proche.

XXXVI. Mots de la fin et remerciements

Je tiens à remercier Lars Vogel pour nous avoir permis de traduire son article, je remercie également Mickael BARON pour sa relecture technique et ses conseils, Cédric Duprez pour sa relecture orthographique et Claude LELOUP et Vincent VIAL pour leurs participations

XXXVII. Liens et lectures