Kildefremvisere og annotationer

Editoren og dens tilsvarende tekstfremviser er hovedsageligt ansvarlige for implementeringen af dokumentets præsentation og konfigurationen af eventuelle påkrævede hjælperklasser. (Se Fremvisere, hvis du ikke er fortrolig med begrebet fremvisere.)  

En tekstfremviser, TextViewer, håndterer alle oplysninger på lavere niveau, som drejer sig om mapping af dokumentmodellen og dens dele til den farvede og formaterede tekst, brugerne ser. Til editorer af kildekodetyper stilles en kildefremviser, SourceViewer, til rådighed. En kildefremviser introducerer begrebet kildekodeannotationer. Disse annotationer kan vises i en lodret lineal i venstre side af teksten, i en oversigtslineal i højre side af teksten, eller som farvede 'squigglies' neden under teksten.

SourceViewer og dens hjælperklasser bruges i heleAbstractTextEditor-hierarkiet. Pakken org.eclipse.jface.text.source definerer denne fremviser og de andre klasser, som understøtter præsentation af annotationer.

Annotationer og linealer

Annotationer er ligesom dokumentdele meget afhængige af den type dokument, der redigeres. IAnnotationModel til et dokument er det, der indeholder annotationerne, optæller dem på anmodning og lytter efter tekstændringer, så annotationerne holdes ajour med teksten. Annotationsmodeller registreres i udvidelsenorg.eclipse.core.filebuffers.annotationModelCreation. Dette udvidelsespunkt gør det muligt for plugins at registrere en klasse, som opretter en annotationsmodel, der er relevant for en given filtype. Java-editoreksemplet bruger ikke dette udvidelsespunkt, så det overtager den annotationsmodel, som er defineret af platformen.

<extension
	point="org.eclipse.core.filebuffers.annotationModelCreation">
	<factory
		extensions="*"
		class="org.eclipse.ui.texteditor.ResourceMarkerAnnotationModelFactory">
	</factory>
</extension>   

Den leverede fabriksklasse opretter en ResourceMarkerAnnotationModel for filer af enhver filtype. Denne klasse viser annotationer, som repræsenterer en markering af en ressource i arbejdsområdet.  (Ressourcemarkeringer indeholder flere oplysninger om markeringer.) Den tildeler hver markering et billede og en beskrivelse og overvåger sin ressource for at konstatere, om der er ændringer af markeringerne.

For at undersøge, hvordan en annotationsmodel vises i en teksteditor, ser vi nu på platformens teksteditor og dens brug af linealer og annotationer. Brugeren kan angive, hvordan forskellige annotationer vises i linealer og tekst i indstillingerne under Generelt > Editorer > Teksteditorer > Annotationer.

Lodret lineal

En lodret lineal til venstre for redigeringsområdet bruges af platformens teksteditorer til at vise tekstintervaller og linjebaserede annotationer ud for deres tekstlinje.

Lodret lineal

Disse annotationer beskrives i den leverede ResourceMarkerAnnotationModel. Denne model placeres iSourceViewer, når kildefremviseren initialiseres af editoren. Følgende kodesekvens fra AbstractTextEditor viser, hvordan dokumentet og annotationsmodellen knyttes sammen med fremviseren.

