`
derekop
  • 浏览: 22882 次
  • 性别: 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` 文件中定义,其他插件可以通过贡献扩展...

    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是一个用于构建桌面...

    eclipse rcp check table

    `CheckTableViewDemo.java`可能是演示如何在Eclipse RCP应用中创建和使用检查表的一个示例代码。在这个文件中,我们可以期待看到关于如何创建自定义表视图、添加复选框列以及处理用户选择事件的相关代码。开发者可能...

Global site tag (gtag.js) - Google Analytics