现在的位置: 首页 > 综合 > 正文

RCP之病人信息系统开发总结(2):项目结构分析和重要类分析

2012年12月21日 ⁄ 综合 ⁄ 共 14223字 ⁄ 字号 评论关闭
1.项目文档结构图
 
 
2.分析包 com.yinger.patientims中的类
 
(1)Activator 类
重要的方法:getImageDescriptor
package com.yinger.patientims; 

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
 * The activator class controls the plug-in life cycle
 * 这个类(激活器)继承自AbstractUIPlugin(抽象UI插件)
 * 它用来控制插件的生命周期,存储插件的全局信息
 * 它是一个单例类,是用来存储插件里其他类的一些静态功能函数的方便位置
 * 在整个插件的生命周期中,Eclipse只使用这个插件类的实例,并不创建其他的实例
 * 在通常情况下,插件类声明一个静态字段,用于引用这个唯一的实例
 * 所以在需要的时候它可以方便的被插件的各个地方所共享
 * 通常情况下这个类不需要改动
 */

public class Activator extends AbstractUIPlugin {

  // The plug-in ID
  public static final String PLUGIN_ID = "com.yinger.patientims"; //$NON-NLS-1$ //$NON-NLS-1$ 是用于国际化的,不能改动

  // The shared instance
  private static Activator plugin; //唯一的实例

  /**
   * The constructor
   */

  public Activator() {
  }

  /*
   * (non-Javadoc)
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
   */

  public void start(BundleContext context) throws Exception {
    super.start(context);
    plugin = this;
  }

  /*
   * (non-Javadoc)
   * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
   */

  public void stop(BundleContext context) throws Exception {
    plugin = null;
    super.stop(context);
  }

  /**
   * 得到唯一的实例
   * Returns the shared instance
   * @return the shared instance
   */

  public static Activator getDefault() {
    return plugin;
  }

  /**
   * 根据路径返回相对于插件类的ImageDescriptor,这个方法很重要
   * 很多时候设置图片或者ImageDescriptor都是调用这个方法
   * 有一个好处就是这种方法是采用相对路径得到的
   * 注意path的写法,如果是在项目下的icons目录中,应该是 /icons/XX.ico
   * Returns an image descriptor for the image file at the given plug-in relative path
   */

  public static ImageDescriptor getImageDescriptor(String path) {
//    AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, imageFilePath)
    return imageDescriptorFromPlugin(PLUGIN_ID, path);
  }
}

 
(2)Application类
可以在这个类中编写登录验证模块,详情见后文——对话框设计
package com.yinger.patientims; 

import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

import com.yinger.patientims.dialogs.LoginDialog;
import com.yinger.patientims.model.Doctor;
import com.yinger.patientims.util.DBUtil;

/**
 * This class controls all aspects of the application's execution
 * Application类是RCP应用程序的主程序类,相当于控制器,类似于Main()方法
 * 该类负责创建一个工作台(Workbench),并且与ApplicationWorkbenchAdvisor类连接
 * 该类实现了IApplication接口,启动RCP应用程序之后该类首先被加载。 如果系统需要登录,通常是在这个类中插入登录模块 通常情况下这个类不需要改动
 */

