dimanche, décembre 06, 2009

J'ai besoin d' ... ajouter dynamiquement des éléments à un menu Eclipse

Lars Vogel propose sur son blog un billet qui explique comment créer et afficher une commande à l'exécution d'une application Eclipse.

Sur le support de cours des commandes que je propose depuis peu, je vais un peu plus loin dans la démonstration. Je montre comment créer et afficher une commande dans un menu en ajoutant une restriction visibleWhen. Je vous propose dans ce billet une explication de cet exemple.

Une vue est utilisée pour ajouter la commande dans le menu principal. Il est ensuite possible d'afficher ou de cacher la commande du menu. Pour cela la vue fournit trois boutons (Create, Hide et Show). Vous trouverez ci-dessous des captures d'écran de l'exemple.




Au niveau des pré-requis, je suppose qu'une commande et un handler sont définis. L'identifiant de la commande est ...helloworldcommandid

Au niveau du code de l'action du bouton Create, présenté ci-dessous, il est codé que la commande doit s'afficher dans la barre de menu principal (menu:org.eclipse.ui.main.menu), que l'identifiant de la commande est ...helloworldcommandid et enfin que la restriction visibleWhen est contrainte par l'expression définie par currentExpression.
public void createParControl(Composite parent) {
...
final Button myButton = new Button(parent, SWT.NONE);
myButton.setText("Create");
myButton.setLayoutData(myData);
myButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
IMenuService service = (IMenuService)PlatformUI.getWorkbench().getService(IMenuService.class);
AbstractContributionFactory ref = new AbstractContributionFactory("menu:org.eclipse.ui.main.menu", null) {
public void createContributionItems(IServiceLocator serviceLocator, IContributionRoot additions) {
CommandContributionItemParameter commandParameter = new CommandContributionItemParameter(serviceLocator, "contributionitem", "eclipse.workbench.commandsprogrammaticvisiblewhenexamples.helloworldcommandid" CommandContributionItem.STYLE_PUSH);
currentExpression = new Expression() {
public EvaluationResult evaluate(IEvaluationContext context) throws CoreException {
if (isVisible) {
return EvaluationResult.TRUE;
} else {
return EvaluationResult.FALSE;
}
}
};
item = new CommandContributionItem(commandParameter);
additions.addContributionItem(item, currentExpression);
}
};
service.addContributionFactory(ref);
myButton.setEnabled(false);
}
});
...
}
Dans la méthode evaluate, vous noterez que l'attribut isVisible est utilisé pour aiguiller si la commande doit être affichée ou pas. Toute la difficulté est de notifier l'expression lorsque l'attribut isVisible est modifié. Pour cela, j'ai examiné le code source de la plateforme Eclipse (merci l'Open Source) et j'ai remarqué que les expressions utilisées pour les restrictions visibleWhen étaient notifiées lorsque la Shell de la WorkbenchWindow recevait un événement Activate.

Ci-dessous est présenté le code utilisé pour mettre à jour l'expression définie par currentExpression.
private void updateExpression() {
WorkbenchWindow current = (WorkbenchWindow)PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final Set menuRestrictions = current.getMenuRestrictions();
if (menuRestrictions == null) { return; }
IEvaluationService es = (IEvaluationService)PlatformUI.getWorkbench().getService(IEvaluationService.class);
IEvaluationContext currentState = es.getCurrentState();
EvaluationReference[] refs = (EvaluationReference[]) menuRestrictions.toArray(new EvaluationReference[menuRestrictions.size()]);
boolean changeDetected = false;
for (EvaluationReference evalRef : refs) {
final Expression expression =evalRef.getExpression();

if (expression == currentExpression) {
evalRef.setPostingChanges(true);
boolean os = evalRef.evaluate(currentState);
evalRef.clearResult();
boolean ns = evalRef.evaluate(currentState);
if (os != ns) {
changeDetected = true;
evalRef.getListener().propertyChange(new PropertyChangeEvent(evalRef, evalRef.getProperty(), valueOf(os), valueOf(ns)));
}
}
}

if (changeDetected) {
IMenuService ms = (IMenuService) PlatformUI.getWorkbench().getService(IMenuService.class);
if (ms instanceof WorkbenchMenuService) {
((WorkbenchMenuService) ms).updateManagers();
}
}
}
Si vous examinez la méthode liftRestrictions de la classe WorkbenchWindow, vous noterez que cela est très similaire. De manière à éviter de rafraichir l'intégralité des expressions des restrictions visibleWhen, j'ai placé un filtre sur l'expression définie précédemment.

Enfin, sur le code des actions des boutons hide et show, l'attribut isVisible est modifié et la méthode updateExpression est appelée. Ci-dessous est présenté le code de l'action show.
public void createPartControl(Composite parent) {
...
Button hideMenuContribution = new Button(parent, SWT.NONE);
hideMenuContribution.setText("Hide");
hideMenuContribution.setLayoutData(myData);
hideMenuContribution.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
isVisible = false;
updateExpression();
}
});
}
Les codes sources de l'exemple sont disponibles à cette adresse.

samedi, décembre 05, 2009

Liens pratiques de la semaine

Vous trouverez ici une sélection de liens pratiques autour des technologies Java qui m'ont particulièrement intéressées ces dernières semaines.

Eclipse
  • Un billet de Lars Vogel qui propose une liste gratuite d'icônes pour vos applications Eclipse RCP (ou autre).
  • Le nouveau projet Gemini hébergé par la fondation Eclipse se veut être un conteneur de différentes spécifications Entreprise Java EE pour le monde OSGi (JPA, JMX, ...). Pour information, la fondation Apache se lance également dans ce créneau via le projet Apache Aries.
  • Lars Vogel propose un nouveau tutoriel sur le sujet du Drag & Drop.
  • Si vous souhaitez comprendre ce qu'est un nature dans la plateforme Eclipse, lisez ce tutoriel proposé par Lars.
  • Le projet OpenSocial Gadgets regroupe un ensemble de composants comme ceux que l'on peut trouver sur la page iGoogle (billet de l'annonce).
  • Un article qui présente les techniques de refactoring avec l'environnement de développement Java (JDT) d'Eclipse.
Java
  • Un billet qui explique comment rediriger le port 8080 de Tomcat vers le port 80 d'Apache 2
  • Java 7 se prépare voici la milestone 5. Sur cette page vous trouverez les exécutables à télécharger.
  • Simple est une bibliothèque qui permet de sérialiser et de-sérialiser en XML. L'aspect intéressant de cette bibliothèque est la définition de la structure du schema XML par annotation de classe Java (tutoriel).
  • Un article qui présente les closures qui seront disponibles dans la prochaine version de Java.
Divers
  • Pour le fun, un site qui permet de générer des nuages de mots clés.

mercredi, novembre 25, 2009

Introduction à la construction de Commandes avec la plateforme Eclipse

Un support de cours concernant la construction de commandes est disponible sur le site de Developpez.com. Il fait parti de la série des supports de cours liée au Workbench et il fait suite au support de cours relatif aux vues.

Les aspects suivants sont étudiés :
  • Avant les commandes il y avait les actions
  • Construction par déclaration et programmation des commandes
  • Elément menuContribution par déclaration
  • Raccourcis clavier
  • Restrictions (visibleWhen, enabledWhen et activeWhen)
  • Paramétrer les commandes
  • Restrictions par programmation
  • Réutilisation (Plugin Spy et activation des traces)
Le lien du support de cours et les exemples peuvent être trouvés ici.

samedi, novembre 14, 2009

Liens pratiques de la semaine

Vous trouverez ici une sélection de liens pratiques autour des technologies Java qui m'ont particulièrement intéressées ces dernières semaines.

Eclipse
  • De retour de Eclipse Summit Europe, Tom Schindl fournit les transparents de ces sessions. Les travaux présentés sont centrés sur le futur Eclipse e4.
  • Même si e4 se prépare pour une sortie en 2010, il ne faut pas oublier que Eclipse 3.6 se prépare également. Eclipse 3.6 M3 est disponible (page de nouveautés et page de téléchargement).
Java
  • Tomcat a 10 ans, un grand bravo pour un serveur d'application léger très pratique pour mes développements et la préparation de mes supports de cours.
  • Subversion devient un projet de la fondation Apache. De mon point de vue il s'agit d'une très bonne nouvelle (annonce).
  • Le projet Atmosphere permet de faire du push serveur sur n'importe quel type de serveur d'application. A noter que la fonctionnalité de faire du push serveur sera intégrée dans la prochaine version de Servlet 3.0
Divers
  • Un billet très pratique qui présente tout un tas d'expressions régulières pour faire par exemple un tri sur une adresse email correctement formée ...

