Программы просмотра исходного кода и аннотации

Редактор и связанная с ним программа просмотра текста играют основную роль в процессе реализации оформления документов и настройки необходимых вспомогательных классов. (Если вы не знакомы с понятием программы просмотра, обратитесь к разделу Программы просмотра).   

TextViewer выполняет все операции, связанные с низкоуровневой обработкой модели документа и ее разделов в сформатированный текст, выделенный разными цветами. Для редакторов стиля исходного кода предусмотрена программа просмотра SourceViewer. Программа просмотра исходного кода применяет такое понятие, как аннотации исходного кода. Аннотации отображаются на линейках, расположенных слева или справа от текста, либо в качестве цветных волнистых линий под текстом.

SourceViewer и связанные вспомогательные классы применяются на всех уровнях иерархии AbstractTextEditor. Определение этой программы просмотра и других классов, поддерживающих представление аннотаций, входит в состав пакета org.eclipse.jface.text.source.

Аннотации и линейки

Свойства аннотаций, также как и разделов, в большой степени зависят от типа редактируемого документа. Интерфейс IAnnotationModel применяется для хранения и обработки аннотаций. Кроме того, он отслеживает изменения, вносимые в текст, для сохранения соответствия между текстом и аннотациям. Модели аннотаций зарегистрированы в расширении org.eclipse.core.filebuffers.annotationModelCreation. С помощью этой точки расширения модуль может зарегистрировать класс и создать модель аннотаций для конкретного расширения файлов. Пример редактора Java не применяет эту точку расширения, поскольку он наследует модель аннотаций, определенную платформой.

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

Предоставленная фабрика классов создает класс ResourceMarkerAnnotationModel для файлов любых типов. Этот класс отображает аннотации, представляющие маркер, связанный с ресурсом рабочей области. (Дополнительная информация о маркерах приведена в разделе Маркеры ресурсов). Он присваивает каждому маркеру изображение и описание, а также отслеживает изменения, вносимые в маркеры связанных ресурсов.

Рассмотрим модель аннотаций на примере линеек и аннотаций текстового редактора платформы. Параметры отображения различных аннотаций на линейках можно настроить с помощью окна диалога Общие > Редакторы > Текстовый редактор > Аннотации.

Вертикальная линейка

Вертикальная линейка, расположенная слева от области редактирования, применяется текстовыми редакторами платформы для отображения диапазонов текста, а также аннотаций, связанных с отдельными строками текста.

Вертикальная линейка

Описание этих аннотаций входит в состав модели ResourceMarkerAnnotationModel. Эта модель загружается в класс SourceViewer в процессе инициализации программы просмотра исходного кода редактором. Следующий фрагмент исходного кода класса AbstractTextEditor связывает документ и модель аннотаций с программой просмотра.

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

Для правильного представления документа и аннотаций на вертикальной линейке, расположенной слева, достаточно указать для программы просмотра исходного кода соответствующий документ и модель аннотаций. Модель связывается с линейкой после загрузки документа. Следующий фрагмент исходного кода позволяет загрузить документ в программу просмотра исходного кода. Для более наглядного описания здесь приведен упрощенный вариант исходного кода SourceViewer:

public void setDocument(IDocument document, IAnnotationModel annotationModel) {
	...
	// создание визуальной модели аннотаций на основе предоставленного исходного кода
	// и сохранение полученной модели в fVisualAnnotationModel
	...
	if (fVerticalRuler != null)
		fVerticalRuler.setModel(fVisualAnnotationModel);

Таким образом линейка связывается с соответствующей моделью аннотаций.   

Рассмотрим саму линейку. Она создается текстовым редактором и затем связывается с соответствующей программой просмотра. Поскольку пример редактора Java не задает дополнительных свойств линеек, то наследуется линейка из класса TextEditor.

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

Текстовый редактор применяет линейку CompositeRuler, для которой не предусмотрено отдельное визуальное оформление. Она состоит из списка элементов оформления, отображающих столбцы линейки (IVerticalRulerColumn). В этом примере столбец линейки, содержащий аннотации (AnnotationRulerColumn) добавляется по умолчанию, а столбец с номером строки - в соответствии с параметрами, указанными пользователем. Столбец линейки аннотаций отвечает за отображение изображений аннотаций в нужных расположениях.

Обратите внимание, что помимо классов, применяемых для отображения линейки, для получения свойств линейки редактору достаточно наследовать только классы среды. JavaDocumentProvider наследует соответствующую модель аннотаций маркеров из FileDocumentProvider. JavaTextEditor наследует оформление линейки из TextEditor.

Линейка обзора

Линейка обзора расположена в правой части области редактирования и применяется для отображения аннотаций, связанных с документом в целом. Такие аннотации отображаются относительно их положения в документе и не перемещаются при прокрутке документа. Однако соответствующая аннотация отображается на вертикальной линейке, когда в редакторе показан связанный фрагмент документа.   

Вертикальная линейка, показанная на следующем рисунке, описывает две задачи и закладку, входящие в состав документа. Поскольку текст, с которым связана закладка, отображается в области редактирования, слева показана соответствующая аннотация.

Вертикальная линейка обзора в редакторе Java

Щелкнув на аннотации, можно перейти к связанному с ней фрагменту исходного кода.

Типы аннотаций, отображаемых на линейке обзора, определяются путем добавления типов аннотаций в линейку. В следующем фрагменте исходного кода класса SourceViewerDecorationSupport типы аннотаций динамически добавляются в линейку. (Дополнительная информация о классе 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();
} }

Кроме того, в состав линейки обзора входит интерфейс IAnnotationAccess, позволяющий получить сведения о конкретной аннотации. Например, тип аннотации и способ отображения. Редактор TextEditor применяет класс DefaultMarkerAnnotationAccess, обрабатывающий аннотации в соответствии со связанными типами маркеров. Список типов маркеров, доступных для отображения на линейке, задается пользовательскими параметрами.

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

За дополнительной информацией о представлении маркеров на линейке обзора обратитесь к реализации DefaultMarkerAnnotationAccess и MarkerAnnotation.

Текстовые аннотации

Кроме аннотаций, отображаемых на линейках, программа просмотра исходного кода поддерживает аннотации в виде цветных волнистых линий в тексте.   

Волнистая линия в редакторе Java

Вернемся к процессу создания программы просмотра исходного кода в 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;
}

Класс SourceViewerDecorationSupport описывает различные элементы оформления программы просмотра исходного кода. Например, текстовые аннотации, поля и строки курсора, выделенные цветом, и т.д.Он настраивается в соответствии с пользовательскими параметрами и поддерживает их динамическое изменение. В большинстве случаев элементы оформления окрашиваются независимо от редакторов (см. описание SourceViewerDecorationSupport и связанных классов AnnotationPainter). Обратите внимание, что для правильной настройки SourceViewer и SourceViewerDecorationSupport необходимо точно знать доступные элементы оформления.

Настройка SourceViewerDecorationSupport

Рассмотрим конфигурацию, применяемую редактором TextEditor для поддержки элементов оформления.

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

Обратите внимание, что параметры аннотаций задают типы всех аннотаций, доступных в пользовательских параметрах. В том числе аннотаций, предоставленных модулем, но не ограничиваясь аннотациями рабочей среды. Если в редакторе требуется показывать не все доступные типы аннотаций, переопределите этот метод и укажите в SourceViewerDecorationSupport только необходимые типы.