`
derekop
  • 浏览: 22939 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

谈一谈 Eclipse RCP 中的对话

    博客分类:
  • rcp
阅读更多
转载: http://it.kswchina.com/java/zd/486283.html  
    在这篇文章里,我要和大家探讨的是对话框,不要小看这个对话框,虽然JFace里面提供了很好用的对话框基类,但是如果你不理解SWT中GUI线程和非GUI线程的概念,那么你依然难以达到你想要的效果。问什么突然想要研究对话框呢?这要从我最近接的一个项目说起。

  有人委托我做一个药店管理系统,这种系统属于进销存管理系统的范畴,理论上讲没有什么难度,可供选择的开发工具有很多,最主流的当然要数 Visual C++和VB、Delphi,如果偷一点懒,选择Office中的Access开发也很简单,但是为了挑战自己,我决定选择Eclipse RCP来写这个程序,Eclipse RCP开发的程序界面很漂亮,但是Eclipse RCP很复杂,稍有不慎就会陷入Bug的泥沼,严重延误工期。这不,一开始就碰到了对话框的难题。

  我的本意是在打开工作台窗口前,先打开一个用户登录的对话框,如果用户登录成功,则关闭对话框,打开工作台窗口。使用Eclipse的向导创建了项目之后,很快我就决定在Application类中实现该功能。我的代码如下,只列出Application类中的start方法:

  public Object start(IApplicationContext context) {

  Display display = PlatformUI.createDisplay();

  // 下面是我的代码

  LoginDialog loginDialog = new LoginDialog();

  // 我的代码结束

  try {

  int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());

  if (returnCode == PlatformUI.RETURN_RESTART) {

  return IApplication.EXIT_RESTART;

  }

  return IApplication.EXIT_OK;

  } finally {

  display.dispose();

  }

  }

  我的本意是只弹出登录对话框,登录对话框关闭后才出现工作台窗口,可是事实证明,即使登录等话框不关闭,也不会影响工作台窗口的创建,效果如下图1:

即使我自己加入阻塞代码也不行,我先加入的代码如下:

  public Object start(IApplicationContext context) {

  Display display = PlatformUI.createDisplay();

  // 下面是我的代码

  LoginDialog loginDialog = new LoginDialog();

  while ( ! loginDialog.getSShell().isDisposed()){

  try {

  Thread.sleep( 100 );

  } catch (Exception e){

  }

  }

  // 我的代码结束

  try {

  int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());

  if (returnCode == PlatformUI.RETURN_RESTART) {

  return IApplication.EXIT_RESTART;

  }

  return IApplication.EXIT_OK;

  } finally {

  display.dispose();

  }

  }

  这个时候虽然可以阻止工作台窗口的产生,但是程序会失去响应,Splash Screen也不消失,关闭程序时会出错,如下图2:

 其实我想要的效果,就是要一个模式对话框,在一般的Windows编程书籍中,都会有专门的篇幅来讲解模式对话框和非模式对话框的区别,以及实现方法。但是Eclipse RCP中没有这样的资料。这个问题当然是可以解决的,下面我们就来讨论其中隐藏的秘密。

  在SWT程序中,一般都会存在两个线程,一个GUI线程,一个非GUI线程,GUI线程就是用来生成窗口和控件的,而非GUI线程里面一般都有一个事件循环,用来处理GUI中产生的事件。在我上面的例子中,我自己加入的阻塞代码不仅没有阻塞GUI线程,反而阻塞了非GUI线程,使得窗口事件得不到处理,所以出现了应用程序没有响应。那么哪一个是GUI线程,哪一个是非GUI线程呢?我刚才加代码的那个肯定是非GUI线程了,而GUI线程,我查了一下文档,文档说GUI线程是在创建Display对象的时候产生的。

  有了上面的知识,就可以解决我们的这个问题了,我们不能用暴力的方法(即Thread的sleep方法)来阻塞非GUI线程,但是我们可以在非 GUI线程里面构建一个事件循环,只要这个事件循环不退出,那后面的工作台窗口当然就不会创建了。构建事件循环,需要用到Display类的一些方法。

  所以,正确的代码如下:

  public Object start(IApplicationContext context) {

  Display display = PlatformUI.createDisplay();

  // 下面是我的代码

  LoginDialog loginDialog = new LoginDialog();

  while ( ! loginDialog.getSShell().isDisposed()){

  if ( ! display.readAndDispatch ())

  display.sleep ();

  }

  // 我的代码结束

  try {

  int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());

  if (returnCode == PlatformUI.RETURN_RESTART) {

  return IApplication.EXIT_RESTART;

  }

  return IApplication.EXIT_OK;

  } finally {

  display.dispose();

  }

  }

  只要把该事件循环的代码转移到对话框类中,我们就可以创建完美的模式对话窗了。

  写到这里,大家肯定会以为Eclipse中没有提供比较好的模式对话框,那就是大家被我误导了。在Eclipse中,Dialog类根本就不是一个窗口,对话框的窗口靠的是Dialog类里面的Shell对象产生的。在Eclipse中大家一定要记住,Shell就等同于Window,所以,没有模式Dialog,却有模式Shell,只需要在创建Shell的时候指定SWT.APPLICATION_MODAL参数就行。而 org.eclipse.jface.dialogs.Dialog类就对Shell做了比较好的封装,使用该类,我们可以很方便地构建一个模式对话框。

  在上面的例子中,我的LoginDialog类没有继承自org.eclipse.jface.dialogs.Dialog,就是使用的一个普通Shell,其代码如下:

  package opengsp;

  import org.eclipse.swt.layout.GridLayout;

  import org.eclipse.swt.graphics.Point;

  import org.eclipse.swt.widgets.Shell;

  import org.eclipse.swt.widgets.Label;

  import org.eclipse.swt.SWT;

  import org.eclipse.swt.widgets.Text;

  import org.eclipse.swt.widgets.Button;

  import org.eclipse.swt.layout.GridData;

  public class LoginDialog {

  private Shell sShell = null ;

  private Label lbUserName = null ;

  private Text txtUserName = null ;

  private Label lbPassword = null ;

  private Text txtPassword = null ;

  private Button btnOK = null ;

  private Button btnCancel = null ;

  public LoginDialog() {

  // TODO Auto-generated constructor stub

  createSShell();

  sShell.open();

  }

  public Shell getSShell() {

  return sShell;

  }

  /**

  * This method initializes sShell

  */

  private void createSShell() {

  sShell = new Shell();

  GridData gridData = new GridData();

  gridData.horizontalSpan = 2 ;

  GridLayout gridLayout = new GridLayout();

  gridLayout.numColumns = 3 ;

  sShell.setText( " 用户登录 " );

  sShell.setLayout(gridLayout);

  sShell.setSize( new Point( 300 , 200 ));

  sShell.addShellListener( new org.eclipse.swt.events.ShellAdapter() {

  public void shellClosed(org.eclipse.swt.events.ShellEvent e) {

  sShell.dispose(); // TODO Auto-generated Event stub shellClosed()

  }

  });

  lbUserName = new Label(sShell, SWT.NONE);

  lbUserName.setText( " 用户名: " );

  txtUserName = new Text(sShell, SWT.BORDER);

  txtUserName.setLayoutData(gridData);

  lbPassword = new Label(sShell, SWT.NONE);

  lbPassword.setText( " 密码: " );

  txtPassword = new Text(sShell, SWT.BORDER);

  Label filler1 = new Label(getSShell(), SWT.NONE);

  btnOK = new Button(getSShell(), SWT.NONE);

  btnOK.setText( " 确定 " );

  btnCancel = new Button(getSShell(), SWT.NONE);

  btnCancel.setText( " 取消 " );

  }

  }

  在上面的代码中,我们需要自己设计OK按钮和Cancel按钮,需要自己处理事件,需要模式对话框的时候,还需要自己构建事件循环。
 其实,我们可以使用JFace提供的Dialog基类来简化我们的开发,使用JFace的Dialog类时,只需要重写几个方法就行了,重写 createDialogArea来添加控件,而且不需要我们自己设计OK按钮和Cancel按钮,重写okPressed来处理事件。所以,我写了了另外一个LoginDialog2类,其代码如下:

  package opengsp;

  import org.eclipse.jface.dialogs.Dialog;

  import org.eclipse.jface.window.IShellProvider;

  import org.eclipse.swt.SWT;

  import org.eclipse.swt.widgets.Composite;

  import org.eclipse.swt.widgets.Control;

  import org.eclipse.swt.widgets.Label;

  import org.eclipse.swt.widgets.Shell;

  import org.eclipse.swt.widgets.Text;

  public class LoginDialog2 extends Dialog {

  private Label lbUserName = null;

  private Text txtUserName = null;

  private Label lbPassword = null;

  private Text txtPassword = null;

  public LoginDialog2(IShellProvider parentShell) {

  super(parentShell);

  // TODO Auto-generated constructor stub

  }

  public LoginDialog2(Shell parentShell) {

  super(parentShell);

  // TODO Auto-generated constructor stub

  }

  @Override

  protected Control createDialogArea(Composite parent) {

  // TODO Auto-generated method stub

  Composite composite = (Composite) super.createDialogArea(parent);

  lbUserName = new Label(composite, SWT.NONE);

  lbUserName.setText("用户名:");

  txtUserName = new Text(composite, SWT.BORDER);

  lbPassword = new Label(composite, SWT.NONE);

  lbPassword.setText("密码:");

  txtPassword = new Text(composite, SWT.BORDER);

  return composite;

  }

  }

  而这个时候,在Application类中的代码如下:

  public Object start(IApplicationContext context) {

  Display display = PlatformUI.createDisplay();

  //下面是我的代码

  LoginDialog2 loginDialog = new LoginDialog2(new Shell());

  loginDialog.open();

  //我的代码结束

  try {

  int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());

  if (returnCode == PlatformUI.RETURN_RESTART) {

  return IApplication.EXIT_RESTART;

  }

  return IApplication.EXIT_OK;

  } finally {

  display.dispose();

  }

  }

  最后说一点,关于可是化编辑环境的。VE是在是太不能让人满意了,根本没有办法对Dialog进行可视化编辑,而且用于Eclispe 3.4的VE 1.4非官方版也不能对ViewPart进行编辑。建议打击使用SWT Designer.

  还有,我觉得不应该把这个对话框插入到Application类中,而是应该放到 ApplicationWorkbenchWindowAdvisor类的preWindowOpen方法中。
  • 大小: 31.9 KB
  • 大小: 25.2 KB
分享到:
评论

相关推荐

    Eclipse rcp深入浅出中英文版及配套代码

    Eclipse RCP,全称Eclipse Rich Client Platform,是一个基于Java的框架,用于构建桌面应用程序。这个框架由Eclipse基金会维护,是Eclipse IDE的一部分,允许开发者创建功能丰富的、可扩展的应用程序,拥有类似IDE的...

    Eclipse RCP 软件打包发布方法

    Eclipse Rich Client Platform (RCP) 是一个强大的框架,用于构建桌面应用程序。它提供了一整套工具和功能,使得开发者可以构建出具有丰富用户界面的应用。在开发完成后,我们需要将这些应用打包并发布,以便用户...

    eclipse RCP Plug-in开发自学教程.pdf

    eclipse RCP(Rich Client Platform)是一种基于eclipse的插件式开发平台,允许开发者使用eclipse结构风格设计弹性的可扩展的应用程序。RCP插件式开发方式可以重用eclipse中的方法和编码模式,提高开发效率和代码...

    EclipseRCP教程

    Eclipse RCP(Rich Client Platform)是一种基于 Eclipse 平台的客户端开发技术,能够帮助开发者快速构建功能强大且界面美观的桌面应用程序。在本教程中,我们将详细介绍 Eclipse RCP 的开发过程、技术要点和注意...

    Eclipse RCP中使用第三方包

    Eclipse RCP中使用第三方包 Eclipse RCP(Rich Client Platform)是一种基于Java的插件式软件架构,允许开发者创建跨平台的桌面应用程序。使用Eclipse RCP,可以快速构建功能强大的客户端应用程序。然而,在实际...

    eclipse rcp应用系统开发方法与实战源代码.zip

    Eclipse RCP,全称Eclipse Rich Client Platform,是一种基于Java的开源框架,用于构建桌面应用程序。它由Eclipse基金会维护,是Eclipse IDE的核心组成部分,提供了丰富的UI组件、插件系统以及工作台(Workbench)...

    Eclipse RCP(富客户端平台)开发中文语言包_3.6.0.rar

    Eclipse RCP(Rich Client Platform)是Eclipse IDE的一个核心组成部分,它提供了一个框架和工具集,用于构建桌面应用程序。Eclipse RCP允许开发者利用Java和SWT(Standard Widget Toolkit)构建功能丰富的、可定制...

    Eclipse RCP.pdf清晰版

    **Eclipse RCP**(Rich Client Platform)是一种构建丰富客户端应用程序的框架,它利用Eclipse平台的强大功能来创建高度定制化的桌面应用程序。通过RCP,开发者能够专注于业务逻辑而非繁琐的界面设计,极大地提高了...

    eclipse RCP mp3工程

    【描述】中的“非常棒的一个rcp应用程序”意味着这个工程展示了Eclipse RCP的强大功能和易用性,可能是通过集成MP3播放、管理、编辑等功能来实现的。"学习学习,快来下"则提示这个项目适合学习Eclipse RCP的开发者,...

    Eclipse Rcp

    Eclipse RCP是一种基于Eclipse平台的富客户端平台技术,它允许开发者创建独立于Eclipse环境的Java桌面应用程序。RCP通过提供一套标准组件和API,简化了桌面应用程序的开发流程,使开发者能够专注于业务逻辑而非界面...

    ECLIPSE+RCP应用系统开发方法与实战(PDF 高岗著)

    11. **实战项目**:书中很可能会包含一个或多个实际项目案例,引导读者一步步实现一个完整的Eclipse RCP应用,从而将理论知识转化为实践技能。 通过阅读这本书,开发者可以掌握Eclipse RCP的开发技巧,理解其设计...

    EclipseRcp 例子程序

    在“Eclipse RCP 例子程序”中,我们可能找到一系列的示例代码和项目,这些示例展示了如何利用Eclipse RCP的各种组件和机制来构建实际的应用。以下是一些关键的知识点: 1. **插件系统**:Eclipse RCP的核心是其...

    Eclipse RCP培训.zip

    Eclipse Rich Client Platform(RCP)是Eclipse框架下的一个核心组成部分,用于构建桌面应用程序。这个"Eclipse RCP培训.zip"文件很可能包含了关于如何开发基于Eclipse RCP的应用程序的各种教程、示例代码和讲解材料...

    Eclipse RCP 插件开发指南

    扩展点(Extension Point)是 Eclipse RCP 中用于定义插件之间交互的一种机制。通过定义扩展点,一个插件可以公开其部分功能供其他插件使用。扩展点通常在插件的 `plugin.xml` 文件中定义,其他插件可以通过贡献扩展...

    使用Eclipse RCP进行桌面程序开发

    #### 一、Eclipse RCP简介与快速起步 **Eclipse RCP** (Rich Client Platform) 是一种基于Java的开源框架,用于开发桌面应用程序。自从Eclipse 3.0版本以来,RCP逐渐成为构建高度定制化、功能丰富的桌面应用的标准...

    documents about Eclipse RCP

    Eclipse Rich Client Platform (RCP) 是一个强大的框架,用于构建桌面应用程序。它基于Java,由Eclipse基金会维护,是Eclipse IDE的核心组成部分。RCP允许开发者利用已有的插件系统构建可定制、模块化的应用,具有...

    Eclipse RCP开发详解

    Eclipse Rich Client Platform (RCP) 是一个强大的框架,用于构建桌面应用程序,它基于Java语言并利用了Eclipse IDE的核心技术。Eclipse RCP允许开发者创建功能丰富的、可扩展的应用程序,这些应用程序拥有与Eclipse...

    Eclipse RCP详细教程

    在Eclipse RCP中,应用程序是由一系列插件组成的,每个插件都可以独立地进行开发、部署和更新。 Eclipse RCP的核心特性之一是它的灵活性和可扩展性。这种灵活性体现在多个方面,例如通过插件机制可以轻松地添加新...

    Eclipse Rcp comon Navigator demo

    Common Navigator是Eclipse RCP中的一个重要组件,它提供了一种通用的资源浏览和管理界面。在本"Common Navigator demo"中,我们将深入探讨如何利用Eclipse RCP创建一个基于Common Navigator的简单应用,并了解如何...

    在Eclipse RCP中应用Spring OSGI 管理bean(一)

    标题中的“在Eclipse RCP中应用Spring OSGI 管理bean(一)”表明这是一篇关于如何在Eclipse Rich Client Platform (RCP)应用程序中集成Spring框架,并利用OSGi服务来管理Bean的教程。Eclipse RCP是一个用于构建桌面...

Global site tag (gtag.js) - Google Analytics