八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  240 随笔 :: 0 文章 :: 3330 评论 :: 14 引用

有不少朋友问到如何把一个已有的Eclipse插件转换为RCP应用程序,其实这个过程并不复杂,因为RCP应用也是基于插件的结构,可以说RCP 就是精简后的Eclipse平台,只是我们要对这个平台做一些定制工作。将任何一个传统的Eclipse插件项目转换到RCP可以分为两个步骤,这篇先介 绍第一个步骤:建立应用程序。

GEF入门系列(三、应用实例)里我曾做过一个精简的GEF应用程序(下载),这一篇里我就一步一步的把这个例子转换为RCP应用程序(点击下载转换后的项目打包)。应用程序(Application)是通过扩展org.eclipse.core.runtime.applications扩展点建立的,其作用 是让Eclipse知道你的RCP需要什么样的功能,比如界面上有哪些视图,菜单和工具条,应用程序窗口的初始大小等等。在plugin.xml里添加应 用程序的定义很简单,像下面这样指定一个id和一个类名就可以了。

<extension
      id
="myapplication"
      point
="org.eclipse.core.runtime.applications">
   
<application>
      
<run class="com.example.application.MyApplication"/>
   
</application>
</extension>

接下来我们的主要任务是实现这个类,MyApplication必须实现 org.eclipse.core.runtime.IPlatformRunnable接口,这个接口只定义了一个run()方法,对于Eclipse Platform来说这个方法就相当于传统java程序的main()方法,是入口方法。所有RCP应用程序里这个方法的实现几乎是完全一样的,即启动 Workbench,并把一个WorkbenchAdvisor实例作为参数传给它,如下所示:

public class MyApplication implements IPlatformRunnable {

    
public Object run(Object args) throws Exception {
        Display display 
= PlatformUI.createDisplay();
        
try {
            
int returnCode = PlatformUI.createAndRunWorkbench(display, new MyWorkbenchAdvisor());
            
if (returnCode == PlatformUI.RETURN_RESTART) {
                
return IPlatformRunnable.EXIT_RESTART;
            }
            
return IPlatformRunnable.EXIT_OK;
        } 
finally {
            display.dispose();
        }
    }
}

所以应用程序的定制实际上是通过这个WorkbenchAdvisor实例实现的。现在我们要构造 org.eclipse.ui.application.WorkbenchAdvisor类的一个子类,也就是上面代码里出现的 MyWorkbenchAdvisor,然后覆盖它的一些方法。比较重要的是这两个方法:createWorkbenchWindowAdvisor() 返回一个WorkbenchWindowAdvisor实例,从类名不难看出它的作用是定制应用程序窗口,包括菜单和工具条,稍后将详细介绍; getInitialWindowPerspectiveId()返回一个透视图的id字符串,这个透视图定义RCP应用程序的界面布局,所以如果在原来 的插件里你没有定义透视图,现在必须要新定义一个了。

public class MyWorkbenchAdvisor extends WorkbenchAdvisor {

    
private static final String PERSPECTIVE_ID = "com.example.ui.MyPerspective";

    
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
            IWorkbenchWindowConfigurer configurer) {
        
return new MyWorkbenchWindowAdvisor(configurer);
    }

    
public String getInitialWindowPerspectiveId() {
        
return PERSPECTIVE_ID;
    }

    
public void initialize(IWorkbenchConfigurer configurer) {
        
super.initialize(configurer);

        
//The workaround call
        WorkbenchAdapterBuilder.registerAdapters();
    }
}

注意:因为我们这个RCP里用到了Resource视图,而这个视图依赖org.eclipse.ui.ide,所以要在上面的 initialize()方法里手动注册一下Adapter,否则Resource视图里无法显示现有项目。(Resource视图在RCP里不推荐使 用,这个调用是无奈之举,请参考这条bug报告

现在来看一下前面代码里MyWorkbenchWindowAdvisor是怎样实现的,它继承自 org.eclipse.ui.application.WorkbenchWindowAdvisor类,为了定义窗口大小和标题要覆盖 preWindowOpen()方法,可以看到我们还顺便隐藏了工具条;要定义窗口的菜单和工具条,应该覆盖 createActionBarAdvisor()方法,返回的ActionBarAdvisor实例马上会介绍到。

public class MyWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

    
public MyWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        
super(configurer);
    }

    
