使用TreeViewer贡献视图(根据《Eclipse入门到精通》中的例子进行的改编)

作者:李红霞 2005-8-13

本文章允许转载,但请要求注明文章作者及出处

一 创建插件项目

创建一个插件项目example.my.treeview,这个例子将向eclipse贡献一个视图,这个视图采用树(Treeviewer)来实现。

下图是本例的文件清单

+ example.my.treeview

+ src

+ example.my.treeview

- TreeviewPlugin.java

+ exampe.my.treeview.data

- CityEntity.java

- CountryEntity.java

- DataFactory.java

- PeopleEnrity.java

+ example.my.treeview.internal

- ITreeEntry.java

- TreeViewerContentProvider.java

- TreeViewerLabelProvider.java

- TreeViewPart.java

+ JRE System Library

+ Plug-in dependencies

+ META-INF

- MENIFEST.MF

- build.properties

- plugin.xml

二 准备数据模型

首先我们准备数据模型,这些数据模型都保存在example.my.treeview.data这个包中

我们定义一个接口ItreeEntry,这个接口将定义树中每个节点共同特征(名称和子节点),代码如下

package example.my.treeview.internal;

import java.util.List;

public interface ITreeEntry {

public String getName();

public void setName(String name);

//设置得到子节点的集合

public void setChildren(List children);

public List getChildren();

}

这里涉及的实体一共有3个,以下是他们的代码

package example.my.treeview.data;

import java.util.List;

import example.my.treeview.internal.ITreeEntry;

public class CityEntity implements ITreeEntry{

private Long id;//唯一识别码

private String name;//城市名

private List peoples;//城市中的人

public CityEntity(){}

public CityEntity(String name){this.name=name;}

public Long getId() {return id;}

public void setId(Long id) {this.id = id;}

public String getName() {return name;}

public void setName(String name) {this.name = name;}

public List getChildren() {return peoples;}

public void setChildren(List peoples) {

this.peoples = peoples;

}

}

package example.my.treeview.data;

import java.util.List;

import example.my.treeview.internal.ITreeEntry;

public class CountryEntity implements ITreeEntry{

//唯一识别码,在数据库里常为自动递增的ID列

private Long id;

private String name;//国家名

//此国家所包含的城市的集合,集合元素为City对象

private List cities;

//两个构造函数

public CountryEntity(){}

public CountryEntity(String name){this.name = name;}

//相应的get和set方法

public List getChildren() {return cities;}

public void setChildren(List cities) {this.cities = cities;}

public Long getId() {return id;}

public void setId(Long id) {this.id = id;}

public String getName() {return name;}

public void setName(String name) {this.name = name;}

}

package example.my.treeview.data;

import java.util.List;

import example.my.treeview.internal.ITreeEntry;

public class PeopleEntity implements ITreeEntry{

private String name;

public PeopleEntity(){}

public PeopleEntity(String name){this.name=name;}

public List getChildren(){return null;}

public void setChildren(List children){}

public String getName() {return name;}

public void setName(String name) {this.name = name;}

}

三 创建树中的数据结构

代码如下

package example.my.treeview.data;

import java.util.ArrayList;

public class DataFactory {

public static Object createTreeData(){

//生成人的数据对象

PeopleEntity p1 = new PeopleEntity("李红霞");

PeopleEntity p2 = new PeopleEntity("金利军");

PeopleEntity p3 = new PeopleEntity("何涛");

//生成城市的数据对象

CityEntity city1=new CityEntity("湖北");

CityEntity city2=new CityEntity("北京");

CityEntity city3=new CityEntity("湖南");

//生成国家的数据对象

CountryEntity c1 = new CountryEntity("美国");

CountryEntity c2 = new CountryEntity("中国");

//将数据对象连接起来

//人和城市的关系

{

ArrayList list = new ArrayList();

list.add(p1);

city1.setChildren(list);

}

{

ArrayList list = new ArrayList();

list.add(p2);

city2.setChildren(list);

}

{

ArrayList list = new ArrayList();

list.add(p3);

city3.setChildren(list);

}

//城市和国家的关系

{

ArrayList list = new ArrayList();

list.add(city1);

c1.setChildren(list);

}

{

ArrayList list = new ArrayList();

list.add(city2);

list.add(city3);

c2.setChildren(list);

}

//将国家置于一个对象之下,

//这个对象可以是List也可以是数组

{

ArrayList list = new ArrayList();

list.add(c1);

list.add(c2);

return list;

}

}

}

四 标签器和内容器

TreeViewer和TableViewer一样,是用内容器和标签器来控制记录对象的显示,并且使用内容器和标签器的语句也是一样的。

下面是标签器的代码

package example.my.treeview.internal;

import org.eclipse.jface.viewers.ILabelProvider;

import org.eclipse.jface.viewers.ILabelProviderListener;

import org.eclipse.swt.graphics.Image;

/**

* @author hopeshared

* 标签提供器,控制纪录在树中显示的文字和图像等

*/

public class TreeViewerLabelProvider

implements ILabelProvider{

//纪录显示 的文字,不能返回null

public String getText(Object element){

ITreeEntry entry = (ITreeEntry)element;

return entry.getName();

}

//纪录显示的图像

public Image getImage(Object element){

return null;

}

//以下方法暂不用,空实现

public void addListener(ILabelProviderListener listener){}

public void dispose(){}

public boolean isLabelProperty(Object e, String p){return false;}

public void removeListener(ILabelProviderListener listen){}

}

下面是内容器的代码

package example.my.treeview.internal;

import java.util.List;

import org.eclipse.jface.viewers.ITreeContentProvider;

import org.eclipse.jface.viewers.Viewer;

/**

* @author hopeshared

* 内容器,由它决定哪些对象应该输出在TreeViewer里显示

*/

public class TreeViewerContentProvider

implements ITreeContentProvider{

//由这种方法决定树的哪一级显示哪些对象

public Object[] getElements(Object inputElement)

{

if(inputElement instanceof List){

List list = (List)inputElement;

return list.toArray();

}else{

return new Object[0];//生成一个空的数组

}

}

//判断某节点是否有子节点,如果有子节点,

//这时节点前都有一个“+”号图标

public boolean hasChildren(Object element){

ITreeEntry entry = (ITreeEntry)element;

List list = entry.getChildren();

if(list==null||list.isEmpty()){return false;

}else{return true;}

}

//由这个方法来决定父节点应该显示哪些子节点

public Object[] getChildren(Object parentElement){

ITreeEntry entry = (ITreeEntry)parentElement;

List list = entry.getChildren();

if(list==null || list.isEmpty()){return new Object[0];

}else{return list.toArray();}

}

//以下方法空实现

public Object getParent(Object element){return null;}

public void dispose(){}

public void inputChanged(Viewer v, Object oldInput, Object newInput){}

}

五 修改清单文件

下面给出的是plugin.xml文件代码

class="example.my.treeview.internal.TreeViewPart"

id="example.my.treeview.treeview"

name="my first tree view plugin"/>

六 插件的实现

在清单文件中已经指出了这个视图的实现类是example.my.treeview.internal.TreeViewPart,下面给出这个文件的代码

package example.my.treeview.internal;

import org.eclipse.jface.viewers.TreeViewer;

import org.eclipse.swt.SWT;

import org.eclipse.swt.layout.FillLayout;

import org.eclipse.swt.widgets.Composite;

import org.eclipse.ui.part.ViewPart;

import example.my.treeview.data.DataFactory;

public class TreeViewPart extends ViewPart{

public void createPartControl(Composite parent){

Composite topComp = new Composite(parent, SWT.NONE);

topComp.setLayout(new FillLayout());

TreeViewer tv = new TreeViewer(topComp, SWT.BORDER);

tv.setContentProvider(new TreeViewerContentProvider());

tv.setLabelProvider(new TreeViewerLabelProvider());

Object inputObj = DataFactory.createTreeData();

tv.setInput(inputObj);

}

public void setFocus(){}

}

七 运行结果

八 给节点增加动作

增加一个ActionGroup类

package example.my.treeview.internal;

import org.eclipse.jface.action.Action;

import org.eclipse.jface.action.IMenuManager;

import org.eclipse.jface.action.MenuManager;

import org.eclipse.jface.dialogs.MessageDialog;

import org.eclipse.jface.viewers.IStructuredSelection;

import org.eclipse.jface.viewers.TreeViewer;

import org.eclipse.swt.widgets.Menu;

import org.eclipse.swt.widgets.Tree;

import org.eclipse.ui.actions.ActionGroup;

/**

* @author hopeshared

* 生成菜单Menu,并将两个Action传入

*/

public class MyActionGroup extends ActionGroup{

private TreeViewer tv;

public MyActionGroup(TreeViewer treeViewer){

this.tv = treeViewer;

}

//生成菜单Menu,并将两个Action传入

public void fillContextMenu(IMenuManager mgr){

//加入两个Action对象到菜单管理器

MenuManager menuManager = (MenuManager)mgr;

menuManager.add(new OpenAction());

menuManager.add(new RefreshAction());

//生成Menu并挂在树Tree上

Tree tree = tv.getTree();

Menu menu = menuManager.createContextMenu(tree);

tree.setMenu(menu);

}

//打开Action类

private class OpenAction extends Action{

public OpenAction(){

setText("打开");

}

//继承自Action的方法,动作代码写在此方法中

public void run(){

IStructuredSelection selection = (IStructuredSelection)tv.getSelection();

ITreeEntry obj = (ITreeEntry)(selection.getFirstElement());

if(obj != null){

MessageDialog.openInformation(null, null, obj.getName());

}

}

}

//刷新的Action类

private class RefreshAction extends Action{

public RefreshAction(){

setText("刷新");

}

//继承自Action的方法,动作代码写在此方法中

public void run(){

tv.refresh();

}

}

}

接着,修改TreeViewPart.java,代码如下

……

Object inputObj = DataFactory.createTreeData();

//-------------加入动作开始

MyActionGroup actionGroup = new MyActionGroup(tv);

actionGroup.fillContextMenu(new MenuManager());

//-------------加入动作结束

tv.setInput(inputObj);

……

结果如下图所示

九 自定义扩展点

我们想将这个视图的显示内容与视图框架分开,这样,我们需要修改视图显示内容的时候只要重新贡献一次显示内容就可以了。

9.1 添加shema文件

这个sheme文件是采用可视化编辑器进行编辑,然后pde自动生成的,代码如下

[Enter description of this extension point.]

[Enter the first release in which this extension point appears.]

[Enter extension point usage example here.]

[Enter API information here.]

[Enter information about supplied implementation of this extension point.]

9.2 创建接口文件

ItreeEntry.java之前就已经创建好了,不需要修改。现在添加另一个接口文件,代码如下:

package example.my.treeview.internal;

public interface IDataFactory {

public Object createTreeData();

}

于是我们修改DataFactory.java,使它实现这个接口。

9.3 修改清单文件

我们来修改清单文件,加入扩展点声明,并扩展它,代码如下

……

schema="schema/datafactory.exsd"/>

……

9.4 修改TreeviewPlugin.java

增加一个方法Object loadDataFactory(),代码如下

……

public static Object loadDataFactory(){

IPluginRegistry r=Platform. getPluginRegistry();

String pluginID="example.my.treeview";

String extensionPointID="datafactory";

IExtensionPoint p=r.getExtensionPoint( pluginID, extensionPointID);

IConfigurationElement[] c=p.getConfigurationElements();

if( c != null) {

for( int i= 0; i

IDataFactory data = null;

try { data=( IDataFactory)c

.createExecutableExtension("class");

if( data != null){ return data.createTreeData(); }

} catch( CoreException x) { }}}

return new Object();

}

……

9.5 修改TreeViewPart.java

Object inputObj = DataFactory.createTreeData();

替换为

Object inputObj = TreeviewPlugin.loadDataFactory();

9.6 其他辅助文件

其实TreeViewerLabelProvider.java和TreeViewerContentProvider.java可以看成是对DataFactory这个扩展点的辅助文件

9.7运行

跟之前的实现没有区别,但是我们向eclipse贡献了一个扩展点

十 参考资料

《Eclipse入门到精通》

www.sohozu.com

《自己动手编写Eclipse扩展点》

EclipseCon2005_Tutorial1.pdf 《Contributing to Eclipse: Understanding and WritingPlug- ins》

