京山游侠

专注技术,拒绝扯淡
posts - 50, comments - 868, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

使用Eclipse RCP进行桌面程序开发(一):快速起步中,我们通过Eclipse的插件开发向导,逐步建立了一个RCP应用程序,但是,这个程序没有任何功能,难以激起我们学习的兴趣。在这一节,我们将一起探索怎样在程序中添加菜单和工具条。先看一下成果:

图一、图二:带有菜单和工具条的RCP程序
rcp18.JPG

rcp19.JPG

图三:工具栏上的按钮的提示文本
rcp20.JPG

图四:点击菜单项或者工具栏按钮后,弹出一个简单的对话框。
rcp21.JPG

这里需要说明一点,为什么要在讲菜单和工具栏的时候一起讲对话框,这是因为对话框是我们所能想到的最简单最直接的用户交互方式,在对话框上可以添加各种各样的控件来实现复杂的功能,为了让我们点击菜单项的时候能够看到效果,这里就用了一个简单的对话框。当然,当我们以后接触到视图、编辑器和透视图这样的概念之后,我们能使用的用户交互方式就不仅仅只是对话框了。

打开我们上一节使用向导建立的工程,可以发现工程下面自动生成了如下文件:
Application.java
ApplicationWorkbenchAdvisor.java
ApplicationWorkbenchWindowAdvisor.java
ApplicationActionBarAdvisor.java
Perspective.java
plugin.xml
这里的Application.java是我们整个程序的入口点,我们的程序运行的时候,会先执行Application的run方法,run方法的代码如下:

 1 public  Object run(Object args)  throws  Exception  {
 2         Display display  =  PlatformUI.createDisplay();
 3          try   {
 4              int  returnCode  =  PlatformUI.createAndRunWorkbench(display,  new  ApplicationWorkbenchAdvisor());
 5              if  (returnCode  ==  PlatformUI.RETURN_RESTART)  {
 6                  return  IPlatformRunnable.EXIT_RESTART;
 7             }

 8              return  IPlatformRunnable.EXIT_OK;
 9         }
  finally   {
10             display.dispose();
11         }

12     }

在第4行我们可以看出,该入口函数将创建用户界面的工作交给了ApplicationWorkbenchAdvisor类。接着,我们打开ApplicationWorkbenchAdvisor.java,代码如下:

 1 public   class  ApplicationWorkbenchAdvisor  extends  WorkbenchAdvisor  {
 2
 3      private   static   final  String PERSPECTIVE_ID  =   " cn.blogjava.youxia.rcp_start.perspective " ;
 4
 5      public  WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer)  {
 6          return   new  ApplicationWorkbenchWindowAdvisor(configurer);
 7     }

 8
 9      public  String getInitialWindowPerspectiveId()  {
10          return  PERSPECTIVE_ID;
11     }

12 }

可以看出,这个类的工作就是为我们的程序指定默认的透视图,然后把创建窗口的工作交给了ApplicationWorkbenchWindowAdvisor类。接着,我们打开ApplicationWorkbenchWindowAdvisor.java文件,看到代码如下:

 1 public   class  ApplicationWorkbenchWindowAdvisor  extends  WorkbenchWindowAdvisor  {
 2
 3      public  ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer)  {
 4          super (configurer);
 5     }

 6
 7      public  ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer)  {
 8          return   new  ApplicationActionBarAdvisor(configurer);
 9     }

10     
11      public   void  preWindowOpen()  {
12         IWorkbenchWindowConfigurer configurer  =  getWindowConfigurer();
13         configurer.setInitialSize( new  Point( 600 450 ));
14         configurer.setShowCoolBar( true );
15         configurer.setShowStatusLine( false );
16         configurer.setTitle( " 第一个RCP程序 " );
17         
18     }

19        
20 }

这个类的功能很强大,我们可以重载它的preWindowCreate、postWindowCreate、preWindowOpen、postWindowOpen等方法,以便修改我们窗口的外观。在这里可以看出,我们重载了preWindowOpen方法来设置窗口的大小和让工具栏可见。很显然,这个类的另外一个功能,就是把创建菜单和工具栏的任务交给了ApplicationActionBarAdvisor类。