public ActionBarAdvisor createActionBarAdvisor(
            IActionBarConfigurer configurer) {
        
return new MyActionBarAdvisor(configurer);
    }

    
public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer 
= getWindowConfigurer();
        configurer.setInitialSize(
new Point(700500));
        configurer.setShowCoolBar(
false);
        configurer.setShowStatusLine(
false);
        configurer.setTitle(
"My RCP Application");
    }
}

有没有注意到,我们新建(和即将新建)的几个类有这样的引用关系:MyApplication->MyWorkbenchAdvisor- >MyWorkbenchWindowAdvisor->MyActionbarAdvisor,在3.1M5以前的Eclipse RCP版本中,还没有ActionbarAdvisor这个类,大部分应用程序定制工作都是在WorkbenchWindowAdvisor这一个类中做 的,带来的问题是这个类的代码很长,可复用的程度比较低;采用现在这种方式就方便多了,比如可以定义几个ActionbarAdvisor然后在 WorkbenchWindowAdvisor中根据需要做出选择,得到的应用程序就具有不同的功能,等等。

现在就来看看MyActionbarAdvisor是怎么实现的,它继承 org.eclipse.ui.application.ActionBarAdvisor类,我们先在makeActions()里构造需要出现在菜单 或工具条上的命令,注意要调用register()方法注册这些命令,作用是在应用程序结束后释放资源,同时支持快捷键操作;然后在 fillMenuBar()方法里把这些命令加入主菜单,因为我们隐藏了工具条,所以没有覆盖fillCoolBar()方法,另外你还可以通过覆盖 fillStatusLine()定义自己的状态栏。我们的这个类实现得很简单,只是一个退出程序菜单项,你应该根据需要添加自己的命令。

public class MyActionBarAdvisor extends ActionBarAdvisor {

    
private IWorkbenchAction exitAction;

    
public MyActionBarAdvisor(IActionBarConfigurer configurer) {
        
super(configurer);
    }

    
protected void makeActions(final IWorkbenchWindow window) {
        exitAction 
= ActionFactory.QUIT.create(window);
        register(exitAction);
    }

    
protected void fillMenuBar(IMenuManager menuBar) {
        MenuManager fileMenu 
= new MenuManager("&File",
                IWorkbenchActionConstants.M_FILE);
        menuBar.add(fileMenu);
        fileMenu.add(exitAction);
    }
}

现在,应用程序需要的类都写好了,让我们检查一下应用程序是否可以正常启动。在Eclipse主菜单上选择Run->Debug...命令, 在对话框左边的“Eclipse Application”组下新建一个运行项“gefpractice-rcp”,在“Program to Run”组下选择“Run an application”,然后在下拉列表里找到我们的应用程序id,要说明的是在applications扩展点里我们指定的id是 “myapplication”,而这里列出的id则添加了插件id作为前缀,变成了“GefPractice-RCP.myapplication”, 如图1所示。


图1 设置为运行应用程序

因为缺省运行会启动Eclipse的全部插件,这样在应用程序里会出现多余的菜单项和功能,所以要设置为只启动我们的这一个插件,方法是切换到 Plug-ins属性页,选择“Choose plug-ins and fragments to launch from the list”,点击右边的“Deselect All”按钮清空选择列表,勾选上我们的插件项目,再按“Add Required Plug-ins”让Eclipse自动添加它依赖的其他插件就可以了,如图2所示。


图2 只启动我们的这一个插件

现自使用这个运行配置启动我们的应用程序,会得到一个很“干净”的界面,如图3所示,如果不是那些Eclipse特有的编辑器/视图的标题栏,你能猜出它是一个Eclipse应用程序吗?作为对比,这是Eclipse插件的版本的运行截图


图3 运行中的应用程序

建立了应用程序,代码的部分就算是完成了,但要得到一个完整的可独立运行的产品这样还不够,下一个帖子里将介绍另一个步骤:将应用程序包装为产品。如果等不及可以先看Branding Your Application这篇文章,只是这篇文章写得比较早,我下个部分要写的是使用.product配置产品,可以更方便的达到相同的目的。关于建立应用程序的更多内容请参考Rich Client Tutorial,这个教程共有三个部分,我当时就是通过它学习的,后来它按照RCP API的发展又及时更新了内容,是难得的入门材料。

posted on 2006-01-07 16:26 八进制 阅读(10729) 评论(31) 编辑 收藏

评论

eclipse中运行插件报错:
Unable to load graphics library [GDI+ is required] (java.lang.UnsatisfiedLinkError: D:\work\workflowdesigner\workplace\.metadata\.plugins\org.eclipse.pde.core\Eclipse ??ó??ò\org.eclipse.osgi\bundles\200\1\.cp\swt-gdip-win32-3139.dll: Can't find dependent libraries)
如何解决呀?thank
 回复 引用   

#2楼 2006-01-09 11:27 fengdh[未注册用户]
恰巧元旦刚过之际,我也碰到同样问题,解决方法愿与同享:

[原因]
推测是XP以外的Windows平台(如98,2000,2000Server等等)上运行之际,缺少GDI+运行库之故。Draw2D(包括SWT GC在内)一部分用到高级Graphics功能,如Anti-alias,Alpha绘图等等,在Windows平台上需要GDI+的支持。 在Linux平台上也需要相应的运行库(Cario for GTK/motif)。

[解决方法]
对于Windows平台,可以从微软网站上下载GDI+的reditributable pack, 将gdiplus.dll拷贝到windows系统目录或者Eclipse(RCP) Application的install location之下即可。
亦可把gdiplus.dll和license文件等拷贝到任意目录,用System.load(...)装入。

 回复 引用   

好文,期待下文
 回复 引用   

原来把插件加入到RCP是这么容易啊!
感谢!
 回复 引用   

to zhanghao:
Rich Client Tutorial 好像已经翻译成了中文,名字是《RCP中文入门教程》
 回复 引用   

#6楼 2006-01-09 17:14 gangge[未注册用户]
按照上面的步骤做了,怎么运行后只有空的RCP框架显示,插件里面的导航栏、属性编辑器、大纲、图形编辑器根本未显示,是怎么回事啊?
 回复 引用   

#7楼[楼主] 2006-01-09 17:35 八进制      
有异常信息吗?
 回复 引用 查看   

#8楼 2006-01-09 17:43 gangge[未注册用户]
有异常:Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.updateMenu
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.configManager
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.newUpdates
Invalid Menu Extension (Path is invalid): org.eclipse.ui.actions.showKeyAssistHandler

运行后框架内显示了菜单条(包括FILE菜单),其它的什么也没有,是不是哪里还要设置什么,透视图(Perspective)我也加了,是不是还要加视图(View);
 回复 引用   

#9楼 2006-01-09 17:48 gangge[未注册用户]
还有,您在[Eclipse]GEF入门系列(三、应用实例) 中提到Eclipse的项目GefPractice,在Eclipse里导入后运行Run-time Workbench,可是我怎么也找不到在Run菜单下怎么也找不到Run-time Workbench,那我怎么运行这个项目啊?

注:我用的版本是eclipse3.1.1+GEF-SDK-3.1
 回复 引用   

outline和property依赖这两个包
org.eclipse.core.runtime,
org.eclipse.ui, org.eclipse.help
 回复 引用   

#11楼[楼主] 2006-01-09 22:52 八进制      
这几条异常信息我这里也有,你的问题应该不是这个原因,你可以下载我提供的那个项目试试有没有问题,如果没有问题可能是代码哪里写得不对,比如WorkbenchAdvisor里没有返回Perspective的id。

Run菜单下有个"Run...",选择这个命令会弹出运行对话框,左边最上面的就是“Run-time Workbench”,现在改叫“Eclipse Application”了。
 回复 引用 查看   

#12楼 2006-01-10 09:51 gangge[未注册用户]
谢谢,我已经下载了gefpractice31.zip并且导入到Eclipse,按照上面的步骤加入RCP中,运行还是空的框架,真不知怎么办。
本文加透视图(MyPerspective)的那部分好象略过了,我写的MyPerspective是这样:
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class MyPerspective implements IPerspectiveFactory {

public void createInitialLayout(IPageLayout layout) {
// TODO Auto-generated method stub

}

}
是不是要在createInitialLayout方法中要加入什么代码吗
 回复 引用   

#13楼 2006-01-18 17:03 Aimd[未注册用户]
gangge:
please see:
http://www.eclipse.org/articles/Article-RCP-3/tutorial3.html
 回复 引用   

#14楼[楼主] 2006-01-18 17:25 八进制      
Thank you, yanbin:-)
 回复 引用 查看   

