zoukankan      html  css  js  c++  java
  • RCP之病人信息系统开发总结(5):MVC模式之View层—视图

    项目中大致有四个视图,我只写了其中一个很重要的导航视图
     
     
     
    一个完整的导航视图开发过程:
    1.继承自ViewPart类的NavigatorView类,主要内容如下:
    (1)定义一个树查看器 TreeViewer
    (2)给TreeViewer设置ContentProvider和LabelProvider
    (3)设置TreeViewer的数据Input
    (4)设置视图上的工具栏CoolBar和菜单栏MenuBar
     
    package com.yinger.patientims.views; 

    import org.eclipse.jface.action.IMenuManager;
    import org.eclipse.jface.action.IToolBarManager;
    import org.eclipse.jface.viewers.DoubleClickEvent;
    import org.eclipse.jface.viewers.IDoubleClickListener;
    import org.eclipse.jface.viewers.ISelection;
    import org.eclipse.jface.viewers.IStructuredSelection;
    import org.eclipse.jface.viewers.TreeViewer;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.ui.IActionBars;
    import org.eclipse.ui.IEditorInput;
    import org.eclipse.ui.IEditorPart;
    import org.eclipse.ui.IWorkbenchPage;
    import org.eclipse.ui.part.DrillDownAdapter;
    import org.eclipse.ui.part.ViewPart;

    import com.yinger.patientims.actions.OpenSearchViewAction;
    import com.yinger.patientims.navigator.NavigatorEntityElement;
    import com.yinger.patientims.navigator.NavigatorEntityFactory;
    import com.yinger.patientims.util.PluginUtil;
    import com.yinger.patientims.views.viewerProvider.NavigatorTreeViewerContentProvider;
    import com.yinger.patientims.views.viewerProvider.NavigatorTreeViewerLabelProvider;

    /**
     * 导航视图
     * 
     */

    public class NavigatorView extends ViewPart {

      private TreeViewer treeViewer; // 树查看器

      @Override
      public void createPartControl(Composite parent) {
        // 创建树查看器
        treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
        // 设置内容提供其和标签提供器
        treeViewer.setContentProvider(new NavigatorTreeViewerContentProvider());
        treeViewer.setLabelProvider(new NavigatorTreeViewerLabelProvider());
        // 读入数据
        treeViewer.setInput(NavigatorEntityFactory.setNavigatorEntity());
        // 自定义的方法
        // 设置视图的工具栏
        setViewToolBar();
        // 自定义的方法,实现双击打开相应的编辑器的功能
        hookDoubleClickAction();
      }

      // 这个方法实际上就是给treeviewer添加了一个处理双击事件的监听器
      private void hookDoubleClickAction() {
        treeViewer.addDoubleClickListener(new IDoubleClickListener() {
          @Override
          public void doubleClick(DoubleClickEvent event) {
            ISelection selection = treeViewer.getSelection();
            // 得到选中的项,注意方法是将得到的选项转换成 IStructuredSelection,再调用 getFirstElement 方法
            Object object = ((IStructuredSelection) selection).getFirstElement();
            // 再将对象转为实际的树节点对象
            NavigatorEntityElement element = (NavigatorEntityElement) object;
            // 得到该对象的editorInput
            IEditorInput editorInput = element.getEditorInput();
            // 得到当前工作台的page
            IWorkbenchPage workbenchPage = getViewSite().getPage();
            // 如果点击的是 信息查询
            if (element.getName().equals("Information Search")) {
              new OpenSearchViewAction(getSite().getWorkbenchWindow()).run();
              return;
            }
            String editorID = null;
            // 这里要结合NavigatorEntityFactory类的setNavigatorEntity方法
            // 这一部分对原书作了修改,化繁为简
            if (element.getName().equals("Patient Information")) {// 病人信息管理
              editorID = PluginUtil.PatientInfoEditor_ID;
            }else if (element.getName().equals("Diagnose Information")) {// 诊断信息管理
              editorID = PluginUtil.DiagnoseInfoEditor_ID;
            }else if (element.getName().equals("Expense Information")) {// 费用信息管理
              editorID = PluginUtil.ExpenseInfoEditor_ID;
            }else{
              return;
            }
            //IEditorPart:An editor is a visual component within a workbench page.
            IEditorPart editorPart = workbenchPage.findEditor(editorInput);
            if(editorPart != null){//已经打开了所需的编辑器
              workbenchPage.bringToTop(editorPart);
            }else {//没有打开就打开来
              try {
                editorPart = workbenchPage.openEditor(editorInput, editorID);
              } catch (Exception e) {
                e.printStackTrace();
              }
            }
          }
        });
      }

      private void setViewToolBar() {
        // IActionBars:Used by a part to access its menu, toolbar, and
        // status line managers.
        IActionBars bars = getViewSite().getActionBars();
        // 定义工具栏
        IToolBarManager toolBarManager = bars.getToolBarManager();
        // 定义下拉菜单栏
        IMenuManager menuManager = bars.getMenuManager();
        // DrillDownAdapter:Implements a simple web style navigation
        // metaphor for a TreeViewer. Home, back,
        // and "drill into" functions are supported for the viewer,
        DrillDownAdapter drillDownAdapter = new DrillDownAdapter(treeViewer);
        // 为工具栏添加“goHome”,“goBack”,“goInto”操作
        drillDownAdapter.addNavigationActions(menuManager);
        // 为菜单栏添加“goHome”,“goBack”,“goInto”操作
        drillDownAdapter.addNavigationActions(toolBarManager);
      }

      @Override
      public void setFocus() {

      }

    }
     
    2.树结构的各个类
     
    接口ITreeElement
    package com.yinger.patientims.navigator; 

    import java.util.List;

    /**
     * 定义导航视图内部的节点的接口
     * 
     * 我觉得不好的地方就是没在这里是用泛型机制!
     */

    public interface ITreeElement {

      public void setName(String name);

      public String getName();

      public void setChildren(List children);

      public List getChildren();

      public boolean hasChildren();

      public void addChildren(ITreeElement iElement);

    }
     
    树节点实现类:NavigatorEntityElement 类
    package com.yinger.patientims.navigator; 

    import java.util.ArrayList;
    import java.util.List;

    import org.eclipse.ui.IEditorInput;

    /**
     * 实现了导航视图内部的节点的接口ITreeElement
     * 
     * 我个人感觉可以定义一个int变量,表示这个element节点的level![OK!我已经实现了]
     */

    public class NavigatorEntityElement implements ITreeElement {

      private String name;// 节点名称
      private int level = 0;// 节点深度,0表示根节点,是默认值
      private List children = new ArrayList();// 节点孩子
      private IEditorInput editorInput;// 节点的IEditorInput对象
      //IEditorInput是新增的,在接口中没有定义,它在元素上绑定一个editor,这样就可以知道双击这个节点需要打开的editor

      public NavigatorEntityElement() {

      }

      public NavigatorEntityElement(String name) {
        this.name = name;
      }

      public NavigatorEntityElement(int level, String name) {
        this(name);
        this.level = level;
      }

      public int getLevel() {
        return level;
      }

      public void setLevel(int level) {
        this.level = level;
      }

      public IEditorInput getEditorInput() {
        return editorInput;
      }

      public void setEditorInput(IEditorInput editorInput) {
        this.editorInput = editorInput;
      }

      @Override
      public void setName(String name) {
        this.name = name;
      }

      @Override
      public String getName() {
        return name;
      }

      @Override
      public void setChildren(List children) {
        this.children = children;
      }

      @Override
      public List getChildren() {
        return children;
      }

      @Override
      public boolean hasChildren() {
        if (children.size() > 0) {
          return true;
        }
        return false;
      }

      @Override
      public void addChildren(ITreeElement iElement) {
        children.add(iElement);
      }

    }
     
    树结构的类NavigatorEntityFactory 类
    package com.yinger.patientims.navigator; 

    import java.util.ArrayList;
    import java.util.List;

    import com.yinger.patientims.editors.editorInput.DiagnoseInfoEditorInput;
    import com.yinger.patientims.editors.editorInput.ExpenseInfoEditorInput;
    import com.yinger.patientims.editors.editorInput.PatientInfoEditorInput;
    /**
     * 这个工厂类主要任务就是负责设置在导航视图中要显示的TreeViewer中的节点元素
     * 实体工厂类将实体类中的各个节点数据关联起来,起到统筹的作用
     */

    public class NavigatorEntityFactory {

      public static Object setNavigatorEntity() {
        /**
         * 这里涉及到一个统一化的问题,有些String在其他的地方引用了,不便于修改!
         * 保存起来?!
         */


        // Level one 一级节点
        NavigatorEntityElement root1 = new NavigatorEntityElement(0, "Hospital Management");
        NavigatorEntityElement root2 = new NavigatorEntityElement(0, "Expense Management");
        NavigatorEntityElement root3 = new NavigatorEntityElement(0, "Information Search");

        // level two 二级节点
        NavigatorEntityElement element1 = new NavigatorEntityElement(1, "Patient Information");
        NavigatorEntityElement element2 = new NavigatorEntityElement(1, "Diagnose Information");
        NavigatorEntityElement element3 = new NavigatorEntityElement(1, "Expense Information");

        // 将下级节点添加到上级
        root1.addChildren(element1);
        root1.addChildren(element2);
        root2.addChildren(element3);

        // 设置编辑器
        element1.setEditorInput(new PatientInfoEditorInput());
        element2.setEditorInput(new DiagnoseInfoEditorInput());
        element3.setEditorInput(new ExpenseInfoEditorInput());

        // 要返回的list
        List list = new ArrayList();
        list.add(root1);
        list.add(root2);
        list.add(root3);
        return list;
      }
    }
     
    3.树的内容提供器ContentProvider和标签提供器LabelProvider
     
    内容提供器:类NavigatorTreeViewerContentProvider
    package com.yinger.patientims.views.viewerProvider; 

    import java.util.List;

    import org.eclipse.jface.viewers.ITreeContentProvider;
    import org.eclipse.jface.viewers.Viewer;

    import com.yinger.patientims.navigator.ITreeElement;
    /**
     * 导航视图中的TreeViewer的内容提供器
     * 
     * 内容提供器提供的是查看器的内容,也就是查看器中的元素是什么对象
     * 注意:TreeViewer的内容提供器要实现的接口是ITreeContentProvider,而不是IContentProvider
     * IContentProvider接口提供了基本的生存期协议,用于将内容提供器与输入元素进行关联
     * 以及处理输入元素的更改
     * 
     * 通常,内容提供器知道如何在输入元素和期望的查看器内容之间进行映射
     * 
     */

    public class NavigatorTreeViewerContentProvider implements ITreeContentProvider {

      public NavigatorTreeViewerContentProvider(){
        //最好是写上一个默认的构造器
      }

      @Override
      public void dispose() {

      }

      @Override
      public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

      }

      @Override//当输入是设定的元素时,返回查看器中显示的元素
      public Object[] getElements(Object inputElement) {
        if (inputElement instanceof List) {
          return ((List) inputElement).toArray();
        }else{
          return new Object[0];//为什么在不是list的时候要返回的是一个空的Object数组呢?
        }
      }

      @Override//得到指定父元素的子元素
      public Object[] getChildren(Object parentElement) {
        ITreeElement treeElement = (ITreeElement)parentElement;
        List children = treeElement.getChildren();
        if(children == null || children.isEmpty()){
          return new Object[0];
        }else{
          return children.toArray();
        }
      }

      @Override//没有去实现
      public Object getParent(Object element) {
        return null;
      }

      @Override//是否有子节点
      public boolean hasChildren(Object element) {
        ITreeElement treeElement = (ITreeElement)element;
        List children = treeElement.getChildren();
        if(children == null || children.isEmpty()){
          return false;
        }else{
          return true;
        }
      }

    }
     
    标签提供器 :NavigatorTreeViewerLabelProvider 类
    package com.yinger.patientims.views.viewerProvider; 

    import org.eclipse.jface.viewers.ILabelProvider;
    import org.eclipse.jface.viewers.ILabelProviderListener;
    import org.eclipse.swt.graphics.Image;
    import org.eclipse.ui.ISharedImages;
    import org.eclipse.ui.PlatformUI;

    import com.yinger.patientims.navigator.NavigatorEntityElement;

    /**
     * 导航视图中TreeViewer的标签提供器 
     * 
     * 标签提供器提供的是用于显示的文本或者图片
     * 注意:TreeViewer的标签提供器最好是实现ILabelProvider,而不是IBaseLabelProvider
     * 
     * 标签提供器可以帮助保存图标资源,因为它可以确保图标的相同实例用于查看器中所有的相似类型
     */

    public class NavigatorTreeViewerLabelProvider implements ILabelProvider {

      public NavigatorTreeViewerLabelProvider(){
        //最好是写上一个默认的构造器
      }

      @Override
      public void addListener(ILabelProviderListener listener) {

      }

      @Override
      public void dispose() {

      }

      @Override
      public boolean isLabelProperty(Object element, String property) {
        return false;
      }

      @Override
      public void removeListener(ILabelProviderListener listener) {

      }

      //重点:学会得到系统提供的图片的方法:PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.XX)
      @Override//要显示的图片
      public Image getImage(Object element) {
        String image1 = ISharedImages.IMG_OBJ_FOLDER;
        String image2 = ISharedImages.IMG_OBJ_FILE;
        NavigatorEntityElement entityElement = (NavigatorEntityElement) element;
        if(entityElement.hasChildren()){
          return PlatformUI.getWorkbench().getSharedImages().getImage(image1);
        }else{
          return PlatformUI.getWorkbench().getSharedImages().getImage(image2);
        }
      }

      @Override//要显示的文本
      public String getText(Object element) {
        NavigatorEntityElement entityElement = (NavigatorEntityElement) element;
        return entityElement.getName();
      }

    }
     
    整个过程的执行流程图
     
     
    4.其他的类或者方法会在后面的相关部分中涉及,例如编辑器的输入类会在编辑器中涉及
    其他视图根据需求设计它们的界面





  • 相关阅读:
    转发 微博 Qzone 微信 草根创业英雄时代落幕:贾跃亭戴威们一去不复返
    python 发送大Json格式数据
    python post json数据
    python post 参数
    IntelliJ Idea 常用10款插件(提高开发效率)
    IDEA操作技巧:一些常用且实用的插件
    nacos
    Sentinel 与 Hystrix 的对比
    阿里启动新项目:Nacos,比 Eureka 更强!
    D3.js学习(一)
  • 原文地址:https://www.cnblogs.com/yinger/p/2255642.html
Copyright © 2011-2022 走看看