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