#15楼 2006-01-24 06:40 2008[未注册用户]
有异常:
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.updateMenu
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.configManager
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.newUpdates
Invalid Menu Extension (Path is invalid): org.eclipse.ui.actions.showKeyAssistHandler

运行后框架内显示了菜单条(包括FILE菜单),其它的什么也没有

我也是这样,我什么都没有改动,,,是不是源代码有错误呢
请版主看看呀,谁有运行正确的么???急,谢谢
 回复 引用   

#16楼 2006-01-30 13:38 carol[未注册用户]
首先祝大家春节快乐!!!!

我也有楼上出现的异常

Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.updateMenu
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.configManager
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.newUpdates
Invalid Menu Extension (Path is invalid): org.eclipse.ui.actions.showKeyAssistHandler

运行后显示了各种Vews (Navigator, Properties和Outline),但是那个GEF的Editor(PracticeEditor)没有出现。我觉得不出现PracticeEditor的原因是因为我没有发现任何地方调用openEditor这个函数来打开,如果初始打开的话,应该在MyWorkbenchAdvisor中就应该调用该函数打开PracticeEditor,但是调用该函数打开PracticeEditor的时候,又要用到*EditorInput类,但是我没有发现斑竹的源代码中有这个类。请教是不是这个原因!

 回复 引用   

#17楼[楼主] 2006-01-30 19:53 八进制      
异常我这里也有,呵呵,但不影响使用。
在Navigator里新建一个项目,在项目里新建一个文件如test.gefpractice就能看到编辑界面了。
 回复 引用 查看   

#18楼 2006-01-30 23:19 carol[未注册用户]
八进制大年初二坚持回答问题,简直让我感动的热泪盈眶。我去看看是怎莫把PracticeEditor打开的,因为我想在应用初始化的时候就打开PracticeEditor。
 回复 引用   

protected void makeActions(final IWorkbenchWindow window) {
exitAction = ActionFactory.QUIT.create(window);
register(exitAction);
}
请问这里添加的菜单项必须是注册的Action吗?我试过直接新建一个Action不能添加到菜单项里面。或者不是ActionFactory.java中定义的Action如果register()的话会报错空的register id,这怎么解决呢?因为要自己设计菜单,谢谢了!
 回复 引用   

#20楼[楼主] 2006-03-05 08:19 八进制      
在你的action的构造方法里setActionId()试试,每个action要有一个id的。
 回复 引用 查看   

#21楼 2006-03-14 21:05 maob[未注册用户]
我在构造时出现:
Application "edu.mm.dbs.gmf.editor.myapplication" could not be found in the registry.
异常,不知要在何处注册
 回复 引用   

#22楼[楼主] 2006-03-15 10:54 八进制      
可能是你的插件没能正常启动,比如在plugin.xml里有错,或者启动过程中出现如nullpointerexception错误,造成这个application没有注册到registry里。
 回复 引用 查看   

#23楼 2006-04-11 12:09 czhcc[未注册用户]
其实出现
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.updateMenu
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.configManager
Invalid Menu Extension (Path is invalid): org.eclipse.update.ui.newUpdates
Invalid Menu Extension (Path is invalid): org.eclipse.ui.actions.showKeyAssistHandler
错误是没有地方添加这几个菜单项,只要在ActionBarAdvisor.fillMenuBar中加一个M_HELP菜单项,就可以解决了。
 回复 引用   