public class Application implements IApplication {

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
   * IApplicationContext)
   */

  public Object start(IApplicationContext context) throws Exception {
    Display display = PlatformUI.createDisplay(); // 创建Display对象
    try {
      // 启动之前先进行登录操作
      if (!login()) {
        return IApplication.EXIT_OK; // 没有登陆成功就正常退出
      }
      // 启动工作台,从而打开应用程序窗口
      int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
      if (returnCode == PlatformUI.RETURN_RESTART)
        return IApplication.EXIT_RESTART;
      else
        return IApplication.EXIT_OK;
    } finally {
      display.dispose();
    }

  }

  /*
   * (non-Javadoc)
   * 
   * @see org.eclipse.equinox.app.IApplication#stop()
   */

  public void stop() {
    if (!PlatformUI.isWorkbenchRunning())
      return;
    final IWorkbench workbench = PlatformUI.getWorkbench();
    final Display display = workbench.getDisplay();
    display.syncExec(new Runnable() {
      public void run() {
        if (!display.isDisposed()) // 关闭窗口之前先判断display是否被销毁了
          workbench.close();
      }
    });
  }

  // 登录验证
  public boolean login() {
    boolean flag = false;// 标志
    int tryCount = 0;//登录的次数
    while (!flag) {
      LoginDialog loginDialog = new LoginDialog(null);// null是可以的!
      Doctor doctor = new Doctor();
      loginDialog.setDoctor(doctor);// 这里很重要
      if (tryCount == 3) {//尝试登录了三次没有成功就退出
//        loginDialog.setErrorMessage("Wrong Login Information!");
        return false;
      }
      int res = loginDialog.open();// 注意,可能用户只是点击了关闭!
      if (res == IDialogConstants.ABORT_ID || res == IDialogConstants.CANCEL_ID) {
        return false; // 关闭或者退出了就直接退出程序
      }
      if (res == IDialogConstants.OK_ID) {// Dialog返回之前会设置好内部的doctor对象
        doctor = DBUtil.getLoginInfo(doctor);// 此时右边的doctor对象有了username和password
      }
      // doctor肯定不为null(每次都是new Doctor()),那么就要看doctor的属性
      if (doctor.getName() != null) {// 如果用户输入了name和password之后,但是信息无效就会提示这个或者用户直接点击了关闭登录
        // MessageDialog.openInformation(null,
        // "Error Information", "Wrong Login Information!");
        // loginDialog.setErrorMessage("Wrong Login Information!");
        flag = true;// 这种情况下才是登录成功,否则继续进行登录
      }else {
        tryCount++;
      }
    }
    return true;
  }

}

 
(3)ApplicationWorkbenchAdvisor 类
设置默认的透视图
package com.yinger.patientims; 

import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
/**
 * Public base class for configuring the workbench. 
 * 该类继承了WorkbenchAdvisor类,在主程序Application类中引用了ApplicationWorkbenchAdvisor类
 * WorkbenchAdvisor类主要用于配置工作台,它告诉工作台如何显示,显示什么信息
 * WorkbenchAdvisor类主要初始化默认的透视图和使用WorkbenchWindowAdvisor类
 * 
 * 重要方法:
 * 1.initialize(IWorkbenchConfigurer configurer):在工作台启动之前进行初始化
 * 2.openWindows():用于在启动时打开工作台窗体
 * 3.postShutdown():用于在所有窗口关闭之后,关闭工作台之前调用,用来保存当前的应用程序的状态,清除初始化方法创建的内容
 * 4.preShutdown():工作台将要关闭之前
 * 5.postStartup():用于在工作台窗口关闭之后,在主循环事件运行之前调用
 * 6.preStartup():用于在初始化结束之后,第一个窗口打开之前调用
 * 7.getDefaultPageInput():返回默认的输入
 * 8.getInitialWindowPerspectiveId():用于为新的工作台窗口返回透视图ID
 * 9.getMainPreferencePageId():返回首选项ID
 */

public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {

  private static final String PERSPECTIVE_ID = "com.yinger.patientims.perspective"; //$NON-NLS-1$

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

  public String getInitialWindowPerspectiveId() {
    return PERSPECTIVE_ID;
  }
}

 
(4)ApplicationWorkbenchWindowAdvisor 类
重要方法:preWindowOpen
可以在这个方法中设置各个组件的显示情况,同时可以设置整个程序的显示样式
package com.yinger.patientims; 

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.eclipse.ui.internal.util.PrefUtil;
/**
 * Public base class for configuring a workbench window. 
 * 该类继承了WorkbenchWindowAdvisor类,主要是对工作台窗口进行控制
 * 包括状态栏,工具栏,透视图栏,快速试图栏,窗口尺寸,标题等等
 * 该类还有一个重要的作用就是创建ActionBarAdvisor类
 * 这个类的方法在整个工作台的生命周期中起着重要作用
 *
 * 重要方法:
 * 1.createEmptyWindowContents(Composite composite):返回当窗口没有页面显示时要显示的控件
 * 2.createWindowContents(Shell shell):创建窗口内容
 * 3.getWindowConfigurer():返回工作台窗口配置
 * 4.openIntro():打开初始内容
 * 5.postWindowClose():在窗口关闭之后调用
 * 6.postWindowCreate():在窗口创建以后,打开之前调用 或者 窗口恢复到保存状态后,在执行postWindowRestor方法之后调用
 * 7.postWindowRestor():在窗口被恢复到保存状态之后,打开之前调用
 * 8.perWindowOpen():在窗口被打开之前调用
 * 9.preWindowShellClose():在窗口的Shell被关闭之前调用
 */

public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

  //这个构造方法在ApplicationWorkbenchAdvisor中调用的
    public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        super(configurer);
    }

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

    //这个方法是在窗口打开之前调用的,用来设置窗口的内容显示情况
    public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        //设置窗体的标题
        configurer.setTitle("Hospital Management System"); //$NON-NLS-1$
        //设置窗体的大小
        configurer.setInitialSize(new Point(800, 600));
        //设置菜单栏        
        configurer.setShowMenuBar(true);
        //设置工具栏
        configurer.setShowCoolBar(true);
        //设置状态线
        configurer.setShowStatusLine(true);
        //设置快速视图栏
        configurer.setShowFastViewBars(true);       

        //定制应用程序的外观
        IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
        //设置选项卡的样式,不是矩形的边框,而是弧形的
        preferenceStore.setValue(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS, false);
        //设置透视图按钮的位置,默认是左上角,改为放置在右上角
        preferenceStore.setValue(IWorkbenchPreferenceConstants.DOCK_PERSPECTIVE_BAR, IWorkbenchPreferenceConstants.TOP_RIGHT);

    }
}

 

 

(5)ApplicationActionBarAdvisor 类
在这个类中定义菜单栏和工具栏中的操作
package com.yinger.patientims; 

import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.actions.ContributionItemFactory;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;

import com.yinger.patientims.actions.OpenExpenseInfoViewAction;
import com.yinger.patientims.actions.OpenNavigatorViewAction;
import com.yinger.patientims.actions.OpenPatientInfoViewAction;
import com.yinger.patientims.actions.OpenSearchViewAction;

/**
 * Public base class for configuring the action bars of a workbench window.
 * 该类继承了ActionBarAdvisor类,负责创建RCP应用程序窗体的菜单,工具栏,状态栏等等 以及添加相应的操作
 * 
 * 重要的方法: 1.makeActions(IWorkbenchWindow window):填充方法 2.fillMenuBar(IMenuManager
 * menuBar):填充主菜单栏 3.fillCoolBar(ICoolBarManager coolBarManager):填充工具栏
 * 4.fillStatusLine(IStatusLineManager statusLineManager):填充状态栏
 * 5.isApplicationMenu():返回是否是给定窗体的给定菜单的ID的应用程序菜单
 */

public class ApplicationActionBarAdvisor extends ActionBarAdvisor {

  private IWorkbenchAction newWindowAction;
  private IWorkbenchAction exitAction;
  private IWorkbenchAction perspectiveAction;
  private IWorkbenchAction aboutAction;
  private IContributionItem showViewAction;
  private OpenNavigatorViewAction openNavigatorViewAction;
  private OpenPatientInfoViewAction openPatientInfoViewAction;
  private OpenExpenseInfoViewAction openExpenseInfoViewAction;
  private OpenSearchViewAction openSearchViewAction;
  private IWorkbenchAction preferenceAction;

  // 这个构造方法在 ApplicationWorkbenchWindowAdvisor类中调用
  public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
    super(configurer);
  }

  // 这个方法很重要,用于设置窗体中的操作
  protected void makeActions(IWorkbenchWindow window) {
    // ActionFactory:工作台操作工厂对象 Access to standard actions provided by
    // the workbench.
    // ActionFactory.OPEN_NEW_WINDOW :具体化了的用于创建“新建窗口”操作的操作工厂对象
    // 定义“新建窗口”操作
    newWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window);
    newWindowAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_DEF_VIEW));
    // 注册操作
    register(newWindowAction);

    // 定义“退出”操作
    exitAction = ActionFactory.QUIT.create(window);
    exitAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
    register(exitAction);

    // 定义“打开透视图”操作
    perspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG.create(window);
    register(perspectiveAction);

    // 定义“关于”操作
    aboutAction = ActionFactory.ABOUT.create(window);
//    aboutAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
    aboutAction.setImageDescriptor(Activator.getImageDescriptor("/icons/small/about.gif"));
    register(aboutAction);

    // 定义“显示视图列表”操作
    showViewAction = ContributionItemFactory.VIEWS_SHORTLIST.create(window);
//    ((IAction) showViewAction).setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_ELEMENT));
    // register(showViewAction); //注意,这类视图不用注册,register方法会报错!

    // 定义打开“首选项”操作
    preferenceAction = ActionFactory.PREFERENCES.create(window);
//    preferenceAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_HOME_NAV));
    preferenceAction.setImageDescriptor(Activator.getImageDescriptor("/icons/Home.ico"));
    register(preferenceAction);

    // 自定义的操作类,分别用来打开相应的视图
    openNavigatorViewAction = new OpenNavigatorViewAction(window);
    openExpenseInfoViewAction = new OpenExpenseInfoViewAction(window);
    openPatientInfoViewAction = new OpenPatientInfoViewAction(window);
    openSearchViewAction = new OpenSearchViewAction(window);
  }

  protected void fillMenuBar(IMenuManager menuBar) {
    // IWorkbenchActionConstants:Action ids for standard actions, groups
    // in the workbench menu bar, and global actions.
    // 定义File菜单
    MenuManager fileManager = new MenuManager("&File", IWorkbenchActionConstants.M_FILE);
    // 在File菜单中添加退出菜单项
    fileManager.add(exitAction);
    // 添加File菜单到菜单栏
    menuBar.add(fileManager);

    // Window菜单
    MenuManager windowManager = new MenuManager("&Window", IWorkbenchActionConstants.M_WINDOW);
    windowManager.add(newWindowAction);
    windowManager.add(perspectiveAction);
    windowManager.add(preferenceAction);
    // Window菜单的子菜单Show View菜单,创建二级菜单
    MenuManager showViewManager = new MenuManager("&Show View", "showView");
//    showViewManager.add(openExpenseInfoViewAction);
//    showViewManager.add(openNavigatorViewAction);
//    showViewManager.add(openPatientInfoViewAction);
//    showViewManager.add(openSearchViewAction);
    // 包含一个“other”,用于打开未显示的视图
    //TODO:很奇怪的是 show view会自己显示一部分的view,这些view是当前的窗口已经显示出来的view
    showViewManager.add(showViewAction);
    windowManager.add(showViewManager);
    menuBar.add(windowManager);

    // Help菜单
    MenuManager helpManager = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP);
    helpManager.add(aboutAction);
    menuBar.add(helpManager);
  }

  @Override
  protected void fillCoolBar(ICoolBarManager coolBar) {
    // Creates a tool bar manager with the given SWT [button style]
    IToolBarManager toolbar1 = new ToolBarManager(coolBar.getStyle());
    // 在这个toolbar上面添加一个操作按钮
    toolbar1.add(openNavigatorViewAction);
    // 把这个toolbar添加到coolbar上面
    coolBar.add(toolbar1);

    IToolBarManager toolbar2 = new ToolBarManager(coolBar.getStyle());
    toolbar2.add(openSearchViewAction);
    coolBar.add(toolbar2);

    IToolBarManager toolbar3 = new ToolBarManager(coolBar.getStyle());
    toolbar3.add(perspectiveAction);
    coolBar.add(toolbar3);

  }

}

 

抱歉!评论已关闭.