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.其他的类或者方法会在后面的相关部分中涉及,例如编辑器的输入类会在编辑器中涉及
其他视图根据需求设计它们的界面





原文地址:https://www.cnblogs.com/yinger/p/2255642.html