#24楼[楼主] 2006-04-11 20:10 八进制      
多谢czhcc的提醒:-)
 回复 引用 查看   

我是从头到尾的研究了你的两篇贴,觉得写得真好,(至少我认为是我看过的里面),我也照做了,后来,在Eclipse环境中可以正常运行,并可看到效果,但最终导出产品时,报错!并生成了错误日记,里面好象报什么类找不到啊等,很纳闷,那为什么测试运行能正常进行了,调试也没错,只是一些警告罢了,求你帮忙解决一下吧!!!!!!!!下面是错误日志:提一下,com.xinwei.shlr.ac是rcp项目用到的另一个插件

# 9 六月 2006 16:40:53
----------
75。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 19 行)
new POIFSFileSystem(new FileInputStream("c:/a.xls"));
^^^^^^^^^^^^^^^
POIFSFileSystem 不能解析为类型
----------
76。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 20 行)
HSSFWorkbook wb = new HSSFWorkbook(fs);
^^^^^^^^^^^^
HSSFWorkbook 不能解析为类型
----------
77。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 20 行)
HSSFWorkbook wb = new HSSFWorkbook(fs);
^^^^^^^^^^^^
HSSFWorkbook 不能解析为类型
----------
78。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 21 行)
HSSFSheet sheet = wb.getSheetAt(0);
^^^^^^^^^
HSSFSheet 不能解析为类型
----------
79。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 22 行)
HSSFRow row = sheet.getRow(2);
^^^^^^^
HSSFRow 不能解析为类型
----------
80。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 25 行)
HSSFCell cell = row.getCell((short)3);
^^^^^^^^
HSSFCell 不能解析为类型
----------
81。D:\example\com.xinwei.shlr.ac\src\com\xinwei\shlr\util\ReadWriteWorkbook.java 中存在错误
(位于第 28 行)
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
^^^^^^^^
HSSFCell 不能解析
----------
81 个问题(34 个错误,47 个警告)
 回复 引用   

#26楼[楼主] 2006-06-09 17:24 八进制      
输出产品的时候少了东西,可能是POIFSFileSystem等类所在项目的build.properties有问题。
 回复 引用 查看   

#27楼 2006-06-29 13:49 tz[未注册用户]
download‘八进制’的gef项目之后,按上面所说做相应修改,运行没有抛出异常,但只显示一个基本的rcp框架(带有FILE菜单),你说的Navigate也没有显示。不知道是什么原因。是否还需在public void createInitialLayout(IPageLayout layout) 方法里面在加些东西?谢谢
 回复 引用   

#28楼 2006-06-29 14:45 tz[未注册用户]
知道怎么回事了,谢谢
 回复 引用   

#29楼 2007-03-29 13:56 nemo[未注册用户]
我的Eclipse RCP程序在Export时出错,许多类似下面的错误信息,请问能告诉我怎么修复吗?

170. ERROR in D:\eclipse\workspace\myProject\src\myProject\ApplicationWorkbenchAdvisor.java (at line 7)
import org.eclipse.ui.internal.ide.model.WorkbenchAdapterBuilder;
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The import org.eclipse.ui.internal.ide cannot be resolved
----------
171. ERROR in D:\eclipse\workspace\myProject\src\myProject\ApplicationWorkbenchAdvisor.java (at line 30)
WorkbenchAdapterBuilder.registerAdapters();
^^^^^^^^^^^^^^^^^^^^^^^
WorkbenchAdapterBuilder cannot be resolved
 回复 引用   

八进制,你好!我问个问题:
我将GEF转换成RCP后,以前在工具栏中添加的命令快捷键没有再显示,请问该怎么处理?是不是要在ActionBarAdvisor中再添加?
 回复 引用   

8进制是这样的,我在GEF工具栏中添加了按照倍率放大、缩小的功能。但是将GEF转成RCP后,这些功能没有出现,ActionFactory和contributionItemFactory中没有找到相关的放大缩小方法,请问该怎么解决这个问题呢?
 回复 引用