zoukankan      html  css  js  c++  java
  • eclipse文件编辑器相关概念

    编辑器 首先必须实现 IEditorPart 接口 必须要实现他的 createPartControl 方法 这个方法可以使用swt或者jface创建界面来显示文件的内容 

    swt不依赖于开发工具  jface是对swt的封装 依赖开发工具


    编辑器因为有文件的输入 类IEditorInput定义了文件输入的协议,包含定义文件的名字 以及显示在编辑器上的label的图标

    Editor input label


    平台一般提供了以下几种实现

    IFileEditorInput  对文件系统文件的输入

     IURIEditorInput 是基于uri的

     IStorageEditorInput 基于字节的


    如果希望编辑器 能够重复多次使用 可以打开多个文件一起出现 必须实现 IReusableEditor 接口

    如果希望编辑器 被记录到导航历史记录中(关闭eclipse后 回到最后次打开的界面 这就是导航历史记录) 必须实现 INavigationLocationProvider.接口

     ITextEditor 继承IEditorPart 拓展了代码的层次结构

    AbstractTextEditor 实现了支持源代码样式



    当用户打开一个文件时 此时就有了 IFileEditorInput.对象,同时创建一个 IDocument

     IDocument, 用来对文本进行控制,此时就必须要有为输入文件IFileEditorInput.对象 IDocument,关联的对象 这个就是 IDocumentProvider

    java编辑器默认使用  org.eclipse.ui.editors.TextFileDocumentProvider 关联


    定义 IDocumentProvider

     <extension
             point="org.eclipse.ui.editors.documentProviders">
          <provider
                class="org.eclipse.ui.editors.text.TextFileDocumentProvider"
                inputTypes="org.eclipse.ui.IStorageEditorInput"
                id="org.eclipse.ui.editors.text.StorageDocumentProvider">
          </provider>
       </extension>

    以上代码是注册document providers与文件后缀的关联 可以自己定义这个document providers

    inputTypes就是输入的文件对象 
    TextFileDocumentProvider会根据inputTypes生成对应的IDocument


    <extension
    	id="ExampleJavaDocumentSetupParticipant"
    	name="%documentSetupParticipantName"
    	point="org.eclipse.core.filebuffers.documentSetup">
    	<participant
    		extensions="jav"
    		class="org.eclipse.ui.examples.javaeditor.JavaDocumentSetupParticipant">
    	</participant>
    </extension>
    



    这个拓展用来映射 文件后缀和IDocumentSetupParticipant

    IDocumentSetupParticipant对象组装给document对象一些被提供的组件 比如分割器

    例如java版本的

     	public void setup(IDocument document) {
    		 
    		IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(                 ), JavaPartitionScanner.JAVA_PARTITION_TYPES);
    		partitioner.connect(document);
    		
    	}
    安装代码会创建一个分割对象

    IDocumentPartitioner 用于将文档分割长若干不重叠的区域

    表现为  ITypedRegion对象,他的好处在于可以提供比如 语法高亮和格式化等功能

    分区对象被提供在 org.eclipse.jface.text.rules 

    可以使用FastPartitioner 对象进行快去分区

    IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
    RuleBasedPartitionScanner是所有分区扫描对象的父类

    他的子类主要用于区分不同的项例如 分隔符,空格,表达式,单行,多行注释,

    例如

    JavaPartitionScanner

    public JavaPartitionScanner() {
    	super();
    	IToken javaDoc= new Token(JAVA_DOC);
    	IToken comment= new Token(JAVA_MULTILINE_COMMENT);
    
    	List rules= new ArrayList();
    	// Add rule for single line comments.
    	rules.add(new EndOfLineRule("//", Token.UNDEFINED)); 
    
    	// Add rule for strings and character constants.
    	rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); 
    	rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); 
    
    	// Add special case word rule.
    	rules.add(new WordPredicateRule(comment));
    
    	// Add rules for multi-line comments and javadoc.
    	rules.add(new MultiLineRule("/**", "*/", javaDoc, (char) 0, true)); 
    	rules.add(new MultiLineRule("/*", "*/", comment, (char) 0, true)); 
    
    	IPredicateRule[] result= new IPredicateRule[rules.size()];
    	rules.toArray(result);
    	setPredicateRules(result);
    }

     TextViewer对象提供了比较低级的代码着色和格式化

     SourceViewer 引进了两个概念

    Annotations Rule

    注解被展示在编辑器左边的位置 

    Vertical ruler

    Overview ruler

    被展示在编辑器右边的列或者在边框底部的一条有颜色的线

    Vertical overview ruler in Java Editor


    希望annotation展示在overview的位置 必须

    annotation的类型添加到overview中

     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 

    用于处理比较特别的annotation

     TextEditor使用DefaultMarkerAnnotationAccess获取 IAnnotationAccess 

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

    source viewer提供annotation 在文本上带有着色的标志 比如

    Squiggly mark in Java Editor

     source viewer在AbstractDecoratedTextEditor.创建着色annotation 例如

    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 用于控制在文本上的装饰显示

    比如文本annotation ,着色边缘,着色光标线,标记等

    如果想了解更多研究关于

     SourceViewerDecorationSupport 和相关的类 例如AnnotationPainter 

    AbstractDecoratedTextEditor 对装饰的支持 例如.

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



    如何配置source viewer


    当sourceviwer实例化时首先需要设置 SourceViewerConfiguration对象 主要是协助生成文档伸缩,代码重做,双击,文本悬浮和高亮等行为的帮助对象

    protected void initializeEditor() {
    	super.initializeEditor();
    	setSourceViewerConfiguration(new JavaSourceViewerConfiguration());
    	...
    普通的SourceViewerConfiguration 并不能满足对编辑器功能的需要 需要覆盖initializeEditor() 方法

    例如java的


    //创建文件悬浮的帮助对象
    public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
    	return new JavaAnnotationHover();
    }
    //创建自动伸展的帮助对象	
    public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer, String contentType) {
    	return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? new JavaAutoIndentStrategy() : new DefaultAutoIndentStrategy());
    }

    文本悬浮

    SourceViewerConfiguration 

    对象默认并未提供对文本悬浮的支持 因为并不知道文本究竟会显示什么东西

    并需在对象中定义悬浮对象

    public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
    	return new JavaTextHover();
    }
    public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
    	return new JavaAnnotationHover();
    }
    ITextHover接口用户处理悬浮的帮助类

    ITextHover 可供偏离度 计算当前代码的位置 

    public class JavaTextHover implements ITextHover {
    
    	...
    	
    	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
    		Point selection= textViewer.getSelectedRange();
    		if (selection.x <= offset && offset < selection.x + selection.y)
    			return new Region(selection.x, selection.y);
    		return new Region(offset, 0);
    	}
    }

     同时获取到某个区域的代码

    public class JavaTextHover implements ITextHover {
    
    	public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
    		if (hoverRegion != null) {
    			try {
    				if (hoverRegion.getLength() > -1)
    					return textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
    			} catch (BadLocationException x) {
    			}
    		}
    		return JavaEditorMessages.getString("JavaTextHover.emptySelection"); 
    	}
    	...
    }

    Hover information on selected region

    代码着色


    SourceViewerConfiguration 默认没有提供代码着色的支持

    需要定义代码着色的装饰器

    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
    
    	PresentationReconciler reconciler= new PresentationReconciler();
    	...
    	return reconciler;
    }

    损坏,修复,修改同步

    当初始代码构建后 颜色的结构确定了  当插入或者删除一个字符时就会导致文档的格式破坏 着色也应该相应的改变

    IPresentationDamager表示文档已经修改,已经破坏, 必须需要被重新构造着色,他必须返回损坏的区域,必须对repairer( IPresentationRepairer是有效的区域

    repairer必须从damager中提取足够的信息去修复文档

     reconciler (IPresentationReconciler)  主要是实时同步文档,能够发现文档发生改变 并通知damager 同时计算damager 调用repairer 进行修复

    org.eclipse.jface.text.reconciler 定义了 同步的类


    基于规则的同步类 定义在  org.eclipse.jface.text.rules包下


    演示如何使用PresentationReconciler 和 DefaultDamagerRepairer.

    在SourceViewerConfigation中实现

    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) 方法

    内容如下

    JavaColorProvider provider= JavaEditorEnvironment.getJavaColorProvider();
    	PresentationReconciler reconciler= new PresentationReconciler();
    		
    	DefaultDamagerRepairer dr= new DefaultDamagerRepairer(JavaEditorEnvironment.getJavaCodeScanner());
    	reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
    	reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
    
    	dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(JavaColorProvider.JAVADOC_DEFAULT))));
    	reconciler.setDamager(dr, JavaPartitionScanner.JAVA_DOC);
    	reconciler.setRepairer(dr, JavaPartitionScanner.JAVA_DOC);
    
    	dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(JavaColorProvider.MULTI_LINE_COMMENT))));
    	reconciler.setDamager(dr, JavaPartitionScanner.JAVA_MULTILINE_COMMENT);
    	reconciler.setRepairer(dr, JavaPartitionScanner.JAVA_MULTILINE_COMMENT);
    
    	return reconciler;



    代码辅助


    代码辅助的类主要被定义在org.eclipse.jface.text.contentassist.下

    SourceViewerConfigation实现一下方法可以实现代码辅助

    public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
    
    	ContentAssistant assistant= new ContentAssistant();
    	assistant.setContentAssistProcessor(new JavaCompletionProcessor(), IDocument.DEFAULT_CONTENT_TYPE);
    	assistant.setContentAssistProcessor(new JavaDocCompletionProcessor(), JavaPartitionScanner.JAVA_DOC);
    
    	...
    	return assistant;
    }

    代码辅助的类必须实现  IContentAssistant.接口

    不同的文档类型 使用不同的处理策略 策略类 需要实现 IContentAssistProcessor.接口

    JavaCompletionProcessor 例子

    public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
    	ICompletionProposal[] result= new ICompletionProposal[fgProposals.length];
    	for (int i= 0; i < fgProposals.length; i++) {
    		IContextInformation info= new ContextInformation(fgProposals[i], MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
    		result[i]= new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i]})); //$NON-NLS-1$
    	}
    	return result;
    }

    配置触发代码提示

    public char[] getCompletionProposalAutoActivationCharacters() {
    	return new char[] { '.', '(' };
    }
    编辑器中的内容中的对象提示 

    public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
    	IContextInformation[] result= new IContextInformation[5];
    	for (int i= 0; i < result.length; i++)
    		result[i]= new ContextInformation(
    			MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset) }),
    			MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)}));
    	return result;
    }
    出发代码提示:

    public char[] getContextInformationAutoActivationCharacters() {
    	return new char[] { '#' };
    }

  • 相关阅读:
    盾机
    隐藏服务器真实IP的方法来防止DDOS攻击
    EJS 是什么 ,怎么用,以及优点
    Centos7 / RHEL 7 双网卡绑定
    linux下配置双网卡及RAC规划——1
    Why React Is Favored by Front-End Specialists
    React Virtual DOM Explained in Simple English
    React Core Features
    Virtual DOM--react
    redux是全局状态(数据)的管理机制,局部数据没有意义
  • 原文地址:https://www.cnblogs.com/liaomin416100569/p/9331433.html
Copyright © 2011-2022 走看看