替RCP的XML编辑器创建
为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中的节点时,编辑器的内容还不会自动跳转到相应位置。 觉得有帮助的话,麻烦顶一下。