优秀设计师网站,服务器和网站空间,微商货源类网站源码,威海专业做网站设计的公司【打开editor的接口讨论】 先来看一下workbench吧#xff0c;workbench从静态划分应该大致如下#xff1a; 从结构图我们大致就可以猜测出来#xff0c;workbench page作为一个IWorkbenchPart#xff08;无论是eidtor part还是view part#… 【打开editor的接口讨论】 先来看一下workbench吧workbench从静态划分应该大致如下 从结构图我们大致就可以猜测出来workbench page作为一个IWorkbenchPart无论是eidtor part还是view part的容器肯定会接受workbench page的管理。看了一下IWorkbenchPage接口定义中确实提供给了如下打开编辑器的操作 【IWokbenchPage提供的接口】 1 public interface IWorkbenchPage extends IPartService, ISelectionService,ICompatibleWorkbenchPage { 2 3 public IEditorPart openEdito(IEditorInput input, String editorId)throws PartInitException; 4 5 public IEditorPart openEdito(IEditorInput input, String editorId, boolean activate) throws PartInitException; 6 7 public IEditorPart openEditor(final IEditorInput input, final String editorId, final boolean activate, final int matchFlags)throws PartInitException; 8 }那到这边可能很多人已经知道了怎么调用这些接口了PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(...)说明PlatformUI可以看作是整个eclipse ui框架的门面类当然最核心的作用就是让用户获取到workbench。Eclipse中存在的其他一些门面类如ResourcesPlugin、Platform、JavaCore、JavaUI等我们再仔细看一下IWorkbenchPage对应的实现类org.eclipse.ui.internal.WorkbenchPage中的以上接口的实现代码真正在管理Editor的是一个叫做EditorManager的东东同理view part对应的管理器角色类是叫做ViewFactory的东东。
这里的EditorManager和View Factory是workbench实现中非常精华的部分看一下里面的实现就会很大程度上理解workbench所谓懒加载、懒初始化是如何实现的了如何实现part 复用的...等等
。 上图就用来说明workbench是如何来管理各种part的其中descriptor角色的核心作用是延迟加载扩展延迟加载用户通过editors或者views提供的扩展reference角色的核心作用是用来延迟初时化具体的part例如避免过早的创建对应的control等等。再说下去有点偏离主题了这部分以后有时间再写【IDE工具类提供的接口】 上面IWorkbenchPage提供接口都需要用户准备两样东西一是创建IEditorInput实例二是指定editor id。有些用户可能不想干这两件事情所以在工具类org.eclipse.ui.ide.IDE中提供了其他的接口1 public static IEditorPart openEditor(IWorkbenchPage page, IFile input) throws PartInitException { } 2 3 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, boolean activate) throws PartInitException { } 4 5 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, boolean activate, boolean determineContentType) { } 6 7 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId) throws PartInitException { } 8 9 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId, boolean activate) throws PartInitException { } 10 11 上面5个接口操作中 对于上面的三个操作Eclipse会自动为你准备IEditorInput实例并动态绑定合适的编辑器类型。对于下面的两个操作Eclipse会为你自动准备IEditorInput实例但是需要用户自己指定editor id。接下来我们看两个问题一是如何创建IEditorInput实例的而是如何动态计算对应的editor id的。【有关FileEditorInput】在IDE工具类中提供的5个接受IFile对象的openEditor接口中在对应的实现中都是默认构造了一个FileEditorInputorg.eclipse.ui.part.FileEditorInput实例这个实例也是org.eclipse.ui.IFileEditorInput接口的默认实现类注意Eclipse中很多地方都使用这种Interface/Default Impl的方式Interface会暴露Default Impl则根据情况选择是否暴露一般是如果Interface希望用户来扩展继承则会暴露对应的Default Impl如果Interface不希望用户来扩展继承例如IResource系列接口则一般会将Default Impl丢如对应的internal包中。我们看一下org.eclipse.ui.part.FileEditorInput中是如何实现IEditorInput.exists()接口的1 public class FileEditorInput implements IFileEditorInput,IPathEditorInput,IPersistableElement { 2 private IFile file; 3 4 public boolean exists() { 5 return file.exists(); 6 } 7 }我们看到内部的实现是持有了IFile句柄如果IFile代表的资源没有存在于工作区之内那么就会返回false。疑问如果我们打开工作区外部的文件呢显然FileEditorInput并不合适稍后看...【动态计算editor id】下面我们再来看一下IDE类是如何计算所谓的默认eidtor id的。追踪实现我们看到了IDE.getDefaultEditor1 public static IEditorDescriptor getDefaultEditor(IFile file, boolean determineContentType) { 2 // Try file specific editor. 3 IEditorRegistry editorReg PlatformUI.getWorkbench() 4 .getEditorRegistry(); 5 try { 6 String editorID file.getPersistentProperty(EDITOR_KEY); 7 if (editorID ! null) { 8 IEditorDescriptor desc editorReg.findEditor(editorID); 9 if (desc ! null) { 10 return desc; 11 } 12 } 13 } catch (CoreException e) { 14 // do nothing 15 } 16 17 IContentType contentType null; 18 if (determineContentType) { 19 contentType getContentType(file); 20 } 21 // Try lookup with filename 22 return editorReg.getDefaultEditor(file.getName(), contentType); 23 }上面的代码大致赶了如下两件事情1、如果对应的资源设定了一个特定的持久化属性EDITOR_KEY则会使用EDITOR_KEY属性值所代表的编辑器说明有关Eclipse资源的属性支持请参阅其他文档。那如果一个资源不在工作区之内又如何设定EDITOR_KEY属性呢 _确实没法设定2、查找对应的content type用户通过org.eclipse.core.runtime.contentTypes扩展点来注册自定义的内容类型在内容类型中会指定对应的文件扩展名和默认编码例如JDT中注册了如下内容类型摘自org.eclipse.jdt.core/plugin.xml!-- -- !-- Extension: Java Content Types -- !-- -- extension pointorg.eclipse.core.runtime.contentTypes !-- declares a content type for Java Properties files -- content-type idjavaProperties name%javaPropertiesName base-typeorg.eclipse.core.runtime.text priorityhigh file-extensionsproperties default-charsetISO-8859-1/ !-- Associates .classpath to the XML content type -- file-association content-typeorg.eclipse.core.runtime.xml file-names.classpath/ !-- declares a content type for Java Source files -- content-type idjavaSource name%javaSourceName base-typeorg.eclipse.core.runtime.text priorityhigh file-extensionsjava/ !-- declares a content type for Java class files -- content-type idjavaClass name%javaClassName priorityhigh file-extensionsclass describer classorg.eclipse.core.runtime.content.BinarySignatureDescriber parameter namesignature valueCA, FE, BA, BE/ /describer /content-type !-- declares a content type for JAR manifest files -- content-type idJARManifest name%jarManifestName base-typeorg.eclipse.core.runtime.text priorityhigh file-namesMANIFEST.MF default-charsetUTF-8/ /extension那如果我们在注册编辑器的时候和对应的content type绑定这不就联系起来了吗_。那我们看一下java源码编辑器扩展描述摘自org.eclipse.jdt.ui/plugin.xmleditor name%JavaEditor.label defaulttrue icon$nl$/icons/full/obj16/jcu_obj.gif contributorClassorg.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditorActionContributor classorg.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor symbolicFontNameorg.eclipse.jdt.ui.editors.textfont idorg.eclipse.jdt.ui.CompilationUnitEditor contentTypeBinding contentTypeIdorg.eclipse.jdt.core.javaSource / /editor我们看到上面的xml中有contentTypeBinding元素里面指定了绑定java源码content type。 那如果我们在注册编辑器的时候没有绑定对应的content type呢Eclipse允许你配置往下看 我想看到这边对eclipse如何动态计算一个文件对应的editor应该是明白了吧再回顾一下吧1、查看资源本身是否有EIDTOR_ID持久属性注意一、只有工作区中存在的资源才允许设置持久属性二、资源属性知识针对特定资源不会影响同类型资源即你对工作区中特定的.java文件设定了EIDTOR_ID持久属性并不会影响工作区中其他.java文件资源的编辑器绑定操作2、查找对应的content type然后查找对应的editor扩展或者查找Eclipse中的Content Types和File Associations配置3、如果都找不到则直接给一个默认的编辑器。例如我们经常碰到是org.eclipse.ui.DefaultTextEditor【IDE工具类提供的接口 VS IWorkbenchPage提供的接口】 看一下以上提到的各个角色之间的调用关系图吧 【使用Eclipse提供的打开editor的接口】 还是那句话需求决定一切。我们看一下打开编辑器的需求 1、打开工作区中工程内的文件资源 2、打开工作区.metadata目录中的文件资源 3、打开工作区外部的文件资源 【说明】Eclipse工作区实际上是有数据区和元数据区两个区域组成的示意如下 对于Eclipse来说.metadata目录下存放的是插件运行时的关键状态数据不建议用户再工作区实例运行期间做相应修改为此eclipse干了两件事情1、运行期间会自动在.metadata目录下产生一个进程锁定的.lock文件2、Eclipse不允许用户通过IResource系列接口直接访问或修改.meatadata目录下的资源 【打开工作区工程内的资源】 假设工作区中有测试工程TestProject工程下有文本文件java_file.txt。对应创建代码如下1 try { 2 //创建工程 3 IProject project ResourcesPlugin.getWorkspace().getRoot().getProject(TestProject); 4 if (!project.exists()) 5 project.create(null); 6 if (!project.isOpen()) 7 project.open(null); 8 9 //创建文件 10 IFile java_file project.getFile(new Path(/java_file.txt)); 11 InputStream inputStreamJava new ByteArrayInputStream(class MyType{}.getBytes()); 12 if (!java_file.exists()) 13 java_file.create(inputStreamJava, false, null); 14 } catch (CoreException e) { 15 IStatus status new Status(IStatus.ERROR, myplugin, 101, 创建资源失败, e); 16 Activator.getDefault().getLog().log(status); 17 }打开方式一Eclipse默认计算对应的editor id会用default text editor打开 1 try { 2 IWorkbenchPage page PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 3 IProject project ResourcesPlugin.getWorkspace().getRoot().getProject(TestProject); 4 5 IFile java_file project.getFile(new Path(/java_file.txt)); 6 IDE.openEditor(page, java_file); 7 } catch (CoreException e) { 8 IStatus status new Status(IStatus.ERROR, myplugin, 102, 打开工作区内文件出错, e); 9 Activator.getDefault().getLog().log(status); 10 }打开方式二指定java源码编辑器打开会用java源码编辑器打开1 try { 2 IWorkbenchPage page PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 3 IProject project ResourcesPlugin.getWorkspace().getRoot().getProject(TestProject); 4 5 IFile java_file project.getFile(new Path(/java_file.txt)); 6 IDE.openEditor(page, java_file, org.eclipse.jdt.ui.CompilationUnitEditor); 7 } catch (CoreException e) { 8 IStatus status new Status(IStatus.ERROR, myplugin, 102, 打开工作区内文件出错, e); 9 Activator.getDefault().getLog().log(status); 10 }打开方式三设定editor id属性该文件以后默认都用此editor id打开1 try { 2 IWorkbenchPage page PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 3 IProject project ResourcesPlugin.getWorkspace().getRoot().getProject(TestProject); 4 5 IFile java_file project.getFile(new Path(/java_file.txt)); 6 java_file.setPersistentProperty(IDE.EDITOR_KEY, org.eclipse.jdt.ui.CompilationUnitEditor); 7 IDE.openEditor(page, java_file); 8 } catch (CoreException e) { 9 IStatus status new Status(IStatus.ERROR, myplugin, 102, 打开工作区内文件出错, e); 10 Activator.getDefault().getLog().log(status); 11 }说明对于工作区工程内的资源可以有两种方式一是local的那就是物理存在与工程之内二是link进入的。打开编辑器的时候不需要做区分。【打开工作区外部的资源】说明既存在于工作区外部同时又没有被link进工程。在Eclipse中有个功能就是File-Open File可以打开一个外部文件。那我们看一下它是怎么实现的。我们只需要打开对应的对话框然后挂起主线程就可以找到对应的action了挂起线程可以帮我们很方便的调试很多类型的问题以后细说~_~分析一下OpenExternalFileAction的实现我们发现它自己构建了一个editor input