编辑器通常具有相应的内容描绘器,它提供编辑器内容的结构化视图,并帮助用户浏览编辑器的内容。
为此,工作台提供了标准的大纲视图。工作台用户使用窗口 > 显示视图菜单来控制此视图何时可视。
由于一般 TextEditor 不知道关于它的文本的结构的任何信息,因此,它不能为所需的大纲视图提供行为。因此,下面显示的缺省大纲视图不会执行操作。
文本框架中的编辑器可以为大纲视图提供它们自己的内容描绘器页面。编辑器的描绘器是在工作台请求类型为 IContentOutlinePage 的适配器时指定的。
public Object getAdapter(Class required) { if (IContentOutlinePage.class.equals(required)) { if (fOutlinePage == null) { fOutlinePage= new JavaContentOutlinePage(getDocumentProvider(), this); if (getEditorInput() != null) fOutlinePage.setInput(getEditorInput()); } return fOutlinePage; } return super.getAdapter(required); }
内容描绘器页面必须实现 IContentOutlinePage。此接口组合了通知选择更改侦听器(ISelectionProvider)的功能与在视图中(IPage)中作为页面的行为。内容描绘器通常是使用 JFace 查看器来实现的。内容描绘器的缺省实现(ContentOutlinePage)使用 JFace 树形查看器来显示大纲的分层表示法。此表示法适合许多结构化描绘器,包括 JavaContentOutlinePage。
让我们看一下页面的实现。如果大纲页面是由编辑器在上面代码片段中创建的,则它的输入元素被设置为编辑器的输入元素。通常,可以直接将此输入传送到大纲页面的查看器中,正如下面所做的那样。
public void createControl(Composite parent) { super.createControl(parent); TreeViewer viewer= getTreeViewer(); viewer.setContentProvider(new ContentProvider()); viewer.setLabelProvider(new LabelProvider()); viewer.addSelectionChangedListener(this); if (fInput != null) viewer.setInput(fInput); }
树形查看器的创建是从 ContentOutlinePage 中继承的。使用标准的内容和标号提供程序。每当设置(或者更改)了编辑器输入时,JavaContentOutlinePage 就会获得编辑器输入的文档并分析文本。
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { ... if (newInput != null) { IDocument document= fDocumentProvider.getDocument(newInput); if (document != null) { document.addPositionCategory(SEGMENTS); document.addPositionUpdater(fPositionUpdater); parse(document); } } }
文本被分析为文档中的许多范围(称为段)。这些段按名称显示在大纲视图中。
当更改选择时,就会检索所选择的段。其偏移量用来设置编辑器中的突出显示范围。
public void selectionChanged(SelectionChangedEvent event) { super.selectionChanged(event); ISelection selection= event.getSelection(); if (selection.isEmpty()) fTextEditor.resetHighlightRange(); else { Segment segment= (Segment) ((IStructuredSelection) selection).getFirstElement(); int start= segment.position.getOffset(); int length= segment.position.getLength(); try { fTextEditor.setHighlightRange(start, length, true); } catch (IllegalArgumentException x) { fTextEditor.resetHighlightRange(); } } }