借用Eclipse 实现文本内容对比功能.docx
《借用Eclipse 实现文本内容对比功能.docx》由会员分享,可在线阅读,更多相关《借用Eclipse 实现文本内容对比功能.docx(71页珍藏版)》请在冰豆网上搜索。
借用Eclipse实现文本内容对比功能
借用Eclipse实现文本内容对比功能
关键字:
eclipsecompareui
一相关知识
pare插件项目,用于进行文本、源码比对的一个插件,提供了一个Editor或Dialog可方便调用。
pare.CompareEditorInput.CompareEditorInput是用于给CompareEditor的EditorInput,需要自己实现。
pare.CompareConfiguration对CompareEditor的配置。
是否允许左边内容被修改,或是否允许右边内容被修改;左右两边的label,image等。
pare.ITypedElement接口,本意为指代有图片、名称、类型的元素。
而在Compare中,为一个基本的对比单元。
pare.IEditableContent接口,是否可编辑的元素
pare.IModificationDate接口,修改时间
pare.IStreamContentAccessor获得内容的接口,内容是以InputStream流的方式获得。
pare.IContentChangeNotifier内容变化的通知接口
pare.BufferedContent抽象类,实现了pare.IStreamContentAccessor和pare.IContentChangeNotifier2个接口
在BufferedContent中持有了一个byte[],表示缓存有界面上修改的内容,当然,最后需要你在CompareEditorInupt中将修改后的byte[]内容保存(比如保存至文件等)
二代码
(1)解决项目依赖
添加对pare的依赖
(2)定义一个表示比对的元素
可继承与BufferedContent,并实现ITypeElement等接口。
主要代码如下:
classCompareItemextendsBufferedContentimplementsITypedElement,IModificationDate,IEditableContent{
privateStringfileName;
privatelongtime;
CompareItem(StringfileName){
this.fileName=fileName;
this.time=System.currentTimeMillis();
}
/**
*@seepare.BufferedContent#createStream()
*/
protectedInputStreamcreateStream()throwsCoreException{
try{
returnnewFileInputStream(newFile(fileName));
}catch(FileNotFoundExceptione){
e.printStackTrace();
}
returnnewByteArrayInputStream(newbyte[0]);
}
/**
*@seepare.IModificationDate#getModificationDate()
*/
publiclonggetModificationDate(){
returntime;
}
/**
*@seepare.ITypedElement#getImage()
*/
publicImagegetImage(){
returnCompareUI.DESC_CTOOL_NEXT.createImage();
}
/**
*@seepare.ITypedElement#getName()
*/
publicStringgetName(){
returnfileName;
}
/**
*@seepare.ITypedElement#getType()
*/
publicStringgetType(){
returnITypedElement.TEXT_TYPE;
}
/**
*@seepare.IEditableContent#isEditable()
*/
publicbooleanisEditable(){
returntrue;
}
/**
*@seepare.IEditableContent#replace(pare.ITypedElement,pare.ITypedElement)
*/
publicITypedElementreplace(ITypedElementdest,ITypedElementsrc){
returnnull;
}
publicvoidwriteFile(){
this.writeFile(this.fileName,this.getContent());
}
privatevoidwriteFile(StringfileName,byte[]newContent){
FileOutputStreamfos=null;
try{
Filefile=newFile(fileName);
if(file.exists()){
file.delete();
}
file.createNewFile();
fos=newFileOutputStream(file);
fos.write(newContent);
fos.flush();
}catch(IOExceptione){
e.printStackTrace();
}finally{
try{
fos.close();
}catch(IOExceptione){
e.printStackTrace();
}
fos=null;
}
}
}
(3)配置CompareConfiguration
CompareConfigurationconfig=newCompareConfiguration();
config.setProperty(CompareConfiguration.SHOW_PSEUDO_CONFLICTS,Boolean.FALSE);
//left
config.setLeftEditable(true);
config.setLeftLabel("Left");
//right
config.setRightEditable(true);
config.setRightLabel("Right");
(4)定义CompareEditorInput
CompareEditorInputeditorInput=newCompareEditorInput(config){
CompareItemleft=newCompareItem("C:
/A.txt");
CompareItemright=newCompareItem("C:
/Inject.log");
@Override
protectedObjectprepareInput(IProgressMonitormonitor)throwsInvocationTargetException,InterruptedException{
returnnewDiffNode(null,Differencer.CONFLICTING,null,left,right);
}
@Override
publicvoidsaveChanges(IProgressMonitorpm)throwsCoreException{
super.saveChanges(pm);
left.writeFile();
right.writeFile();
}
};
editorInput.setTitle("文件比较");
(5)弹出CompareEditor或Dialog
CompareUI.openCompareEditor(editorInput); //打开对比Editor
CompareUI.openCompareDialog(editorInput);//弹出对比Dialog
三效果
(1)Editor效果
(2)Dialog效果
四其他
(1)代码是基于Eclipse插件项目的emailTemplate创建的,可直接使用附件中的源码替换到默认生成的类。
(2)代码演示了在EclipseRCP环境下使用Compare功能。
∙MessagePopupAction.zip(1.6KB)
∙描述:
源码
∙下载次数:
40
∙17:
57
∙浏览(869)
∙评论(5)
∙分类:
RCPSWT&JFace
∙发布在EclipsePlugIns&RCP&OSGI圈子
∙收藏
2009-09-23
缩略显示
SWT的图片叠加效果
关键字:
imageoverlayicon
一.核心类说明
ImageDescriptor
用于表示一个可用于创建org.eclipse.swt.graphics.Image的类
CompositeImageDescriptor
可用于创建出自定义图像效果的Image的抽象类
DecoratorOverlayIcon
这是org.eclipse.ui.internal.decorators下的类,很可惜,它是package的class,不可外部调用
OverlayIcon
用于创建出2个图片叠加效果的类.不过,只可以做”右上”的叠加
OverlayImageDescriptor
我自己扩展OverlayIcon类,简单的支持”上左”,”上右”,”下左”,”下右”.而不是OverlayIcon只可以做”右上”的叠加
二.代码说明
1.OverlayImageDescriptor.java实现类
2.MainShell可运行类
见源码
三.原始图片
四.效果截图
∙cn.iwoo.swt.image.rar(9.5KB)
∙描述:
源码
∙下载次数:
56
∙10:
58
∙浏览(391)
∙评论
(1)
∙分类:
RCPSWT&JFace
∙收藏
2009-08-08
缩略显示
TreeViewer的ContentProvider详解,以及Lazy载入
关键字:
treeviewerlazypendingcontentprovider
为了实现这样的效果:
载入的过程中,显示Pending。
载入完毕,Pending消失。
我们先从基础的说起,先来看ITreeContentProvider接口:
publicinterfaceITreeContentProvider{
publicObject[]getElements(ObjectinputElement);
publicObject[]getChildren(ObjectparentElement);
publicbooleanhasChildren(Objectelement);
//...
}
getElements表示在setInput(Object)的时候,如何从Object中得到一个数组,而使用这个数组去将树的第一层结点显示出来。
这个方法只在setInput时才使用一次。
getChildren表示在每次展开树的节点时,如果得到下一级节点的值,当然,树的节点展开了一次就不会再调用这个方法了,因为在树节点对应的控件TreeItem中,已经创建好了子节点控件了。
hasChildren就是判断当前节点是否有子节点,有的话,就显示+号。
ITreeContentProvider的使用类型可以分成3种(我自己分的,^-^)。
1。
简单模式
2。
LazyLoader模式(简单)
3。
LazyLoader模式(显示Pending)
一.简单模式
其实就是在setInput的模型中,已经预先将所有的子模型都载入完毕,而不用再动态的载入子模型了。
模型说明:
这个模型代表树节点,是支持父子结构的。
当然,在Jface里面是有一个TreeNode的,org.eclipse.jface.viewers.TreeNode,相应的还提供了一个org.eclipse.jface.viewers.TreeNodeContentProvider。
publicclassTreeNode{
privateTreeNodeparent;
privateListchildren=newArrayList();
privateObjectvalue;
ContentProvider代码:
publicclassSimpleContentProviderimplementsITreeContentProvider{
publicObject[]getElements(ObjectinputElement){
return((TreeNode)inputElement).getChildren().toArray();
}
publicObject[]getChildren(ObjectparentElement){
return((TreeNode)parentElement).getChildren().toArray();
}
publicbooleanhasChildren(Objectelement){
return((TreeNode)element).getChildren().size()>0;
}
构建setInput的模型
就是在构建模型的时候,将所有的子模型都加载好了:
privateTreeNodebuildLazyContent(){
TreeNoderoot=newTreeNode(null);
TreeNodelevel_1_1=newTreeNode("1.1");
root.addChild(level_1_1);
//...
returnroot;
}
其他代码:
viewer.setLabelProvider(newTreeViewerLabelProvider());
viewer.setContentProvider(newSimpleContentProvider());
viewer.setInput(this.buildSimpleContent());
二.LazyLoad模式(简单)
在setInput的模型中,只有最顶层的模型,再每次点击+的时间,将下一层的模型动态的载入,从而将树的子节点构造出来。
也就是在getChildren中动态载入即可。
ContentProvider代码。
注意getChildren和hasChildren的方法实现,hasChildren返回true,表示需要给这个树节点显示+号。
点击+号,getChildren会动态的载入子节点数据,这样就实现了LazyLoad了。
publicclassSimpleLazyContentProviderimplementsITreeContentProvider{
publicObject[]getChildren(ObjectparentElement){
TreeNodeparent=(TreeNode)parentElement;
this.loadChildren(parent);
returnparent.getChildren().toArray();
}
publicbooleanhasChildren(Objectelement){
returntrue;
}
privatevoidloadChildren(TreeNodeparent){
TreeNodechild_1=newTreeNode("1");
parent.addChild(child_1);
TreeNodechild_2=newTreeNode("2");
parent.addChild(child_2);
}
构建setInput的模型:
只需要构建第一层树节点即可,后面的就交给ContentProvider去处理。
privateTreeNodebuildSimpleLazyContent(){
TreeNoderoot=newTreeNode(null);
TreeNodelevel_1_1=newTreeNode("1.1");
root.addChild(level_1_1);
returnroot;
}
其他代码:
viewer.setLabelProvider(newTreeViewerLabelProvider());
viewer.setContentProvider(newSimpleLazyContentProvider());
viewer.setInput(this.buildSimpleLazyContent());
三.LazyLoader模式(显示Pending)
和模式是二一样的,都是点+载入子模型。
但是,如果是需要长时间的加载,模式二会将界面卡住,而这个模式,再点击+号后,会先显示一个Pending树节点(并可以显示进度条),并看到随着数据一个一个载入树节点一个一个添加出来,所有数据都载入后,Pending树节点消失,这样用户体验就会好很多。
在这个模式,需要用到很多其他的类,具体看代码:
模型代码:
1.需要实现IDeferredWorkbenchAdapter接口。
2.注意fetchDeferredChildren方法。
将载入子数据的过程放到了模型里面(很怪)。
publicclassPendingTreeNodeextendsTreeNodeimplementsIDeferredWorkbenchAdapter{
publicvoidfetchDeferredChildren(Objectobject,IElementCollectorcollector,
IProgressMonitormonitor){
PendingTreeNodeparent=(PendingTreeNode)object;
try{
Thread.sleep(500);
}catch(InterruptedExceptione){
e.printStackTrace();
}
PendingTreeNodenode1=newPendingTreeNode("1");
parent.addChild(node1);
collector.add(node1,monitor);
try{
Thread.sleep(500);
}catch(InterruptedExceptione){
e.printStackTrace();
}
PendingTreeNodenode2=newPendingTreeNode("2");
parent.addChild(node2);
collector.add(node2,monitor);
}
ContentProvider代码。
1.添加了一个DeferredTreeContentManager,并使用该manager代理getChildren方法。
2.hasChildren返回true。
3.修改了getElements方法。
publicclassPendingLazyContentProviderimplementsITreeContentProvider{
privateDeferredTreeContentManagermanager;
publicObject[]getChildren(ObjectparentElement){
returnmanager.getChildren(parentElement);
}
publicbooleanhasChildren(Objectelement){
returntrue;
}
publicObject[]getElements(ObjectinputElement){
if(inputElementinstanceofPendingTreeNode){
return((PendingTreeNode)inputElement).getChildren().toArray();
}
returnnewObject[0];
}
publicvoidinputChanged(Viewerviewer,ObjectoldI