到这里,谜底已经揭晓,要创建我们自己的菜单和工具条,就一定是在ApplicationActionBarAdvisor.java中做文章了。不错,打开这个文件,我们可以看到这个类有两个重要的方法:
protected void makeActions(IWorkbenchWindow window);
protected void fillMenuBar(IMenuManager menuBar);
我们可以在makeActions方法中创建我们的Action,什么是Action呢?Action是jface中的一个概念,在jface中通过org.eclipse.jface.action中的Action和ActionContributionItem类实现了视图和处理代码的分离,这样无论何时用户触发了一个控件的事件,都会激活一个相应的Action类实例来进行时间处理。毫无疑问,我们的菜单项是一个Action类的子类了。

下面请看ApplicationActionBarAdvisor.java的源代码:

 1 package  cn.blogjava.youxia.rcp_start;
 2
 3 import  org.eclipse.jface.action.IMenuManager;
 4 import  org.eclipse.jface.action.MenuManager;
 5 import  org.eclipse.ui.IWorkbenchWindow;
 6 import  org.eclipse.ui.application.ActionBarAdvisor;
 7 import  org.eclipse.ui.application.IActionBarConfigurer;
 8 import  org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
 9 import  cn.blogjava.youxia.actions.Action1;
10
11 public   class  ApplicationActionBarAdvisor  extends  ActionBarAdvisor  {
12     
13      private  IWorkbenchAction action1;
14
15      public  ApplicationActionBarAdvisor(IActionBarConfigurer configurer)  {
16          super (configurer);
17     }

18
19      protected   void  makeActions(IWorkbenchWindow window)  {
20         action1  =   new  Action1(window);
21         action1.setText( " 第一个菜单项 " );
22         action1.setId( " cn.blogjava.youxia.actions.action1 " );
23         register(action1);
24     }

25
26      protected   void  fillMenuBar(IMenuManager menuBar)  {
27         MenuManager newMenu  =   new  MenuManager( " 第一个菜单 " , " cn.blogjava.youxia.firstmenu " );
28         menuBar.add(newMenu);
29         newMenu.add(action1);
30     }

31    
32 }

可以看出,我们通过创建cn.blogjava.youxia.actions.Action1类的实例来创建一个菜单项,然后把它加入到菜单newMenu中,然后再把newMenu加入menuBar中,整个过程很容易理解。那么register(action1)是做什么的呢?这是为了把我们的Action的实例注册到工作台中,这样当我们的工作台销毁的时候,我们的Action也可以被销毁。

