关于Eclipse开发插件(三)
视图之间实现事件监听
两个视图中的组件之间的互动,在开发插件的时候是经常碰到的问题.点击视图1列表的某项时,视图2的文本框显示相应的字符.
第一种主动式:
主动式就是在视图1的代码块中获取对视图2的对象的引用.然后将视图1中的对象主动的传给视图2.
修改View1.java和View2.java
Eclipse通过plugin.xml来加载插件和插件中的扩展点(如视图扩展点),所以可以在View1.java中由id标识来取得视图2对象.
View1.java
public class View1 extends ViewPart {
private List list; // 将列表写成类的实例变量,以扩大它的可访问范围
//注意这个List并不是java.util包下的.而是org.eclipse.swt.widgets.List;包下的.
public void createPartControl(Composite parent) {
IWorkbenchHelpSystem help = PlatformUI.getWorkbench().getHelpSystem();
help.setHelp(parent, "cn.com.kxh.myplugin.buttonHelpId");
Composite topComp = new Composite(parent, SWT.NONE);
topComp.setLayout(new FillLayout());
list = new List(topComp, SWT.BORDER);
list.add("中国");
list.add("美国");
list.add("法国");
// 列表选择事件监听
list.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// 由IWorkbenchPage获得view2对象
IWorkbenchPage wbp = getViewSite().getPage();
//在插件中IWorkbenchPage对象比较重要,这里再给出一种获得此对象的通用的方法.
// Activator.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
IViewPart view2 = wbp.findView("cn.com.kxh.myplugin.View2");
//这个地方的参数是"视图2"在plugin.xml中的id标识.由此可见plugin.xml文件在插件中的地位是极其重要的.
// 将当前选择的列表项显示在文本框中
Text text = ((View2) view2).getText();
text.setText(list.getSelection()[0]);
}
});
}
@Override
public void setFocus() {}
}
View2.java (将View2.java的文本框对象改成类的实例变量,并编写相应的Setter和Getter方法)
public class View2 extends ViewPart {
private Text text;
public void createPartControl(Composite parent) {
Composite topComp = new Composite(parent,SWT.NONE);
topComp.setLayout(new FillLayout());
text = new Text(topComp,SWT.BORDER);
text.setText("我是Text框");
}
public void setFocus() {}
public Text getText() {
return text;
}
public void setText(Text text) {
this.text = text;
}
}
SamplePerspective.java(和我的上一篇博客上没有做任何修改)
public class SamplePerspective implements IPerspectiveFactory {
// 参数IPageLayout是用于透视图的布局管理器
public void createInitialLayout(IPageLayout layout) {
// 得到本透视图的编辑空间标识
String editorArea = layout.getEditorArea();
// 在透视图左部创建一个空间,并将“视图1”放入其中。
// "left"是此空间的标识;IPageLayout.LEFT指出此空间在透视图布局中的位置靠左;
// 0.2f 指此空间占用透视图20%的宽度;editorArea 指使用透视图的编辑空间
IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.2f, editorArea);
left.addView("cn.com.kxh.myplugin.View1"); // 参数为plugin.xml中“视图1”的id标识
// 将“视图2”加入到透视图的底部
IFolderLayout bottom = layout.createFolder("bottom", IPageLayout.BOTTOM, 0.8f, editorArea);
bottom.addView(View2.class.getName());// 由于我们把视图的id取成和类全名一样,所以也可以用这种写法
// 将以前定义的actionset(主菜单、工具栏按钮)加入到本透视图。这要在plugin.xml文
// 件的action设置中将visible="false"才看得出效果,这时打开其他透视图,action设置的
// 主菜单、工具栏按钮将不会出现在界面上,只有打开本透视图才会出现。
layout.addActionSet("myplugin.actionSet");// 参数为actionSet在plugin.xml中的id标识
}
}
总结:
(1)在插件中IWorkbenchPage对象比较重要,这里再给出一种获得此对象的通用方法,不过他是获得当前活动的IWorkbenchPage对象.
Activator.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivepage();
(2)IWorkbenchPage.findView("cn.com.kxh.myplugin.View2")中的参数为"视图2"在plugin.xml中设置的id标识.
由此可见.plugin.xml文件在插件中的地位是及其重要的.IWorkbenchPage处理findView方法之外.还用findEditor方法来得到编辑器对象.像"cn.com.kxh.myplugin.View2"这种标识符在系统开发中会经常用到,最好建立一个类来集中放置这些字符串常量.然后系统中用的时候只用其常量名即可,否则把标识符的字串分散在代码中,以后改起来会非常麻烦.常量类的示例代码如下:
public final class StringConstants{
public final static String VIEW1="cn.com.kxh.myplugin.View1";
public final static String VIEW2=View2.class.getName();
}
要用的时候时候直接类名点调用就可以了.
附上上面代码的运行结果.