private void initializeSourceViewer(IEditorInput input) {
		
	IAnnotationModel model= getDocumentProvider().getAnnotationModel(input);
	IDocument document= getDocumentProvider().getDocument(input);
		
	if (document != null) {
		fSourceViewer.setDocument(document, model);
		...

Når kildefremviseren konfigureres med et relevant dokument og en relevant annotationsmodel, har den tilstrækkeligt med oplysninger til at kunne præsentere dokumentet og sørge for, at de rigtige annotationer vises i den lodrette lineal til venstre. Modellen knyttes sammen med linealen, når dokumentet klargøres. Følgende kodesekvens viser, hvad der sker, når et dokument klargøres i kildefremviseren. For tydelighedens skyld er den forenklet i forhold til den faktiske kode i SourceViewer:

public void setDocument(IDocument document, IAnnotationModel annotationModel) {
	...
	// opret visuel annotationsmodel på basis af leveret model og gem den
	// i fVisualAnnotationModel
	...
	if (fVerticalRuler != null)
		fVerticalRuler.setModel(fVisualAnnotationModel);

Sådan knyttes linealen sammen med den relevante annotationsmodel.   

Lad os se på selve linealen. Den oprettes af teksteditoren og forbindes herefter med editorens fremvisningsfunktion. Da Java-editoreksemplet ikke definerer nogen speciel funktionsmåde for linealer, overtager den linealen som defineret i TextEditor.

protected IVerticalRuler createVerticalRuler() {
	CompositeRuler ruler= new CompositeRuler();
	ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
	if (isLineNumberRulerVisible())
		ruler.addDecorator(1, createLineNumberRulerColumn());
	return ruler;
}

Teksteditoren bruger en CompositeRuler. Denne lineal har ikke sin egen visuelle præsentation. Præsentationen stilles til rådighed af en liste over dekoratører, som viser kolonner (IVerticalRulerColumn) i linealen. I dette eksempel tilføjes en linealkolonne, som viser annotationer(AnnotationRulerColumn), altid, og en linealkolonne med linjenummer tilføjes på basis af brugerpræferencerne. Annotationslinealkolonnen håndterer detaljerne med at vise annotationsbillederne de rigtige steder.

Trods alle de klasser, som er involveret i at vise en lineal, vil du bemærke, at eksempeleditoren kun behøver at gøre strukturklasser til underklasser for at fremkalde linealfunktionsmåde.  JavaDocumentProvider overtager en relevant annotationsmodel for markeringer fra FileDocumentProvider. JavaTextEditor overtager linealpræsentationen fra TextEditor.

Oversigtslineal

En oversigtslineal i højre side af redigeringsområdet bruges til at vise annotationer, som vedrører hele dokumentet. Disse annotationer vises i forhold til deres position i dokumentet og flytter sig ikke, selvom brugeren blader i dokumentet.  Der er som regel en tilsvarende annotation i den lodrette lineal, når denne del af dokumentet er synlig.  

Den lodrette lineal nedenfor viser, at der er to opgaver i dokumentet og ét bogmærke. Da teksten med bogmærket er synlig, vises dens annotation også til venstre.

Lodret oversigtslineal i Java-editor

Brugeren kan navigere til annotationens placering i koden ved at klikke på selve annotationen.

De typer annotationer, som vises i oversigtslinealen, afgøres ved tilføjelse af annotationstyper til linealen. I følgende kodesekvens fra SourceViewerDecorationSupport tilføjes annotationstyper dynamisk til linealen. (Næste afsnit indeholder flere oplysninger om SourceViewerDecorationSupport.)

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();
} }

Oversigtslinealen leveres også med en IAnnotationAccess, som bruges til at stille oplysninger til rådighed om en bestemt annotation, f.eks. dens type og den måde, den skal vises på. TextEditor bruger en DefaultMarkerAnnotationAccess, som fortolker annotationer i henhold til deres markeringstyper og rådfører sig med brugerindstillingerne for at se, hvilke markeringstyper der skal vises i oversigtslinealen.

protected IAnnotationAccess createAnnotationAccess() {
	return new DefaultMarkerAnnotationAccess(fAnnotationPreferences);
}

Implementeringen af DefaultMarkerAnnotationAccess ogMarkerAnnotation indeholder flere oplysninger om præsentation af markeringer i oversigtslinealen.

Tekstannotationer

Foruden at vise annotationer i linealer kan en kildefremviser også vise annotationer som farvede 'squiggly'- markeringer i teksten.  

Squiggly-markering i Java-editor

Nu ser vi igen på oprettelsen af kildefremviseren i 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;
}

Klassen SourceViewerDecorationSupport håndterer mange af de dekorationer, som vises i en kildefremviser, f.eks. tekstannotationer, farvede margener, farvede markørlinjer og lignende. Den konfigureres med brugerindstillinger, så den kan reagere på dynamiske opdateringer af ændrede brugerindstillinger. De fleste editorer behøver ikke tage sig af detaljerne forbundet med maling af dekorationer. (Se SourceViewerDecorationSupport og de tilhørende klasser som f.eks.AnnotationPainter, hvis du absolut vil!). Det vigtigste er at vide, hvilke dekorationer der er til rådighed, så SourceViewer og den understøttendeSourceViewerDecorationSupport konfigureres rigtigt.

Konfigurér SourceViewerDecorationSupport

Lad os se på den konfiguration, som bruges af TextEditor til dekorationsunderstøttelse.

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());
}

Bemærk, at annotationsindstillingerne bruges til at definere annotationstyper for alle de annotationer, som vises i brugerindstillingerne. Det omfatter annotationer, som bidrages af en plugin, og er ikke begrænset til de annotationer, der leveres af arbejdsbænken. Hvis du ikke vil have vist alle de tilgængelige annotationer i editoren, skal du tilsidesætte denne metode og kun klargøre SourceViewerDecorationSupport med de typer, du vil have vist.