java viewer 控件_插件制作过程记录(使用TreeViewer贡献视图)相关推荐

  1. java 开源控件_一些好用的开源控件

    工作两年,一直都在做些编码方面的表面功夫,实现了很多很炫的功能,在此写下一些体验.有些比较小的dll文件我会发上来,如果是开源组织的代码我会把地址附上,毕竟人家是会更新的.大家还有什么好用的开源控件欢 ...

  2. python 窗体控件_python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐(二)...

    1 #-*- coding: UTF-8 -*- 2 #python tkinter menu 3 #python version 3.3.2 4 #EN = Window 7 5 6 7 from ...

  3. python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐

    在了解python中的tkinter模块的时候,你需要了解一些tkinter的相关知识 下面是python的API文档中的一个简单例子: 1 import tkinter as tk 2 3 clas ...

  4. java treeview控件_【TreeView下载】TreeView控件 v1.1.6 官方版-开心电玩

    软件介绍 TreeView控件是一款有Java语言编写的代码显示工具,这款软件将用户要观看的代码以树状结构显示,支持以节点的方式观看代码,让代码的现实更清晰.更有条理,让用户可以更好的了解代码结构,欢 ...

  5. java viewer 控件_android初学者——自定义控件(继承View)

    对于像我一样的新手,我们习惯用android自带的控件和传统的布局方式. 但对于高手,布局却是如下: 其中A extends LinerLayout, B extends TextView. 上面的话 ...

  6. java jframe 控件_窗体控件JFrame的使用

    ---------------siwuxie095 工程名:TestUI 包名:com.siwuxie095.ui 类名:MyFrame.java 工程结构目录如下: 在 Source 界面和 Des ...

  7. appium java 时间控件_在 Appium 中快速单击控件的变通方法

    为什么需要快速点击控件 在我要测试的APP中,有一个名曰"秘密花园"的玩意儿,里面可以切换 正式.灰度.测试 环境:因为不想让用户随便就可以点进去切环境,开发同学在正常界面的某个位 ...

  8. java 地图控件_控件交互-与地图交互-开发指南-Android 地图SDK | 高德地图API

    控件是指浮在地图图面上的一系列用于操作地图的组件,例如缩放按钮.指南针.定位按钮.比例尺等. UiSettings 类用于操控这些控件,以定制自己想要的视图效果.UiSettings 类对象的实例化需 ...

  9. java 地图控件_室内地图Android SDK地图控件 - 蜂鸟云

    地图控件 Fengmap Android SDK 提供多个控件.控件与地图之间存在交互.本模块将对控件交互部分提供说明介绍. 注:除指北针控件外,其余控件的创建都在onMapInitSuccess事件 ...

最新文章

  1. jsoup 多个 class Selector 怎么写?
  2. ASP.NET Core身份认证服务框架IdentityServer4(2)-整体介绍
  3. 把服务器文件备份到文件服务器,服务器之间文件备份方案、如何把服务器文件自动备份到另外一台服务器?...
  4. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
  5. 操作系统和常用软件下载
  6. 精通Hibernate类与类关联关系:[三]映射一对多双向自身关联关系
  7. 战斗部毁伤效能评估软件系统
  8. 词干提取(stemming)和词形还原(lemmatization)
  9. credential provider filter注意
  10. linux安装 web2py,在Linux上使用web2py_uwsgi_nginx搭建web服务器
  11. 【CVPR 2021】搜索网络宽度:BCNet: Searching for Network Width with Bilaterally Coupled Network
  12. igraph study
  13. laravel 实现微博第三方登陆
  14. 迷你图书管理器1.0 - 变量+数组
  15. ubuntu18.04系统外接显卡(英伟达RTX 2080 Ti)驱动安装
  16. 信息安全技术小测试08设备与环境安全
  17. RHEL 7系统审计、系统日志文件、服务安全及打补丁 AIDE 系统入侵检测
  18. C++11初篇(快速了解)
  19. SpringBoot系列之数据库初始化-jpa配置方式
  20. 历史记录艺术画笔工具

热门文章

  1. 女性向游戏难复制下一个“恋与”,从日本游戏能取到什么经?
  2. MDN Web Docs
  3. 权益证明问题 —— Proof of Stake FAQ
  4. C\C++ Qt开发的动态桌面壁纸程序
  5. 奔驰采用鸿蒙系统,余承东官宣:鸿蒙系统正式登陆奔驰S级
  6. python3爬虫下载音乐_python3爬虫:下载网易云音乐排行榜
  7. OSChina 周日乱弹 —— 蜂蜜真好吃
  8. JavaScript深入浅出第2课:函数是一等公民是什么意思呢?
  9. 倘若生活没有改变,期盼又从何而来
  10. matlab snr mse,MATLAB 均方根误差MSE、两图像的信噪比SNR、峰值信噪比PSNR、结构相似性SSIM...