第二种监听式:
Eclipse环境的3个视图:"包资源管理器,大纲,属性"当双击包资源管理器中的结点时,大纲和属性视图也跟着改变.当然用前面讲的主动式来实现这个效果,不超过一个视图,用主动式就比较麻烦了,可以随着包资源管理器结点而需要改变的可能不止是大纲,属性视图,这时主动式就力所不及了.对于这种情况,则可以使用监听式.
1.基本实例
例如:View1,View2和View3视图,其中View2,View3需要监听View1中表格的选择事件.可以这样实现.
(1)在View1类的createPartControl方法中加上如下一句:
getSite().setSelectionProvider(tableViewer);//假设视图中有一个表格对象tableViewer
setSelectionProvider方法的参数类型是ISelectionProvider(provider翻译为提供者),
而TableViewer类正好实现了这一个接口(TreeViewer也一样).加此一句之后,如果再选择表格行时,
底层事件机制将会通知所有监听者.
(2)接着需要在View2,View3中各添加一个监听器到底层,一般也是写在createPartControl方法中.代码如下所示:
getSite().getPage().addSelectionListener(new ISelectionListener(){
public void selectionChanged(IWorkbenchPart part,ISelection selection){
String partId = part.getSite().getId();
if(partId.equals("cn.com.kxh.myplugin.View1")){
System.out.println(part.getTitle());//part就是View1对象
System.out.println(selection);//selection就是被选择的表格行所代表的记录对象
}
}
});
这样,就在View2,View3中截获了View1的选择事件.由于底层的选择提供者可能不仅仅是View1,所以才需要再View2,View3的监听代码中根据View1对plugin.xml中的id标识做一下判断.当然,也可以将这个判断交由底层来负责.如下所示:
getSite().getPage().addSelectionListener("cn.com.kxh.myplugin.View1",new ISelectionListener(){
public void selectionChanged(IWorkbenchPart part,ISelection selection){
System.out.println(part.getTitle());//part就是View1对象
System.out.println(selection);//selection就是被选择的表格行所代表的记录对象
}
});
如果View1中有两个表格怎么办?像下面的这样是行不通的.
getSite().setSelectionProvider(tableViewer1);
getSite().setSelectionProvider(tableViewer2);
既然是一个视图中只能设置一个选择提供者,那么可以换一种思路:创建一个自定义的选择提供者,然后由这个选择提供者收集tableViewer1,tableViewer2的选择事件集中传到底层.
自定义选择提供者就需要实现ISelectionProvider接口,查了一下该接口的层次结构发现有一个SelectionProviderAdapter适配器类,可惜它不是public类,无法继承它.那么久将SelectionProviderAdapter的代码复制到如下的MySelectionProvider类中.并略做修改.
class MySelectionProvider implements ISelectionProvider {
List listeners = new ArrayList();
ISelection theSelection = StructuredSelection.EMPTY;
public void addSelectionChangedListener(ISelectionChangedListener listener) {
listeners.add(listener);
}
public ISelection getSelection() {
return theSelection;
}
public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
listeners.remove(listener);
}
public void setSelection(ISelection selection) {
theSelection = selection;
final SelectionChangedEvent e = new SelectionChangedEvent(this, selection);
Object[] listenersArray = listeners.toArray();
for (int i = 0; i < listenersArray.length; i++) {
final ISelectionChangedListener l = (ISelectionChangedListener) listenersArray[i];
Platform.run(new SafeRunnable() {
public void run() {
l.selectionChanged(e);
}
});
}
}
}
现在有了选择提供器,但是View1中两个表格选择事件的功能还没有实现,可以发现TableViewer有一个addSelectionChangedListener方法.它能够监听表格的选择事件,但它接受的参数类型是ISelectionChangedListener.可以再单独创建一个ISelectionChangedListener接口的实现类,也可以让MySelectionProvider实现此接口.从而让MySelectionProvider即是底层的选择提供者,又是表格的选择事件的监听者.这里采用后一方案,让MySelectionProvider再实现ISelectionChangedListener接口.如下所示:
class MySelectionProvider implements ISelectionProvider,ISelectionChangedListener{
...原代码不改变.省略
public void selectionChanged(SelectionChangedEvent event){
setSelection(event.getSelection());
}
}
View2,View3中的代码不必修改,只需要把View1类中的相应代码修改如下:
MyselectionProvider selectionProvider = new MySelectionProvider();
tableViewer1.addSelectionChangedListener(selectionProvider);
tableViewer2.addSelectionChangedListener(selectionProvider);
getSite().setSelectioinProvider(selectionProvider);
这里只提到了视图,实际上任何WorkbenchPart的子类都可以使用这种机制,包括编辑器,另外,由于可以创建自定义选择提供者,所以可以不仅局限于监听TreeViewer或者TableViewer,也可以监听Combo,Text等组件的非选择事件,只需要将要传送的信息包装成一个ISelection对象传给MySelectionProvider.setSelection方法既可.下面的代码就可以使得View1中的文本框组件的每次击键字符传播给各个视图的监听器.
final MySelectionProvider selectionProvider = new MySelectionProvider();
text.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent e){
String s = String.valueOf(e.character);
ISelection selection = new StructuredSelection(s);
selectionProvider.setSelection(selection);
}
public void keyReleased(KeyEvent e){}
});
注意:滥用底层事件广播机制可能会对性能有影响,但这需要用户在实际开发中做出测试和评估,以确定方法是否真的对性能造成了影响,而不是想当然.
关于Eclipse开发插件(三)的更多相关文章
- 程序猿必备的8款web前端开发插件三
1.HTML5 Canvas 3D波浪翻滚动画 之前我们分享过好几款基于HTML5 Canvas的波浪和水波纹动画,比如这款HTML5 3D波浪起伏动画特效和这款超酷无比的HTML5 WebGL水面水 ...
- Hadoop伪分布配置与基于Eclipse开发环境搭建
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 在windows下用eclipse + pydev插件来配置python的开发环境
在windows下用eclipse + pydev插件来配置python的开发环境 一.安装 python 可以到网上下个Windows版的python,官网为:https://www.python. ...
- Spring(一):eclipse上安装spring开发插件&下载Spring开发包
eclipse上安装spring开发插件 1)下载安装插件包:https://spring.io/tools/sts/all 由于我的eclipse版本是mars 4.5.2,因此我这里下载的插件包是 ...
- 第三篇:配置Hadoop的Eclipse开发环境
前言 在先前的文章中,已经介绍了如何在Ubuntu Kylin操作系统下搭建Hadoop运行环境,而现在将在之前工作的基础上搭建Eclipse开发环境. 配置 开发环境:Eclipse 4.2,其他同 ...
- Python开发环境(1):Eclipse+PyDev插件
电脑:小米笔记本电脑Pro 15.6寸(i5-8250U),操作系统:Windows 10,JDK版本:1.8.0_152(环境变量已配置) Step 1.下载Eclipse 根据我的CPU型号,选择 ...
- Eclipse开发环境配置,打磨Eclipse,安装插件(适用3.4,3.5,3.6,3.7)
转载自:http://elf8848.iteye.com/blog/354035 打磨Eclipse -- 磨刀不误砍柴工 -------------------------------------- ...
- eclipse SE增加Web开发插件
最近接触了些java项目,之前安装了eclipse SE版本.没有Web开发插件,调试不了Web代码.点击“Window”--“Preference” 左边菜单栏是找不到“Server”项来配置服务器 ...
- windows下用eclipse+goclipse插件+gdb搭建go语言开发调试环境
windows下用eclipse+goclipse插件+gdb搭建go语言开发调试环境 http://rongmayisheng.com/post/windows%E4%B8%8B%E7%94%A ...
随机推荐
- case中定义变量
1.c语言switch/case中定义变量 case 0: int b = 0 ; printf("0");break; case 1: printf("1" ...
- 自动脚本工具新版 v2.0
自动脚本工具 下载 下载工具后,解压,直接双击 "execute.bat" 文件后(前提已配置好 jdk 1.7 的环境),会生成文件夹 "output",该文 ...
- 《Oracle Database 12c DBA指南》第一章 - 基本技能简介
当前关于12c的中文资料比较少,本人将关于DBA的一部分官方文档翻译为中文,很多地方为了帮助中国网友看懂文章,没有按照原文句式翻译,翻译不足之处难免,望多多指正. 1 基本技能简介 作为一个数据库管理 ...
- 本地已有SVN项目导入到eclipse中
有时候在本地上checkout了项目,在eclipse中不希望重新checkout一次,可以如下操作: 1.在project上右键-> team -> share project -> ...
- Codeforces Round #105 (Div. 2) ABCDE
A. Insomnia cure 哎 只能说英语太差,一眼题我看了三分钟. 题意:给5个数k, l, m, n 和 d,求1~d中能被k, l, m, n 至少一个整除的数的个数. 题解:…… 代码: ...
- nyoj 49 开心的小明
开心的小明 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 小明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天 ...
- HDFS的Java客户端操作代码(HDFS的查看、创建)
1.HDFS的put上传文件操作的java代码: package Hdfs; import java.io.FileInputStream; import java.io.FileNotFoundEx ...
- IOS开发--C语言入门--如何结合Terminal和Vim开发C语言程序
一直以来都想着挤出时间,记录开发之路的点点滴滴(现在记录已成回忆),和大家一起分享,开发人员总是在沟通和相互学习中提高自身的能力.路过的大神也好初学者也罢,若发现文章中又观点不对的,还望大家指出. 现 ...
- [置顶] MapReduce 编程之 倒排索引
本文调试环境: ubuntu 10.04 , hadoop-1.0.2 hadoop装的是伪分布模式,就是只有一个节点,集namenode, datanode, jobtracker, tasktra ...
- Visual Studio动态代码生成的实现基础
这篇文章讨论以下3个问题: 1.代码生成器应该做什么 2.大多数代码生成器的缺点 3.动态代码生成实现的基础 代码生成器应该做什么? 我认为,目标是加快项目开发,方式是减少重复代码手工操作,实现是用过 ...