vendredi, novembre 13, 2009

Google Wave, mon invitation est arrivée

Un petit billet pour vous annoncer que je viens enfin de recevoir une invitation pour Google Wave. Je vous ferai un retour très prochainement.

Cette invitation est accompagnée d'autres invitations. Les plus motivés qui me laissent un commentaire auront droit à des invitations.

mercredi, novembre 04, 2009

Introduction à FLEX : supports de cours non finalisé

Comme indiqué dans un précédent billet, j'ai abandonné les supports de cours concernant la partie FLEX. Je mets donc à disposition en libre utilisation (source powerpoint) les premières ébauches relatives à ce sujet.

J'ai dans l'espoir que des personnes motivées continuent ce travail.

Un document au format powerpoint est disponible ici. Il correspond à la partie introduction.

Bonne lecture sur les choses présentes.

vendredi, octobre 30, 2009

Liens pratiques de la semaine

Vous trouverez ici une sélection de liens pratiques autour des technologies Java qui m'ont particulièrement intéressées ces dernières semaines.

Eclipse
  • Eclipse e4 1.0 Millestone 1 est sortie. La grande nouveauté est l'introduction d'un débugger JavaScript via l'utilisation de Mozilla Rhino. Page des nouveautés et page de téléchargement.
  • Un exemple de Lars Vogel qui montre comment utiliser l'API d'accès aux dépendances de plugin.
  • Angelo Zerr continue ses articles sur la création d'une application Eclipse RCP qui communique avec un serveur OSGi basé sur Spring DM. Quatre nouveaux billets sont disponibles billet 3, billet 4, billet 5 et billet 6. Merci à Angelo pour ces ressources de très bonnes qualités.
Java
  • La société Jetbrains fournit en Open Source son environnement de développement IntelliJ IDEA. J'ai testé cette version et malheureusement les choses qui m'intéressent ne sont pas incluses dans la version Open Source, il faut passer par la version payante ...

J'ai besoin de ... cacher ou afficher des commandes en fonction de la perspective courante

Actuellement je suis en train de rédiger un support de cours autour de la nouvelle API Commands et le moins que l'on puisse dire : enfin ...

Avant, pour enrichir un menu, une barre d'outils ou un menu contextuel, il fallait passer par l'API Actions. C'était assez galère et la plupart du temps tout se faisait de manière "programmatique". L'API Commands permet d'étendre les menus et les barres d'outils de manière déclarative en se focalisant principalement sur la déclaration via la construction d'extensions. Il se peut qu'il y ait encore des classes à créer mais cela s'est sensiblement réduit.

Ce billet présente un exemple d'utilisation de cette nouvelle API. L'exemple consiste à cacher des commandes selon la perspective active. Les points pédagogiques de ce billet sont
  • Réutiliser des commandes définies par la plateforme Eclipse
  • Utiliser des Command Core Expressions
  • Ajouter une commande au menu d'une application Eclipse de manière déclarative
  • Ajouter une commande au menu et à la barre d'outils d'une vue de manière déclarative
Réutilisation de commandes prédéfinis

J'utiliserai des commandes et des handlers prédéfinis par la plateforme Eclipse. Ces commandes se focalisent essentiellement sur la manipulation de perspectives. Vous trouverez ci-dessous les commandes que je souhaite employer et leurs identifiants respectifs :
  • org.eclipse.ui.window.closeAllPerspectives : ferme toutes les perspectives
  • org.eclipse.ui.window.closePerspective : ferme la perspective courante
  • org.eclipse.ui.window.nextPerspective : active la perspective suivante
  • org.eclipse.ui.window.previousPerspective : active la perspective précédente
  • org.eclipse.ui.window.savePerspective : sauvegarder la perspective courante
  • org.eclipse.ui.window.customizePerspective : modifier la perspective courante
  • org.eclipse.ui.perspectives.showPerspective : affiche une perspective
Création d'éléments menuContribution

La création d'un élément menuContribution va nous permettre d'enrichir une barre de menu, une barre d'outils, une barre de menu d'une vue, une barre d'outils d'une vue ou d'un menu contextuel.

Dans ce billet, j'ai m'attarder à enrichir une barre de menu principale et celle d'une vue puis une barre d'outils d'une vue.

Il faut créer une extension basée sur le point d'extension org.eclipse.ui.menus comme indiqué sur la figure ci-dessous.