下面请看Action1类的源代码:

 1 package  cn.blogjava.youxia.actions;
 2
 3 import  org.eclipse.jface.action.Action;
 4 import  org.eclipse.ui.IWorkbenchWindow;
 5 import  org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
 6 import  cn.blogjava.youxia.rcp_start.FirstDialog;
 7
 8
 9 public   class  Action1  extends  Action  implements  IWorkbenchAction  {
10     
11      private  IWorkbenchWindow workbenchWindow;
12
13      public  Action1(IWorkbenchWindow window)  {
14          if  (window  ==   null {
15              throw   new  IllegalArgumentException();
16         }

17
18          this .workbenchWindow  =  window;
19     }

20     
21      public   void  run()  {
22          //  make sure action is not disposed
23          if  (workbenchWindow  !=   null {
24              // 在这里添加功能
25             FirstDialog dg  =   new  FirstDialog(workbenchWindow.getShell());
26             dg.open();
27             
28         }

29     }

30
31      public   void  dispose()  {
32         workbenchWindow  =   null ;
33
34     }

35
36 }

在构造函数中保存我们工作台窗口的引用,在run方法中执行功能,是不是很简单?在这里,我们用到了一个对话框类cn.blogjava.youxia.rcp_start.FirstDialog,这个类从org.eclipse.swt.widgets.Dialog类继承,熟悉swt的朋友一定不会陌生。我建议大家可以使用Designer插件,这个插件对swt/jface提供非常好的可视化支持,在这个对话框中,我们只简单的添加了两个按钮。

FirstDialog.java源文件如下:

 1 package  cn.blogjava.youxia.rcp_start;
 2
 3 import  org.eclipse.swt.SWT;
 4 import  org.eclipse.swt.events.SelectionAdapter;
 5 import  org.eclipse.swt.events.SelectionEvent;
 6 import  org.eclipse.swt.widgets.Button;
 7 import  org.eclipse.swt.widgets.Dialog;
 8 import  org.eclipse.swt.widgets.Display;
 9 import  org.eclipse.swt.widgets.Shell;
10
11
12 public   class  FirstDialog  extends  Dialog  {
13
14      protected  Shell shell;
15     
16      private   int  result;
17
18      public  FirstDialog(Shell parent,  int  style)  {
19          super (parent, style);
20     }

21
22      public  FirstDialog(Shell parent)  {
23          this (parent, SWT.NONE);
24     }

25
26      public   int  open()  {
27         createContents();
28         shell.open();
29         shell.layout();
30         Display display  =  getParent().getDisplay();
31          while  ( ! shell.isDisposed())  {
32              if  ( ! display.readAndDispatch())
33                 display.sleep();
34         }

35          return  result;
36     }

37
38      protected   void  createContents()  {
39         shell  =   new  Shell(getParent(), SWT.DIALOG_TRIM  |  SWT.APPLICATION_MODAL);
40         shell.setSize( 150 70 );
41         shell.setText( " 第一个对话框 " );
42
43          final  Button okButton  =   new  Button(shell, SWT.NONE);
44         okButton.addSelectionListener( new  SelectionAdapter()  {
45              public   void  widgetSelected(SelectionEvent e)  {
46                 result  =   1 ;
47                 shell.dispose();
48             }

49         }
);
50         okButton.setText( " OK " );
51         okButton.setBounds( 10 10 48 22 );
52
53          final  Button cancelButton  =   new  Button(shell, SWT.NONE);
54         cancelButton.addSelectionListener( new  SelectionAdapter()  {
55              public   void  widgetSelected(SelectionEvent e)  {
56                 result  =   2 ;
57                 shell.dispose();
58             }

59         }
);
60         cancelButton.setText( " Cancel " );
61         cancelButton.setBounds( 89 10 48 22 );
62     }

63
64 }

65


上面所讲的,只是添加菜单和工具栏的第一种方法,这种方法把构建菜单的工作以静态代码的方式加入到了ApplicationActionBarAdvisor类中,如果需要修改用户界面,则需要修改代码并重新编译。

添加菜单项的第二种方法就要简单得多,而且修改起来也方便,还可以对菜单项实现更加灵活的控制,但是,需要对Eclipse的插件基础有比较好的了解。那这第二种方法就是通过扩展actionSets扩展点来添加菜单。

对扩展点的扩展,可以通过编辑plugin.xml文件了实现,比如我们添加的第二个菜单项,其配置文件如下:

 1 < extension
 2           id ="cn.blogjava.youxia.actionset"
 3          name ="我的菜单扩展"
 4          point ="org.eclipse.ui.actionSets" >
 5        < actionSet
 6              description ="第一个扩展"
 7             id ="RCP_Start.actionSet1"
 8             label ="RCP_Start.actionSet1"
 9             visible ="true" >
10           < action
11                 class ="cn.blogjava.youxia.actions.Action2"
12                icon ="icons/alt_window_16.gif"
13                id ="RCP_Start.action2"
14                label ="第二个菜单项"
15                menubarPath ="cn.blogjava.youxia.firstmenu/additions"
16                style ="push"
17                toolbarPath ="additions"
18                tooltip ="第二个菜单项的按钮" />
19        </ actionSet >
20     </ extension >

其实Eclipse为我们提供了很好的可视化plugin.xml的编辑器,如下图,我们可以对菜单的外观进行和行为进行灵活的控制:

rcp22.JPG

从配置文件中我们可以看到,我们为这第二个菜单项指定的Action是cn.blogjava.youxia.actions.Action2类,这个类我们必须实现org.eclipse.ui.IWorkbenchWindowActionDelegate接口,这个接口中比org.eclipse.jface.actions.Action中多定义了一个方法public void selectionChanged(IAction action, ISelection selection),这个方法是必须的,以便工作台窗口在用户选定哪一项资源的时候通知我们的Action类的实例。其代码如下:

 1 package  cn.blogjava.youxia.actions;
 2
 3 import  org.eclipse.jface.action.IAction;
 4 import  org.eclipse.jface.viewers.ISelection;
 5 import  org.eclipse.ui.IWorkbenchWindow;
 6 import  org.eclipse.ui.IWorkbenchWindowActionDelegate;
 7 import  cn.blogjava.youxia.rcp_start.FirstDialog;
 8
 9 public   class  Action2  implements  IWorkbenchWindowActionDelegate  {
10     
11      private  IWorkbenchWindow window;
12
13      public   void  dispose()  {
14          //  TODO 
15
16     }

17
18      public   void  init(IWorkbenchWindow window)  {
19          //  TODO 
20          this .window  =  window;
21
22     }

23
24      public   void  run(IAction action)  {
25          //  TODO 
26         FirstDialog dg  =   new  FirstDialog(window.getShell());
27         dg.open();
28
29     }

30
31      public   void  selectionChanged(IAction action, ISelection selection)  {
32          //  TODO 
33
34     }

35
36 }


总结:通过向工作台中添加菜单和工具栏,并使用对话框作为与用户交互的基础,我们已经基本上可以构建功能比较复杂的程序了。但这仅仅只是RCP编程的开端。下一节,我们将一起探索Eclipse的透视图和视图。


评论

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-01-11 13:07 by ziyu_1
非常不错啊。

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2007-03-22 21:32 by Tommy
按照你贴的代码,工具栏好像出不来,是什么原因呢?谢谢!

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2007-03-22 21:35 by Tommy
xml文件中的:cn.blogjava.youxia.firstmenu/additions是指?

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-04-08 08:45 by lvjinxin
我也有同样的问题,请给回复,我的也是工具还有第二个菜单项出来不!!

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-04-11 16:04 by Tide
需要把 ApplicationWorkbenchWindowAdvisor 中的configurer.setShowCoolBar(true); // 参数设置为true

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2007-05-11 19:15 by xxx
需要把 ApplicationWorkbenchWindowAdvisor 中的configurer.setShowCoolBar(true); // 参数设置为true
============
设置为true还是不管用!??

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2007-05-11 19:20 by xxx
菜单栏和透视图之间出现了一个很宽的空白区域,但是没有显示工具栏。
怎么回事儿?望回复

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-06-12 17:24 by 阿南
你没有在CoolBar上加任何东西,所以就空了很大一块,加个Action上去就好了·

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-07-30 16:31 by 小白之家
呵呵

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-12-18 22:10 by kile
博主好!
能不能详细说一下你第二个按钮是怎么做的?
我按照你说第二种方法添加,修改了plugin.xml之后,第二个菜单项是不能出现的,第一个菜单项是好的。
因此,我试图像添加第一个菜单项那样,同时依据你给的action2的源码,但是怎么弄都不对,有的时候第二个菜单项出现了,但是没有action。博主能不能把你的最终的Action2.java和ApplicationActionBarAdvisor.java贴出来,参考一下?
谢谢!
我对java太陌生了,呵呵

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2007-12-24 20:44 by 小河
谢谢,很顺利 完成一二。

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2008-03-19 12:07 by wn
"工具栏的第二个菜单项出不来!"解决方法是:将ApplicationActionBarAdvisor.java中的
protected void fillMenuBar(IMenuManager menuBar) {
MenuManager newMenu = new MenuManager( " 第一个菜单 " , " cn.blogjava.youxia.firstmenu " );"cn.blogjava.youxia.firstmenu" 两边的空格去掉。

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2008-03-29 22:41 by banditgao
原来plugin.xml里的 menubarPath ="cn.blogjava.youxia.firstmenu/additions"



MenuManager newMenu = new MenuManager(" 第一个菜单 ", "cn.blogjava.youxia.firstmenu");


cn.blogjava.youxia.firstmenu 这个东西是对应的,两个一样才能出第二个菜单

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2008-05-04 15:04 by hello
请问博主,如何在RCP菜单栏和工具栏上加上透视图的菜单栏及工具栏啊?
多谢了先

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2008-10-23 16:54 by 小仔
报错:org.eclipse.core.runtime.AssertionFailedException: null argument:Action must not have null id

怎么解决?

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单栏的字体大小及颜色设置  回复  更多评论   

2008-12-29 17:40 by 黄伟
使用Eclipse RCP进行桌面程序开发(二):怎样设置菜单栏的字体大小及颜色设置

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2009-02-05 21:20 by 初学者
报错:java.lang.StackOverflowError
at org.eclipse.jface.action.MenuManager.markDirty(MenuManager.java:507)
不知道原因!望能解答,谢了!

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2009-02-05 21:30 by 初学者
@初学者
找到原因了,是输入错误

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2009-04-17 10:01 by 创意产品网
学习了,感谢。。。

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2010-11-20 09:46 by 澳洲鸟_http://phl.javaeye.com/
感谢博主,我最近在拿eclipse3.6学习,但略微有些不同,但学习绝对没问题

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2012-03-08 10:46 by kane
为什么我在新建工程的时候,如果选择带有intro的插件工程的,自定义的菜单就显示不出来。这个是为什么啊?求博主解答。谢谢!

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2012-08-10 10:55 by jones
4.2 juno 第二个菜单也一直出不来。
1、"cn.blogjava.youxia.firstmenu" 2边去除了空格;
2、< action 等代码中< 后的空格也去除了;

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2012-08-10 11:10 by jones
试验了一晚上。
今天将plugin.xml 中 “tooltip ="第二个菜单项的按钮" />” 的 / 规范为 </action>
run as 后还是只有“第一个菜单项”,无意再次按了空格键,出现对话框(昨天以为是help)。 今天仔细看了下:看到有 第一个views 、第一个菜单项(没第二个菜单项)。 选择了 RCP Perspective,竟然出现了"第一个view"显示区,当然“第二个菜单项”也出现了。

将 </action> 改回 之前的 />, 显示还是正常。 就搞不懂了。

留字希望对后来者有用。 本人也初学者。

=============
"附加" 区:additions
可以去baidu.好像是将菜单、按钮等可按类别组合显示;

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2012-09-28 15:11 by 张晓光
java.lang.RuntimeException: Application "cn.project.one.RCP_Start.application" could not be found in the registry. The applications available are: org.eclipse.e4.ui.workbench.swt.E4Application, org.eclipse.e4.ui.workbench.swt.GenTopic, org.eclipse.equinox.app.error.
这是什么原因呀

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2013-02-01 11:45 by 麦小逸
开始接触rcp,看到你的文章分析代码特别清晰!谢谢!

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2013-05-07 14:38 by jenny
两个工具栏之间怎么通讯?比如有启动和停止,点启动时,启动变灰,停止变可用;点停止时停止变灰,开始变可用。谢谢!

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框[未登录]  回复  更多评论   

2013-07-15 10:45 by 匿名
楼主,我的菜单为何是灰色的呢·不能点,能看到

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2013-07-23 11:01 by sheleng
为什么我的第二个菜单栏和工具栏都无法显示,configurer.setShowCoolBar(true);
"cn.blogjava.youxia.firstmenu"的空格也去掉了,还是无法显示,求救啊...

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2013-07-30 14:23 by a030703130
学习了~_~~_~~_~~_~~_~~_~

# re: 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框  回复  更多评论   

2013-07-30 16:04 by java 博客
学习了 学习了~~~~~

只有注册用户登录后才能发表评论。


网站导航: