Il revient à l'éditeur et à son afficheur de texte d'implémenter la présentation du document et de configurer les classes auxiliaires requises. (Si vous ne connaissez pas bien la notion d'afficheur, reportez-vous à la section Afficheurs.)
Un TextViewer gère les détails de faible niveau de mappage du modèle de document et de ses partitions pour obtenir le texte en couleur et formaté que voit l'utilisateur. Un SourceViewer est fournit pour les éditeurs de style de code source. Un afficheur de code source introduit la notion d'annotations de code source. Ces annotations peuvent apparaître dans une règle verticale sur la gauche du texte, dans une règle sur la droite du texte, ou sous forme de traits de couleur ondulés sous le texte.
SourceViewer et ses classes auxiliaires sont utilisés dans toute la hiérarchie AbstractTextEditor. Le module org.eclipse.jface.text.source définit cet afficheur ainsi que les autres classes prenant en charge la présentation des annotations.
Nous avons vu précédemment qu'outre le document lui-même, un fournisseur de documents propose un modèle d'annotations du document, IAnnotationModel. Ce modèle d'annotation gère les annotations, les énumère à la demande et traque les modifications de texte de sorte que les annotations soient toujours en conformité avec le texte. Le JavaDocumentProvider hérite du comportement défini dans FileDocumentProvider et son modèle d'annotation.
protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { if (element instanceof IFileEditorInput) { IFileEditorInput input= (IFileEditorInput) element; return new ResourceMarkerAnnotationModel(input.getFile()); } return super.createAnnotationModel(element); }
ResourceMarkerAnnotationModel définit un modèle d'annotation qui correspond à un marqueur sur une ressource dans l'espace de travail. (Pour plus d'informations sur les marqueurs, reportez-vous à la section Marqueurs de ressources.) Il affecte une image et une description à chaque marqueur et surveille toute modification des marqueurs de la ressource.
Pour voir comme un modèle d'annotation s'affiche dans un éditeur de texte, voyons comment fonctionne l'éditeur de texte de la plateforme et comment il utilise les règles et les annotations. Les spécificités d'affichage des différentes annotations sont indiquées dans les règles et l'utilisateur peut contrôler le texte dans les préférences Plan de travail > Editeurs > Editeur de texte sous l'onglet Annotations.
Une règle verticale, affichée sur la gauche de la zone de l'éditeur, permet aux éditeurs de texte de la plateforme d'afficher des plages de texte et des annotations en ligne à côté de leur ligne de texte.
Ces annotations sont décrites dans le ResourceMarkerAnnotationModel fourni. Ce modèle est défini dans le SourceViewer lorsque l'afficheur de code source est initialisé par l'éditeur. L'extrait de code suivant de AbstractTextEditor montre comment le document et le modèle d'annotation sont associés à l'afficheur.
private void initializeSourceViewer(IEditorInput input) { IAnnotationModel model= getDocumentProvider().getAnnotationModel(input); IDocument document= getDocumentProvider().getDocument(input); if (document != null) { fSourceViewer.setDocument(document, model); ...
Une fois l'afficheur de code source configuré avec le document et le modèle d'annotation adéquats, il dispose de suffisamment d'informations pour présenter le document et assurer l'affichage des annotations appropriées dans la règle verticale de gauche. Le modèle est associé à la règle lors de la définition du document. L'extrait de code suivant montre ce qui se produit lorsqu'un document est défini dans l'afficheur de code source. Il a été simplifié par rapport au code réel du SourceViewer pour plus de clarté :
public void setDocument(IDocument document, IAnnotationModel annotationModel) { ... // crée un modèle d'annotation visuelle à partir du modèle fourni et // le stocke dans fVisualAnnotationModel ... if (fVerticalRuler != null) fVerticalRuler.setModel(fVisualAnnotationModel);
Ainsi, la règle est associée au modèle d'annotation approprié.
Observons la règle. Elle est créée par l'éditeur de texte puis connectée à l'afficheur de l'éditeur. L'exemple d'éditeur Java ne définissant pas de comportement particulier pour les règles, il hérite de la règle telle que définie dans TextEditor.
protected IVerticalRuler createVerticalRuler() { CompositeRuler ruler= new CompositeRuler(); ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH)); if (isLineNumberRulerVisible()) ruler.addDecorator(1, createLineNumberRulerColumn()); return ruler; }
L'éditeur de texte utilise une CompositeRuler. Cette règle ne dispose pas de présentation visuelle qui lui soit propre. La présentation est fournie par une liste de décorateurs qui affichent des colonnes IVerticalRulerColumn) dans la règle. Dans cet exemple, une colonne de règle qui affiche des annotations (AnnotationRulerColumn) est toujours ajoutée ainsi qu'une colonne de règle de numéro de ligne basée sur les préférences utilisateur. La colonne de règle d'annotation gère les particularités d'affichage des images d'annotation aux emplacements appropriés.
Quel que soit le nombre de classes impliquées dans l'affichage d'une règle, notez qu'il suffit à l'exemple d'éditeur de sous-classer les classes de la structure pour obtenir le comportement de la règle. JavaDocumentProvider hérite du modèle d'annotation de marqueur approprié fourni par FileDocumentProvider. JavaTextEditor hérite de la présentation de règle fournie par TextEditor.
Une règle, située sur le côté droit de la zone de l'éditeur, permet d'afficher des annotations concernant la totalité du document. Ces annotations s'affichent à un emplacement relatif à leur position dans le document et ne bougent pas lorsque l'utilisateur fait défiler le document. Il existe généralement une annotation correspondante sur la règle verticale lorsque cette portion du document est visible.
La règle verticale ci-dessous montre que le document contient deux tâches et un signet. Le texte avec signet étant visible, son annotation est également affichée sur la gauche.
L'utilisateur peut naviguer jusqu'à l'emplacement de l'annotation dans le code en cliquant sur l'annotation elle-même.
Les types d'annotations affichés dans la règle sont fonction des types d'annotations ajoutés à la règle. Dans le fragment de code suivant issu de SourceViewerDecorationSupport, les types d'annotations sont ajoutés dynamiquement à la règle. (Pour plus d'informations sur SourceViewerDecorationSupport, reportez-vous à la section suivante.)
private void showAnnotationOverview(Object annotationType) {
if (fOverviewRuler != null) { Color c= getAnnotationTypeColor(annotationType);
fOverviewRuler.setAnnotationTypeColor(annotationType, c); int l= getAnnotationTypeLayer(annotationType);
fOverviewRuler.setAnnotationTypeLayer(annotationType, l);
fOverviewRuler.addAnnotationType(annotationType);
fOverviewRuler.update();
} }
Cette règle est également fournie avec un IAnnotationAccess qui donne des informations concernant une annotation particulière, telles que son type et son mode d'affichage. TextEditor utilise un DefaultMarkerAnnotationAccess qui interprète les annotations en fonction de leurs types de marqueurs et qui consulte les préférences utilisateur pour savoir quels types de marqueurs doivent s'afficher dans la règle.
protected IAnnotationAccess createAnnotationAccess() { return new DefaultMarkerAnnotationAccess(fAnnotationPreferences); }
Reportez-vous à l'implémentation de DefaultMarkerAnnotationAccess et de MarkerAnnotation pour plus de détails sur la présentation des marqueurs dans la règle.
Outre les annotations des règles, un afficheur de code source peut afficher des annotations sous forme de traits ondulés de couleur dans le texte.
Nous reviendrons sur la création de l'afficheur de code source dans TextEditor.
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { ... ISourceViewer sourceViewer= new SourceViewer(parent, ruler, fOverviewRuler, isOverviewRulerVisible(), styles); fSourceViewerDecorationSupport= new SourceViewerDecorationSupport(sourceViewer, fOverviewRuler, fAnnotationAccess, sharedColors); configureSourceViewerDecorationSupport(); return sourceViewer; }
La classe SourceViewerDecorationSupport gère la plupart des décorations qui apparaissent dans un afficheur de code source, y compris les annotations de texte, les marges colorées, les lignes de curseur colorées, etc. Elle est configurée avec les préférences utilisateur de façon à répondre aux mises à jour dynamiques des modifications de ces préférences. La plupart des éditeurs n'ont pas à tenir compte des détails de conception de ces décorations. (Si vous devez vous pencher sur ces détails, reportez-vous à SourceViewerDecorationSupport et aux classes associées, telles que AnnotationPainter.). Vous devez toutefois savoir qu'elles sont les décorations disponibles de sorte que le SourceViewer et ses SourceViewerDecorationSupport soient correctement configurés.
Voyons la configuration qu'utilise TextEditor pour le support des décorations.
protected void configureSourceViewerDecorationSupport() { Iterator e= fAnnotationPreferences.getAnnotationPreferences().iterator(); while (e.hasNext()) fSourceViewerDecorationSupport.setAnnotationPreference((AnnotationPreference) e.next()); fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(DefaultMarkerAnnotationAccess.UNKNOWN, UNKNOWN_INDICATION_COLOR, UNKNOWN_INDICATION, UNKNOWN_INDICATION_IN_OVERVIEW_RULER, 0); fSourceViewerDecorationSupport.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR); fSourceViewerDecorationSupport.setMarginPainterPreferenceKeys(PRINT_MARGIN, PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN); fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey()); }
Notez que les préférences des annotations permettent de définir des types d'annotations pour toutes les annotations indiquées dans les préférences utilisateur, y compris les annotations fournies par n'importe quel plug-in sans se limiter à celles fournies par le plan de travail. Si vous ne voulez pas afficher toutes les annotations disponibles dans votre éditeur, vous devez remplacer cette méthode et ne définir le SourceViewerDecorationSupport qu'avec les types à afficher.