Ajoutez ensuite un élément menuContribution et créez un sous élément de type menu. Puis, au niveau de l'élément menuContribution modifiez l'attribut locationURI avec la valeur menu:org.eclipse.ui.main.menu, ceci permettra d'enrichir le menu principal de l'application Eclipse.


Au niveau de l'attribut de l'élément menu, modifiez l'attribut label qui est le nom du menu affiché dans la barre de menu principal par la valeur Perspective Commands.


J'ajoute ensuite à l'élément menu plusieurs sous éléments de type command. De cette façon, je regroupe dans le menu Perspective Commands cinq commandes prédéfinies par la plateforme Eclipse. Pour chaque élément command, je modifie l'attribut commandId qui désigne l'identifiant de la commande. Pour éviter toutes erreurs, j'utilise le bouton Browse et je recherche l'identifiant de la commande qui m'intéresse. Sur la capture d'écran ci-dessous, je présente l'élément command (sous élément de menu) associé à la commande org.eclipse.ui.window.closeAllPerspectives.


Concernant l'enrichissement de la barre d'outils d'une vue le procédé reste le même. Ajoutez un élément menuContribution puis un sous élément command. Dans l'attribut locationURI indiquez cette fois toolbar:eclipse.workbench.commandsperspectiveexample.commandsviewsampleid dont le suffixe désigne l'identifiant de la vue cible.


Pour l'élément command, je renseigne l'attribut commandId par la valeur org.eclipse.ui.window.customizePerspective qui permet d'appeler la commande en charge de modifier le contenu d'une perspective.

Finalement pour l'enrichissement de la barre de menu de la vue, procédez de la même façon. Par contre la valeur de l'attribut locationURI est menu:eclipse.workbench.commandsperspectiveexample.commandsviewsampleid et la valeur de l'attribut commandId est org.eclipse.ui.perspectives.showPerspective.

Avant de continuer, testons le résultat attendu. Vous devriez obtenir ceci :


Création d'une restriction visibleWhen

Attardons-nous maintenant à ajouter une restriction de type visibleWhen sur un élément du menu que nous avons créé (notamment nous désirons cacher l'élément Fermer toutes les perspectives).

La restriction visibleWhen appliquée à un élément menuContribution consiste à cacher un élément graphique (élément de menu ou de barre d'outils) lorsque l'expression associée à la restriction est évaluée comme fausse.

L'expression que nous allons exprimer consiste à afficher la-dite commande si la perspective active est égale à MyEmptyPerspective. Cette dernière est une perspective que nous allons créer.

Pour commencer, sélectionnez la commande Fermer toutes les perspectives.


Ajoutez un sous élément visibleWhen


Ajoutez un sous élément with et précisez dans l'attribut variable la valeur activeWorkbenchWindow.activePerspective. Ceci permet de récupérer le contenu de cette variable.


Enfin ajoutez un sous élément equals et précisez dans l'attribut value la valeur MyEmptyPerspective.


Lors du test, la commande Fermer toutes les perspectives localisée dans le menu PerspectiveCommands ne doit pas être affichée. Par contre, si vous créez une nouvelle perspective (en utilisant la commande Save Perspective As ...) et en l'appelant MyEmptyPerspective puis en l'activant cette commande devrait être disponible.

Le mot de la fin ...

L'API Commands facilite l'enrichissement de la barre de menu, barre d'outils, etc. Dans un prochain billet, je vous montrerai comment utiliser et créer un Property Tester.

Le code source de cet exemple est disponible ici.

lundi, octobre 12, 2009

Atelier Construction Plug-in avec la plateforme Eclipse sur Developpez.com

Les leçons tirées de l'atelier Construction Plug-in avec la plateforme Eclipse sont disponibles sous le format Developpez.com.

Pour l'instant, la première et la deuxième leçons sont uniquement disponibles. Les autres viendront quand j'aurai effectué le passage dans le format.

Leçon 1 : Construction d'un Plug-in
Leçon 2 : Perspectives

mercredi, octobre 07, 2009

Atelier Construction Plug-in avec la plateforme Eclipse : leçon 2 / Perspectives

Je continue la diffusion des supports concernant l'atelier Construction Plug-in avec la plateforme Eclipse (précédent billet).

Vous trouverez donc dans ce billet, les supports de la leçon 2.
Les autres leçons devraient être disponibles très prochainement.