使用EclipseRCP进行桌面程序开发(二):菜单、工具栏和对话框

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

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

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

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

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

打开我们上一节使用向导建立的工程,可以发现工程下面自动生成了如下文件:

Application.javaApplicationWorkbenchAdvisor.javaApplicationWorkbenchWindowAdvisor.javaApplicationActionBarAdvisor.javaPerspective.javaplugin.xml

这里的Application.java是我们整个程序的入口点,我们的程序运行的时候,会先执行 Application的run方法,run方法的代码如下:

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  {23   private  static  final String PERSPECTIVE_ID =  " cn.blogjava.youxia.rcp_start.perspective " ;45    public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor (IWorkbenchWindowConfigurer configurer)  {6     return  new ApplicationWorkbenchWindowAdvisor(configurer);7   }89    public String getInitialWindowPerspectiveId()  {10     return PERSPECTIVE_ID;11   }12 }

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

1  public  class ApplicationWorkbenchWindowAdvisor extends  WorkbenchWindowAdvisor  {23    public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer)  {4     super (configurer);5   }67    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer)  {8     return  new ApplicationActionBarAdvisor(configurer);9   }1011    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程序 " );1718   }1920 }

这个类的功能很强大,我们可以重载它的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;23 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;1011  public  class ApplicationActionBarAdvisor extends ActionBarAdvisor  {1213   private IWorkbenchAction action1;1415    public ApplicationActionBarAdvisor(IActionBarConfigurer configurer)  {16     super (configurer);17   }1819    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   }2526    protected  void fillMenuBar(IMenuManager menuBar)  {27     MenuManager newMenu =  new MenuManager( " 第一个菜单 " , " cn.blogjava.youxia.firstmenu " );28     menuBar.add(newMenu);29     newMenu.add(action1);30   }3132 }

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

下面请看Action1类的源代码:

1 package cn.blogjava.youxia.actions;23 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;789  public  class Action1 extends Action implements IWorkbenchAction  {1011   private IWorkbenchWindow workbenchWindow;1213    public Action1(IWorkbenchWindow window)  {14      if (window ==  null )  {15       throw  new IllegalArgumentException();16     }1718     this .workbenchWindow = window;19   }2021    public  void run()  {22     // make sure action is not disposed23      if (workbenchWindow !=  null )  {24       // 在这里添加功能25       FirstDialog dg =  new FirstDialog(workbenchWindow.getShell ());26       dg.open();2728     }29   }3031    public  void dispose()  {32     workbenchWindow =  null ;3334   }3536 }

在构造函数中保存我们工作台窗口的引用,在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;23 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;101112  public  class FirstDialog extends Dialog  {1314   protected Shell shell;1516   private  int result;1718    public FirstDialog(Shell parent, int style)  {19     super (parent, style);20   }2122    public FirstDialog(Shell parent)  {23     this (parent, SWT.NONE);24   }2526    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   }3738    protected  void createContents()  {39     shell =  new Shell(getParent(), SWT.DIALOG_TRIM |  SWT.APPLICATION_MODAL);40     shell.setSize( 150 , 70 );41     shell.setText( " 第一个对话框 " );4243     final Button kButton =  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 );5253     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   }6364 }65

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

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

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

1 5    10      19    20  

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

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

package  cn.blogjava.youxia.actions;23 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;89  public  class Action2  implements IWorkbenchWindowActionDelegate  {1011   private  IWorkbenchWindow window;1213    public  void dispose()  {14     // TODO1516   }17 18    public  void init(IWorkbenchWindow window)  {19     // TODO20       this .window = window;2122   }2324    public  void run(IAction action)  {25     // TODO26      FirstDialog dg =  new FirstDialog(window.getShell());27     dg.open ();2829   }3031    public  void selectionChanged (IAction action, ISelection selection)  {32     // TODO3334   }3536 }

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

让情谊在笑声中升腾,当朋友遇到了难题的时候,

使用EclipseRCP进行桌面程序开发(二):菜单、工具栏和对话框

相关文章:

你感兴趣的文章:

标签云: