为RCP的XML编辑器创建

为RCP的XML编辑器创建OutlinePage 2007.12.12阅读(187)下一篇:CCTV,你让我怎么... |返回日志列表 赞赞赞取消赞转载分享评论(7)复制地址更多 
 
这两天所做的RCP项目需要实现XMLEditor的Outline同步显示。 
查了古今中外的资料也没发现一篇真正有用的教程。 
所以在解决问题后记录下来,以供有需要的朋友参考。 


效果如图所示
完成此项任务,我们需要编写以下几个Class: 
1、XMLEditor:extends TextEditor 
2、XMLContentOutlinePage:extends ContentOutlinePage 
3、OutlineContentProvider:implements ITreeContentProvider 
4、OutlineLabelProvider:extends LabelProvider 
其中2、3、4为1的innerClass。 


Step1:创建Editor。 
如何创建没啥好说的,地球人都知道。 
这里就说两个和outlinePage有关的接口。 
1、 
public Object getAdapter(Class key) { 
    if (key.equals(IContentOutlinePage.class)) { 
        IEditorInput input = getEditorInput(); 
        if (input instanceof IFileEditorInput) { 
            if (outlinePage == null) 
                outlinePage = new XMLContentOutlinePage(input); 
            return outlinePage; 
        } 
    } 
    return super.getAdapter(key); 
} 

2、在编辑了XMLEditor内容后需要更新一次我们的outlinePage,所以重写了editorSaved方法。 
public void editorSaved() { 
    if (outlinePage != null) 
        outlinePage.update(); 
} 


Step2:创建XMLContentOutlinePage。 
class XMLContentOutlinePage extends ContentOutlinePage { 
    protected IEditorInput input; 

    public XMLContentOutlinePage(IEditorInput input) { 
        super(); 
        this.input = input; 
    } 

    public void update() { 
        TreeViewer viewer = (TreeViewer) getTreeViewer(); 
        if (viewer != null) { 
            Control control = viewer.getControl(); 
            if (control != null && !control.isDisposed()) { 
                control.setRedraw(false); 
                viewer.setInput(input); 
                viewer.expandAll(); 
                control.setRedraw(true); 
            } 
        } 
    } 

    public void createControl(Composite parent) { 
        super.createControl(parent); 
        TreeViewer viewer = (TreeViewer) getTreeViewer(); 
        viewer.setContentProvider(new OutlineContentProvider()); 
        viewer.setLabelProvider(new OutlineLabelProvider()); 
        viewer.setInput(input); 
        viewer.expandAll(); 
    } 
} 



Step3:创建OutlineContentProvider。 
这里实现了inputChanged方法,用于将Editor中的现有XMLString转换为相应的DOM 
中间绿色的部分依据你使用的DOM类型不同会有不同的实现方式 
我这里使用DOM4J来处理XMLEditor的文本内容 


class OutlineContentProvider implements ITreeContentProvider { 
    IEditorInput input; 
    Document doc; 

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 
        input = (IEditorInput) newInput; 
        if (newInput != null) { 
            IDocument document = getDocumentProvider().getDocument(newInput); 
            if (document != null) { 
try { 
doc = DocumentHelper.parseText(document.get()); 
} catch (DocumentException e) { 
e.printStackTrace(); 
} 
} 
        } 
    } 
   
    public Object[] getChildren(Object parentElement) { 
        Element el = (Element) parentElement; 
        return el.elements().toArray(); 
    } 

    public Object getParent(Object element) { 
        Element el = (Element) element; 
        return el.getParent(); 
    } 

    public boolean hasChildren(Object element) { 
        Element el = (Element) element; 
        return el.elements() != null; 
    } 

    public Object[] getElements(Object inputElement) { 
        //在inputChanged得到新的DOM树以后ECP框架会首先调用此函数,用于获取DOM树的根节点 
        //上面的三个函数用于实现子节点们的递归 
        return doc.getRootElement().elements().toArray(); 
    } 

    public void dispose() { 
    } 
} 



Step4:创建OutlineLabelProvider。 
这个是最简单,但也是不可缺少的一部分。 
content节点们在树里面会显示成什么样全靠它咯。 
偷个懒,让它直接继承LabelProvider吧。 

class OutlineLabelProvider extends LabelProvider { 
    @Override 
    public String getText(Object element) { 
        //这里以Element的tagName为名显示在outline内 
        //如果你愿意,大可使用当前element的任何属性作为它在outline中的名字 
        Element el = (Element) element; 
        return el.getName(); 
    } 
} 



这样就算大功告成了。 
目前还没有实现outline与XMLEditor的反向绑定。 
就是说在选择outline中的节点时,编辑器的内容还不会自动跳转到相应位置。 
觉得有帮助的话,麻烦顶一下。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值