视图是工作台页面内的可视组件,通常用来浏览信息的层次结构(如工作空间)、打开编辑器或显示活动编辑器的属性。用户可以通过“Window”→“Show view”菜单显示视图,也可以从视图局部标题栏关闭视图。
视图分类
在Eclipse中用户可以在同一时间打开多个视图(编辑器在同一时间只能打开一个),每个视图能够有自己的位置布局信息,Eclipse会根据上一次视图布局的信息初始化视图。
Eclipse视图一般来说有两种表现形式,一种是用户通过视图扩展点“org.eclipse.ui.views”实现自定义的视图,另一种是实现Eclipse中视图提供的扩展,用户可以通过实现Eclipse的相应接口实现,如Outline视图和Properties视图,如图1所示。
在Eclipse中,用户可以按自己的要求建立自己的视图,即扩展Eclipse的视图扩展点。也能实现Eclipse的接口,通过Eclipse的Adapter机制实现Eclipse的扩展。其中,Outline和Properties视图也是通过这种方式实现的,在后面的章节会介绍Outline视图和Properties视图的实现。
当用户定义了自己的视图后能通过“Window”→“Show view”菜单打开自定义的视图。如图2所示。
常用视图可实现的功能
Eclipse的视图就功能来说一般有两种形式,一种是功能性视图,例如Java的Default视图,default负责用树形目录组织Java的项目结构,并且能通过双击节点在编辑器中打开相应的资源。另一种视图是辅助型的视图,例如Console负责控制台信息的显示。
不管是哪种类型的视图,它们的实现原理是一样的。在Eclipse中视图可以实现的功能有如下一些。
右键菜单:可以通过视图中的树、表弹出的菜单完成相应的功能。
工具栏:可以定制视图的工具栏,完成当前视图的功能。
表格:视图中可以加入表格以显示相应的表结构信息。
树:视图中可以加入树结构以显示相应的树结构信息。
Log 输出:视图中可以直接输出信息。
这些只是一般在Eclipse中可以看到的实现,用户可以把视图当做操作Eclipse接口。
提示:任何SWT的组件都可以作为视图的一部分,用户可以按自己的需求定制自己的视图。
创建“Tree viewer”视图
创建“Tree viewer”视图插件项目,步骤如下:
1. 打开新建向导。
单击Eclipse的“File”→“New”→“Other”菜单项,在弹出的对话框中选择Select对话框左边的 Plug-in Development 向导。
2. 建立一个空的插件项目。
输入插件工程的名字为“com.free.view. treeview”。
输入插件的ID为“com.free.view.treeview”。
输入插件的Name为“helloworld Plug-in”。
选择使用模板建立插件项目,如图3所示。
单击“Next”按钮,选择“Tree viewer”选项。
单击“Finish”按钮,完成项目的建立。
通过这种方式建立了一个包含JFace的“Tree viewer”组件的插件项目,此项目已经具备了视图插件常用的功能。
视图扩展点
通过插件模板创建了“Tree viewer”视图插件,此插件只实现了一个视图分类节点和视图节点。如例程1所示。
例程1 plugin.xml
<extension point="org.eclipse.ui.views"> <category name="tree view" id="com.free.view.categoryall"> <view name="Tree View" icon="icons/tree.GIF" category="com.free.view.categoryall" class="com.free.view.treeview.views.TreeViewTest" id="com.free.view.treeview.views.TreeViewTest">
“plugin.xml”实现了视图的扩展点“org.eclipse.ui.views”,Eclipse会根据扩展点的信息展现视图。
视图扩展点的实现类
在“Tree viewer”视图中要完成的功能有:树、菜单、工具栏和事件响应事件。“Tree viewer”视图的实现类为“TreeViewTest”,通过实现类能实现这些功能。
实现类中要完成如下的功能。
1. 初始化树。
2. 完成菜单和工具栏响应的Action。
3. 完成上下文菜单。
4. 完成工具栏。
5. 完成双击树节点的响应方式。
在createPartControl方法中能对视图进行初始化,代码片段如下。
public void createPartControl(Composite parent) { //初始化树 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); drillDownAdapter = new DrillDownAdapter(viewer); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setSorter(new NameSorter()); viewer.setInput(getViewSite()); //完成菜单和工具栏响应的Action makeActions(); //完成上下文菜单 hookContextMenu(); //完成双击树节点的响应方式 hookDoubleClickAction(); //完成工具栏 contributeToActionBars(); }
通过实现类,用户能加入自己感兴趣的功能。“Tree viewer”视图中实现类的完整代码如例程2所示。
例程2 TreeViewTest.java
public class TreeViewTest extends ViewPart { private TreeViewer viewer; private DrillDownAdapter drillDownAdapter; private Action action1; private Action action2; private Action doubleClickAction; //创建树节点 class TreeObject implements IAdaptable { private String name; private TreeParent parent; public TreeObject(String name) { this.name = name; } public String getName() { return name; } public void setParent(TreeParent parent) { this.parent = parent; } public TreeParent getParent() { return parent; } public String toString() { return getName(); } public Object getAdapter(Class key) { return null; } } class TreeParent extends TreeObject { private ArrayList children; public TreeParent(String name) { super(name); children = new ArrayList(); } public void addChild(TreeObject child) { children.add(child); child.setParent(this); } public void removeChild(TreeObject child) { children.remove(child); child.setParent(null); } public TreeObject [] getChildren() { return (TreeObject [])children.toArray(new TreeObject[children.size()]); } public boolean hasChildren() { return children.size()>0; } } //实现内容提供器 class ViewContentProvider implements IStructuredContentProvider,ITreeContentProvider { private TreeParent invisibleRoot; public void inputChanged(Viewer v, Object oldInput, Object newInput) { } public void dispose() { } public Object[] getElements(Object parent) { if (parent.equals(getViewSite())) { if (invisibleRoot==null) initialize(); return getChildren(invisibleRoot); } return getChildren(parent); } public Object getParent(Object child) { if (child instanceof TreeObject) { return ((TreeObject)child).getParent(); } return null; } public Object [] getChildren(Object parent) { if (parent instanceof TreeParent) { return ((TreeParent)parent).getChildren(); } return new Object[0]; } public boolean hasChildren(Object parent) { if (parent instanceof TreeParent) return ((TreeParent)parent).hasChildren(); return false; } //初始化树节点 private void initialize() { TreeObject to1 = new TreeObject("Leaf 1"); TreeObject to2 = new TreeObject("Leaf 2"); TreeObject to3 = new TreeObject("Leaf 3"); TreeParent p1 = new TreeParent("Parent 1"); p1.addChild(to1); p1.addChild(to2); p1.addChild(to3); TreeObject to4 = new TreeObject("Leaf 4"); TreeParent p2 = new TreeParent("Parent 2"); p2.addChild(to4); TreeParent root = new TreeParent("Root"); root.addChild(p1); root.addChild(p2); invisibleRoot = new TreeParent(""); invisibleRoot.addChild(root); } } //实现标签提供器 class ViewLabelProvider extends LabelProvider { public String getText(Object obj) { return obj.toString(); } public Image getImage(Object obj) { String imageKey = ISharedImages.IMG_OBJ_ELEMENT; if (obj instanceof TreeParent) imageKey = ISharedImages.IMG_OBJ_FOLDER; return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey); } } class NameSorter extends ViewerSorter { } public TreeViewTest() { } public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); drillDownAdapter = new DrillDownAdapter(viewer); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setSorter(new NameSorter()); viewer.setInput(getViewSite()); makeActions(); hookContextMenu(); hookDoubleClickAction(); contributeToActionBars(); } //提供右键菜单 private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { TreeViewTest.this.fillContextMenu(manager); } }); Menu menu = menuMgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, viewer); } //提供视图工具栏 private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); } private void fillLocalPullDown(IMenuManager manager) { manager.add(action1); manager.add(new Separator()); manager.add(action2); } //填充菜单 private void fillContextMenu(IMenuManager manager) { manager.add(action1); manager.add(action2); manager.add(new Separator()); drillDownAdapter.addNavigationActions(manager); // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } private void fillLocalToolBar(IToolBarManager manager) { manager.add(action1); manager.add(action2); manager.add(new Separator()); drillDownAdapter.addNavigationActions(manager); } //创建菜单和工具栏对应的Action private void makeActions() { action1 = new Action() { public void run() { showMessage("Action 1 executed"); } }; action1.setText("Action 1"); action1.setToolTipText("Action 1 tooltip"); action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages(). getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); action2 = new Action() { public void run() { showMessage("Action 2 executed"); } }; action2.setText("Action 2"); action2.setToolTipText("Action 2 tooltip"); action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages(). getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); doubleClickAction = new Action() { public void run() { ISelection selection = viewer.getSelection(); Object bj = ((IStructuredSelection)selection).getFirstElement(); showMessage("Double-click detected on "+obj.toString()); } }; } private void hookDoubleClickAction() { viewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { doubleClickAction.run(); } }); } private void showMessage(String message) { MessageDialog.openInformation( viewer.getControl().getShell(), "Tree View", message); } //响应获得焦点 public void setFocus() { viewer.getControl().setFocus(); } }
上例中通过内容提供器(ViewContentProvider)、标签提供器(ViewLabelProvider)及树节点(TreeObject)的定义提供了树的实现,另外通过createPartControl方法实现了相应的菜单和工具栏。
提示:本例中右键菜单和工具栏的实现方式非常值得效仿,而且非常直观,读者可以比较一下在SWT中的实现方式,找到它们之间的异同点。
运行“Tree viewer”视图
“Tree viewer”插件到此就已经完成,现在可以调试插件了。
1. 运行插件。
2. 打开运行时工作台的“Show View”。
在“Show View”窗口中可以看到前面建立的分类和视图节点。
3. 运行“Tree viewer”视图
双击“Tree View”节点,打开视图窗口,如图4所示。
在Eclipse插件的开发中,视图插件的开发是比较重要的一个部分。视图是工作台页面内的可视组件,用户可以通过视图,扩展Eclipse原有的功能。
-----------------------------------------------------
转载请注明来源此处
原地址:#
发表