Un utilisateur est souvent amené à fournir des informations textuelles dans une zone simple comme une zone de texte ou une zone de liste déroulante. Bien que le code de l'application qui alimente ces zones soit généralement plus simple que le code qui alimente un widget complexe, tel qu'un tableau ou une arborescence, ces zones "simples" requièrent plus d'efforts de la part de l'utilisateur. Celui-ci doit identifier les zones qui requièrent du contenu, si une zone contient du contenu valide et les sélections attendues. La prise en charge de l'assistant de zone JFace contient des classes qui guident l'utilisateur à travers les tâches de saisie.
Le package org.eclipse.jface.fieldassist propose deux types d'assistance. La prise en charge des zones décorées vous permet d'inclure des décorations d'image qui informent l'utilisateur de l'état d'une zone donnée. La prise en charge de la proposition de contenu vous permet d'offrir une fenêtre en incrustation d'assistant de contenu affichant des choix de contenu à l'utilisateur.
Les zones décorées vous permettent de placer des décorations d'image en regard des zones définies dans une fenêtre ou une boîte de dialogue. Les décorations peuvent être placées en regard de l'un des quatre angles d'une zone. Tout comme les afficheurs, les zones décorées sont destinées à ajouter une fonctionnalité à une commande SWT, tout en continuant à offrir un accès à la commande sous-jacente. L'API de DecoratedField vous permet d'ajouter, de masquer et d'afficher des décorations en regard d'une zone. L'accès à la commande sous-jacente est fourni pour vous permettre d'utiliser l'API SWT existante afin d'affecter la commande sous-jacente, par exemple, définir son contenu, sa couleur ou sa police.
Vue de l'extérieur, une zone décorée se comporte comme une commande simple. En réalité, les zones décorées utilisent une commande pour gérer la présentation de la zone et de ses décorations. Fondamentalement, cela ne doit pas avoir d'importance pour l'application client. Mais, cela signifie que la zone décorée doit effectuer la création de la commande. Par exemple, observez ce fragment, dans lequel une application crée une commande de texte dans l'une de ses boîtes de dialogue :
... // Créer une zone de texte Text text = new Text(parent, SWT.BORDER); text.setText("some text"); ...
Pour être décorée, cette zone doit être créée de la manière suivante :
... // Créer une zone décorée pour une commande de texte DecoratedField field = new DecoratedField(parent, SWT.BORDER, new TextControlCreator()); Text text = (Text)field.getControl(); text.setText("some text"); ...
Les mêmes éléments de style et de parent que ceux qui seraient utilisées pour créer la commande de base sont également utilisés pour créer une zone décorée. La principale différence dans le code réside dans le fait qu'une instance de IControlCreator, créant le type de commande spécifique souhaité dans la zone, est fournie. Dans le cas des zones de texte, vous pouvez utiliser la classe TextControlCreator pour créer la commande. Toutefois, vous avez la possibilité d'implémenter IControlCreator pour créer tout autre type de commande dans la zone, comme une zone de liste déroulante ou une flèche, par exemple.
Lorsqu'une zone décorée est créée, des décorations peuvent y être ajoutées, dans l'un des quatre angles. Les constantes d'emplacement SWT permettent d'indiquer où la décoration doit être placée. Pour ajouter une décoration, vous devez indiquer un FieldDecoration, qui définit l'image de la décoration, et le texte descriptif (facultatif) qui s'affiche lorsque l'utilisateur survole la décoration.
... // Créer une décoration de zone et l'ajouter à la zone Image image = JFaceResources.getImage("myplugin.specialimage"); FieldDecoration mySpecialDecoration = new FieldDecoration(image, "This field is special"); field.addFieldDecoration(mySpecialDecoration, SWT.TOP | SWT.LEFT, false); ...
Le paramètre booléen sert à indiquer si la décoration doit s'afficher uniquement lorsque la commande est sélectionnée ou si elle doit s'afficher en permanence. Dans le cas présent, la décoration s'affichera en permanence. Toutefois, il peut arriver que la décoration doive être masquée ou affichée. Le fragment suivant masque une décoration existante.
... // Pour une raison quelconque, j'ai besoin de masquer la décoration field.hideDecoration(mySpecialDecoration); ...
Si l'image ou la description d'une décoration est mise à jour, la zone doit en être informée, de manière à retracer la décoration.
... // Pour une raison quelconque, la zone est devenue spéciale mySpecialDecoration.setDescription("This field is extra-special"); field.updateDecoration(mySpecialDecoration); ...
Lors de la mise en forme d'une zone décorée dans une boîte de dialogue ou une fenêtre, vous devez mettre en forme la commande de mise en forme de la zone au lieu de la commande simple sous-jacente. Observez à nouveau le code qui permet de créer une commande de texte. Lorsque vous mettez une commande de texte en forme, l'application définit des données de mise en forme sur la commande.
... // Créer une zone de texte Text text = new Text(parent, SWT.BORDER); text.setText("some text"); // Définir les données de mise en forme GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT); text.setLayoutData(data); ...
Lors de la mise en forme d'une zone décorée, l'application doit laisser les données de mise en forme dans la commande de mise en forme de la zone. En fonction de la présentation souhaitée, il se peut que la taille de la zone doive être ajustée pour la taille de la décoration.
... // Créer une zone décorée pour une commande de texte DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator()); Text text = (Text)field.getControl(); text.setText("some text"); // Définir les données de mise en forme GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH + FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(), SWT.DEFAULT); field.getLayoutControl().setLayoutData(data); ...
La prise en charge de l'assistant de zone ne requiert pas (ni ne suppose) que vous utilisiez uniquement des zones décorées dans une boîte de dialogue ou une fenêtre spécifique. Cependant, la présentation de votre fenêtre peut devenir un peu compliquée lorsque des zones décorées sont associées à de simples commandes. Pour aligner des zones décorées et des zones non décorées, vous devez prendre en compte le retrait crée par la largeur de la décoration. La largeur d'une décoration est simplement la largeur de son image. Les choses peuvent toutefois se compliquer si vous utilisez des décorations de largeur différente. Si tel est le cas, vous pouvez simplifier l'opération en enregistrant toutes vos décorations dans le registre FieldDecorationRegistry.
Le registre de décoration de zone vous permet d'enregistrer vos décorations de zone et d'y accéder à l'aide d'un ID chaîne. Ceci permet facilement de faire référence à des décorations utilisées dans l'ensemble de votre application. Vous pouvez choisir de définir une API qui affiche vos ID de décoration si vous souhaitez les mettre à disposition d'autres plug-ins. Notez que l'enregistrement d'une décoration ne gère pas le cycle de vie des images situées à l'intérieur de ces décorations. Votre application peut décider de la manière dont vous allez gérer ces images. Par exemple, le registre d'images JFace peut être utilisé pour enregistrer et gérer le cycle de vie de l'image. Votre application peut également vouloir créer l'image à la demande et la supprimer lorsque celle-ci n'est plus utile. Le javadoc correspondant aux méthodes d'enregistrement dans FieldDecorationRegistry explique les différentes manières dont les images peuvent être indiquées lors de l'enregistrement d'une décoration.
Enregistrer vos décorations dans le registre des décorations de zone peut également simplifier la présentation lorsque des zones décorées et non décorées sont utilisées. Par défaut, une zone décorée consultera le registre des décorations de zone afin de déterminer la largeur maximale d'une décoration, et s'assurera que toutes les décorations utiliseront cette largeur. Par conséquent, toutes les zones décorées s'aligneront correctement, quelle que soit la largeur d'une décoration en particulier. Pour aligner les zones non décorées, vous pouvez utiliser le protocole FieldDecorationRegistry pour accéder à la largeur de la décoration la plus large et créer le retrait nécessaire.
... // Créer une zone de texte Text text = new Text(parent, SWT.BORDER); text.setText("some text"); // Définir les données de mise en forme GridData data = new GridData(); data.horizontalAlignment = SWT.FILL; data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(); text.setLayoutData(data); ...
Bien que l'assistance de l'assistant de zone ne précise pas comment les décorations doivent être utilisées, le registre définit également les décorations standard qui peuvent être utilisées par les applications pour afficher certains états d'une zone. Par exemple, le fragment suivant utilise une décoration standard pour les zones obligatoires :
... // Créer une zone décorée avec une décoration de zone obligatoire. DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator()); FieldDecoration requiredFieldIndicator = FieldDecorationRegistry.getDefault(). getFieldDecoration(FieldDecorationRegistry.DEC_REQUIRED); field.addDecoratedField(requiredFieldIndicator, SWT.BOTTOM | SWT.LEFT, false); ...
Outre l'annotation des zones avec les décorations, les applications peuvent fournir un assistant de proposition de contenu qui active une fenêtre en incrustation de proposition d'une zone. Vous pouvez installer un élément ContentProposalAdapter sur un contrôle arbitraire dans le but de fournir ce comportement. Le fragment suivant installe un adaptateur de proposition de contenu sur une commande de texte. Vous devez savoir que cette commande de texte peut être créée directement par l'application ou extraite d'une zone décorée.
... autoActivationCharacters = new char[] { '#', '(' }; keyStroke = KeyStroke.getInstance("Ctrl+Space"); // imaginons que myTextControl ait déjà été créée ContentProposalAdapter adapter = new ContentProposalAdapter( myTextControl, new TextContentAdapter(), new SimpleContentProposalProvider(new String [] {"ProposalOne", "ProposalTwo", "ProposalThree"}), keyStroke, autoActivationCharacters);
Pour extraire et définir le contenu de la commande lorsque l'utilisateur choisit une proposition dans la fenêtre en incrustation, l'adaptateur doit être fourni avec une instance de IControlContentAdapter, capable d'extraire et de définir le contenu d'un type de commande particulier. Pour les zones de texte, vous pouvez utiliser la classe TextContentAdapter. Toutefois, vous avez la possibilité d'implémenter IControlContentAdapter pour utiliser l'adaptateur de proposition de contenu avec tout autre type de commande.
Lors de la création d'un adaptateur de proposition de contenu, vous devez également indiquer une instance de IContentProposalProvider, dont les propositions sont elles-mêmes extraites. Ce fournisseur est chargé de renvoyer un tableau de propositions de contenu. Les propositions sont indiquées sous forme d'instances de IContentProposal, dont le libellé et le contenu de la proposition peuvent être extraits, en complément d'autres informations, telles que la description détaillée de la proposition.
Dans l'exemple précédent, on utilise l'élément SimpleContentProposalProvider. Ce fournisseur est défini en indiquant un simple tableau de chaînes, telles que des propositions de contenu. Le fournisseur simple implémente le protocole nécessaire pour mapper chaque chaîne dans l'élément IContentProposal attendu. La souplesse d'utilisation de IContentProposalProvider vous permet d'implémenter un fournisseur de proposition avec des fonctions avancées, comme le filtrage des propositions en fonction du contenu de la commande, en fournissant des étiquettes explicatives dans la fenêtre en incrustation au lieu du contenu réel qui sera inséré et en indiquant la position du curseur attendue après l'insertion d'une proposition. Consultez l'exemple d'assistant de zone et recherchez des implémenteurs de IContentProposalProvider pour une utilisation avancée.
Nous avons vu que la définition de base d'un adaptateur de proposition de contenu inclut la commande pour laquelle les propositions sont fournies, l'adaptateur de contenu utilisé pour modifier le contenu de la commande et le fournisseur de propositions qui définit la liste des propositions dans la fenêtre en incrustation. Outre ces éléments fondamentaux, il existe de nombreuses manières de configurer l'adaptateur de proposition de contenu :
L'assistance de l'assistant de zone au niveau JFace offre beaucoup de souplesse à votre application en déterminant comment décorer les zones et afficher les propositions pour le contenu de la zone. Elle est recommandée pour les applications JFace autonomes ou les applications client riches autonomes. Cependant, si votre application est destinée à s'intégrer avec d'autres plug-ins, comme le SDK Eclipse ou des plug-ins tiers, vous voudrez probablement utiliser le support de l'assistant de zone de manière cohérente avec les autres plug-ins. Le plan de travail définit les classes utilitaires qui utilisent l'assistant de zone pour des types d'interactions spécifiques.
Par exemple, la classe ContentAssistField crée une zone qui contient une décoration d'ampoule visant à informer l'utilisateur que l'assistant de contenu est disponible. Elle configure également un adaptateur de proposition de contenu pour l'insertion de type assistant de contenu. Enfin, elle fournit un gestionnaire pour la commande d'assistant de contenu au niveau du plan de travail de sorte que la fenêtre en incrustation de proposition de contenu s'ouvre lorsque l'utilisateur appelle la frappe ou la séquence de déclenchement indiquée dans les associations de touches du plan de travail. Voir le package org.eclipse.ui.fieldassist pour plus d'informations sur ces classes utilitaires.
Ce package est destiné à évoluer à mesure que le plan de travail étend son utilisation de l'assistant de zone et standardise l'utilisation des décorations pour certains états de zone.