Eclipse插件打开编辑器
今天终于可以闲一天,想来想去就乱写点东西吧,说不定对有些新人有点帮助呢~_~
用Eclipse API的方式来打开编辑器,可能对任何一个插件开发者都不是很陌生的操作了。但是,还是建议你忍着看一下,全当是复习吧~_~。
【打开editor的接口讨论】
先来看一下workbench吧,workbench从静态划分应该大致如下:
从结构图我们大致就可以猜测出来,workbench page作为一个IWorkbenchPart(无论是eidtor part还是view part)的容器,肯定会接受workbench page的管理。看了一下,IWorkbenchPage接口定义中确实提供给了如下打开编辑器的操作:
【IWokbenchPage提供的接口】
public interface IWorkbenchPage extends IPartService, ISelectionService,ICompatibleWorkbenchPage { public IEditorPart openEdito(IEditorInput input, String editorId)throws PartInitException; public IEditorPart openEdito(IEditorInput input, String editorId, boolean activate) throws PartInitException; public IEditorPart openEditor(final IEditorInput input, final String editorId, final boolean activate, final int matchFlags)throws PartInitException; }
那到这边,可能很多人已经知道了怎么调用这些接口了:
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中提供了其他的接口:
public static IEditorPart openEditor(IWorkbenchPage page, IFile input) throws PartInitException { } public static IEditorPart openEditor(IWorkbenchPage page, IFile input, boolean activate) throws PartInitException { } public static IEditorPart openEditor(IWorkbenchPage page, IFile input, boolean activate, boolean determineContentType) { } public static IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId) throws PartInitException { } public static IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId, boolean activate) throws PartInitException { }
上面5个接口操作中, 对于上面的三个操作,Eclipse会自动为你准备IEditorInput实例,并动态绑定合适的编辑器类型。对于下面的两个操作,Eclipse会为你自动准备IEditorInput实例,但是需要用户自己指定editor id。
接下来我们看两个问题,一是如何创建IEditorInput实例的;而是如何动态计算对应的editor id的。
【有关FileEditorInput】
在IDE工具类中提供的5个接受IFile对象的openEditor接口中,在对应的实现中都是默认构造了一个FileEditorInput(org.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()接口的:
public class FileEditorInput implements IFileEditorInput,IPathEditorInput,IPersistableElement { private IFile file; public boolean exists() { return file.exists(); } }
我们看到内部的实现是持有了IFile句柄,如果IFile代表的资源没有存在于工作区之内,那么就会返回false。(疑问:如果我们打开工作区外部的文件呢???显然,FileEditorInput并不合适,稍后看...)
【动态计算editor id】
下面,我们再来看一下IDE类是如何计算所谓的默认eidtor id的。追踪实现,我们看到了IDE.getDefaultEditor
public static IEditorDescriptor getDefaultEditor(IFile file, boolean determineContentType) { // Try file specific editor.IEditorRegistry editorReg = PlatformUI.getWorkbench() .getEditorRegistry(); try { String editorID = file.getPersistentProperty(EDITOR_KEY); if (editorID != null) { IEditorDescriptor desc = editorReg.findEditor(editorID); if (desc != null) { return desc; } } } catch (CoreException e) { // do nothing } IContentType contentType = null; if (determineContentType) { contentType = getContentType(file); } // Try lookup with filenamereturn editorReg.getDefaultEditor(file.getName(), contentType); }
上面的代码大致赶了如下两件事情:
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 point="org.eclipse.core.runtime.contentTypes"><!-- declares a content type for Java Properties files --><content-type id="javaProperties" name="%javaPropertiesName" base-type="org.eclipse.core.runtime.text"priority="high" file-extensions="properties"default-charset="ISO-8859-1"/><!-- Associates .classpath to the XML content type --><file-association content-type="org.eclipse.core.runtime.xml" file-names=".classpath"/> <!-- declares a content type for Java Source files --><content-type id="javaSource" name="%javaSourceName" base-type="org.eclipse.core.runtime.text"priority="high" file-extensions="java"/><!-- declares a content type for Java class files --><content-type id="javaClass" name="%javaClassName" priority="high" file-extensions="class"> <describerclass="org.eclipse.core.runtime.content.BinarySignatureDescriber"><parameter name="signature" value="CA, FE, BA, BE"/></describer></content-type> <!-- declares a content type for JAR manifest files --><content-type id="JARManifest" name="%jarManifestName" base-type="org.eclipse.core.runtime.text"priority="high" file-names="MANIFEST.MF"default-charset="UTF-8"/> </extension>
那如果我们在注册编辑器的时候和对应的content type绑定,这不就联系起来了吗~_~。那我们看一下java源码编辑器扩展描述(摘自org.eclipse.jdt.ui/plugin.xml):
<editorname="%JavaEditor.label"default="true"icon="$nl$/icons/full/obj16/jcu_obj.gif"contributorClass="org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditorActionContributor"class="org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor"symbolicFontName="org.eclipse.jdt.ui.editors.textfont"id="org.eclipse.jdt.ui.CompilationUnitEditor"><contentTypeBindingcontentTypeId="org.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。对应创建代码如下:
try { //创建工程IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); if (!project.exists()) project.create(null); if (!project.isOpen()) project.open(null); //创建文件IFile java_file = project.getFile(new Path("/java_file.txt")); InputStream inputStreamJava = new ByteArrayInputStream("class MyType{}".getBytes()); if (!java_file.exists()) java_file.create(inputStreamJava, false, null); } catch (CoreException e) { IStatus status = new Status(IStatus.ERROR, "myplugin", 101, "创建资源失败", e); Activator.getDefault().getLog().log(status); }
打开方式一:Eclipse默认计算对应的editor id,会用default text editor打开
try { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); IFile java_file = project.getFile(new Path("/java_file.txt")); IDE.openEditor(page, java_file); } catch (CoreException e) { IStatus status = new Status(IStatus.ERROR, "myplugin", 102, "打开工作区内文件出错", e); Activator.getDefault().getLog().log(status); }
打开方式二:指定java源码编辑器打开,会用java源码编辑器打开
try { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); IFile java_file = project.getFile(new Path("/java_file.txt")); IDE.openEditor(page, java_file, "org.eclipse.jdt.ui.CompilationUnitEditor"); } catch (CoreException e) { IStatus status = new Status(IStatus.ERROR, "myplugin", 102, "打开工作区内文件出错", e); Activator.getDefault().getLog().log(status); }
打开方式三:设定editor id属性,该文件以后默认都用此editor id打开
try {IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject");IFile java_file = project.getFile(new Path("/java_file.txt"));java_file.setPersistentProperty(IDE.EDITOR_KEY, "org.eclipse.jdt.ui.CompilationUnitEditor");IDE.openEditor(page, java_file);} catch (CoreException e) {IStatus status = new Status(IStatus.ERROR, "myplugin", 102, "打开工作区内文件出错", e);Activator.getDefault().getLog().log(status);}
说明:对于工作区工程内的资源,可以有两种方式:一是local的,那就是物理存在与工程之内;二是link进入的。打开编辑器的时候,不需要做区分。
【打开工作区外部的资源】
说明:既存在于工作区外部,同时又没有被link进工程。
在Eclipse中有个功能,就是File->Open File,可以打开一个外部文件。那我们看一下它是怎么实现的。我们只需要打开对应的对话框,然后挂起主线程,就可以找到对应的action了(挂起线程可以帮我们很方便的调试很多类型的问题,以后细说~_~):
分析一下OpenExternalFileAction的实现,我们发现它自己构建了一个editor input
转载于:https://www.cnblogs.com/Soy-technology/p/11383174.html
Eclipse插件打开编辑器相关推荐
- 转:Eclipse中打开文件所在文件夹的插件及设置
如果你经常需要在Eclipse里打开相关资源文件所在的文件夹,比较麻烦,要右键,属性,在Location一栏中把所在的文件夹拷贝一下,然后再去资源管理器里输入这个路径,回车,打开它. 解决方法: 用E ...
- 我常用的Eclipse插件
2019独角兽企业重金招聘Python工程师标准>>> <p>以下的插件都可以使用Eclipse Marketplace进行查找,安装.</p> <p& ...
- 开发 Eclipse 插件
如何创建.调试和安装插件 在本文中,David Gallardo 向您展示了如何使用 Plug-in Development Environment 的代码生成向导来创建 Eclipse 插件.您将学 ...
- 编写Eclipse插件教程–第1部分
Eclipse是三个最受欢迎的Java开发IDE之一. 其成功的原因之一是其可扩展性. 对于任何知道该怎么做并且已经做到的人来说,编写eclipse插件都可以非常轻松快捷. 不幸的是,第一次在Ecli ...
- eclipse插件大全整理学习
Eclipse Web Tools Platform(WTP) 地址:http://download.eclipse.org/webtools/ WTP十分强大,支持HTML, JavaScript, ...
- Gradle Eclipse插件教程
Today we will look into Gradle Eclipse plugin. In my previous post, we have discussed about Gradle B ...
- eclipse插件说明
Properties Editor Properties Editor 编辑java的属性文件,并可以自动存盘为Unicode格式 更多Properties Editor 信息 Colorer T ...
- Eclipse插件大全 (下)
Quigen Quigen这个插件利用Velocity模板引擎来快速生成任何类型的文本内容.它不需要进行配置,所要做的只是利用它自带Velocity编辑器编写一个velocity 模板文件. 更多Q ...
- Eclipse插件集合
Rails框架软件:eXPlain是一款基于Rails框架开发的项目管理工具.它的安装说明请看这里,软件下载请点击这里,软件说明请点击这里.还有类似的Rails框架软件rPlan. YA系列软件:YA ...
最新文章
- java-在应用中获取spring定义的bean
- 挑战者联盟!谁会成为最赚钱的人工智能公司
- 韩春雨,时隔六年再发高分论文
- Facebook Messenger要点燃聊天机器人革命,据说四月就发布!
- P1975-[国家集训队]排队【树状数组套线段树】
- ironpython3桌面开发_IronPython项目有了新负责人
- 云服务器的主机名是否可以修改??
- 微软Silverlight 5开发书籍汇总
- matlab绘制正弦波频谱图,matlab对正弦信号作FFT得到频谱图
- 怎么登录163邮箱?TOMvip邮箱登录详情介绍
- python复制文件夹shutil.copytree
- vue打包中background-image图片路径问题
- java界面小程序-模拟算卦六爻
- 饿了么(elementUI)组件库如何在vue项目中使用?
- 解决无法直接打开EXCEL文件的问题
- AD域更新计算机配置组策略无效的解决,Window server 2012 R2 AD域的组策略设置
- 【Leetcode】1430. Check If a String Is a Valid Sequence from Root to Leaves Path in a Binary Tree
- 程序员表白专用: 5 种实用表白方法!帮你快速攻陷心仪女生
- 在硅胶产品表面处理中,丝印、移印与镭雕的区别
- 再从淘宝数据结构来看电子商务中商品属性设计
热门文章
- 解决“cannot open git-receive-pack”错误
- jQuery 设置select默认选中问题
- linux查看CPU信息
- 《Cracking the Coding Interview》——第18章:难题——题目11
- CSU 1328: 近似回文词
- 【Vue】组件复用导致的路由切换时页面不刷新问题
- Python导入sciry包出错
- python是一门面向什么的语言用词语填空_使用pygame写一个古诗词填空通关游戏
- linux ssh 脚本 密码,ssh自动登录的4种实现方法
- VS创建props属性表并在新项目中导入props属性表