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

    项目中大致有三个编辑器Editor,我也只是写了最重要的 PatientInfoEditor
     
     
    一个完整的编辑器的开发过程:
    1.继承自EditorPart的PatientInfoEditor 类,主要内容如下:
    (1)定义一个用于显示信息的TableViewer
    (2)给TableViewer设置ContentProvider,LabelProvider以及Sorter
    (3)设置TableViewer的数据Input
    (4)设置编辑器的工具栏CoolBar上的按钮:这里将各个Action定义成了内部类,因为它们没有可复用性
    Action包括Add,Modify,Delete,Refresh,其中Delete和Refresh很简单,关键是Add和Modify,它们是通过打开一个Dialog来完成的,
    具体内容将在下节介绍
    为了避免误删除,要有提示:
     
    package com.yinger.patientims.editors; 

    import java.util.List;

    import org.eclipse.core.runtime.IProgressMonitor;
    import org.eclipse.jface.action.Action;
    import org.eclipse.jface.action.ToolBarManager;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.jface.viewers.IStructuredSelection;
    import org.eclipse.jface.viewers.TableViewer;
    import org.eclipse.jface.wizard.WizardDialog;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.custom.ViewForm;
    import org.eclipse.swt.events.SelectionAdapter;
    import org.eclipse.swt.events.SelectionEvent;
    import org.eclipse.swt.layout.FillLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Table;
    import org.eclipse.swt.widgets.TableColumn;
    import org.eclipse.swt.widgets.ToolBar;
    import org.eclipse.ui.IEditorInput;
    import org.eclipse.ui.IEditorSite;
    import org.eclipse.ui.PartInitException;
    import org.eclipse.ui.part.EditorPart;

    import com.yinger.patientims.Activator;
    import com.yinger.patientims.dao.PatientDAO;
    import com.yinger.patientims.editors.viewerSorter.PatientInfoSorter;
    import com.yinger.patientims.model.Patient;
    import com.yinger.patientims.sigleton.PatientFactory;
    import com.yinger.patientims.util.PluginUtil;
    import com.yinger.patientims.views.viewerProvider.PatientInfoTableViewerContentProvider;
    import com.yinger.patientims.views.viewerProvider.PatientInfoTableViewerLabelProvider;
    import com.yinger.patientims.wizards.AddPatientInfoWizard;

    public class PatientInfoEditor extends EditorPart {

      private PatientDAO patientDAO;

      // 一般查看器在哪个控件(类)里显示,这个类就要有一个相应的查看器的字段
      private TableViewer tableViewer;// 表格查看器
      private boolean sort;// 标识排序的方式

      @Override
      public void doSave(IProgressMonitor monitor) {
      }

      @Override
      public void doSaveAs() {
      }

      @Override
      // 这个方法要修改(编写)
      public void init(IEditorSite site, IEditorInput input) throws PartInitException {
        this.setSite(site);
        this.setInput(input);
      }

      @Override
      public boolean isDirty() {
        return false;
      }

      @Override
      public boolean isSaveAsAllowed() {
        return false;
      }

      @Override
      // 在这个方法中设置编辑器中要显示的内容
      public void createPartControl(Composite parent) {
        // 首先初始化一个PatientDAO
        patientDAO = new PatientDAO();

        // 首先创建一个ViewForm对象,它方便于控件的布局
        ViewForm viewForm = new ViewForm(parent, SWT.NONE);
        // 布局
        viewForm.setLayout(new FillLayout());
        // 创建TableViewer
        createTableViewer(viewForm);
        tableViewer.setContentProvider(new PatientInfoTableViewerContentProvider());
        tableViewer.setLabelProvider(new PatientInfoTableViewerLabelProvider());
        tableViewer.setInput(patientDAO.getPatientInfoList());
        tableViewer.setSorter(new PatientInfoSorter());

        // 添加编辑器的工具栏,包括了 修改,删除,刷新 三个按钮
        ToolBar toolBar = new ToolBar(viewForm, SWT.FLAT);
        ToolBarManager toolBarManager = new ToolBarManager(toolBar);
        toolBarManager.add(new AddPatientAction());
        toolBarManager.add(new DeletePatientAction());
        toolBarManager.add(new ModifyPatientAction());
        toolBarManager.add(new RefreshAction());
        toolBarManager.update(true);
        // This brings the underlying widgets up to date with any changes.

        // 设置viewform
        viewForm.setTopLeft(toolBar);
        viewForm.setContent(tableViewer.getControl());
      }

      private void createTableViewer(Composite composite) {
    //    tableViewer = new TableViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
        tableViewer = new TableViewer(composite, SWT.FULL_SELECTION);
        Table table = tableViewer.getTable();
        // 设置显示标题
        table.setHeaderVisible(true);
        // 设置显示表格线
        table.setLinesVisible(true);
        // 设置表格的布局 TableColumnLayout
        //TODO:重点注意下面的布局设置!不能有,它会导致很多问题,例如数组溢出,还有界面放大缩小出现
        //延迟!很多问题!
    //    table.setLayout(new TableColumnLayout());
        // 建立一列
        TableColumn tc1 = new TableColumn(table, SWT.LEFT);
        // 设置列标题
        tc1.setText("ID");
        // 设置列宽
        tc1.setWidth(60);
        // 添加排序器(列被点击时触发)
        // 注意:widgetSelected方法的末尾一定要refresh,这样可以保证不用手动刷新!
        // 还有,参数传一个SelectionAdapter就可以了!
        tc1.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -1 : 1);
            tableViewer.refresh();
          }
        });

        TableColumn tc2 = new TableColumn(table, SWT.LEFT);
        tc2.setText("Name");
        tc2.setWidth(100);
        tc2.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -2 : 2);
            tableViewer.refresh();
          }
        });

        TableColumn tc3 = new TableColumn(table, SWT.LEFT);
        tc3.setText("Sex");
        tc3.setWidth(60);
        tc3.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -3 : 3);
            tableViewer.refresh();
          }
        });

        TableColumn tc4 = new TableColumn(table, SWT.LEFT);
        tc4.setText("Age");
        tc4.setWidth(60);
        tc4.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -4 : 4);
            tableViewer.refresh();
          }
        });

        TableColumn tc5 = new TableColumn(table, SWT.LEFT);
        tc5.setText("Phone");
        tc5.setWidth(100);
        tc5.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -5 : 5);
            tableViewer.refresh();
          }
        });

        TableColumn tc6 = new TableColumn(table, SWT.LEFT);
        tc6.setText("Department");
        tc6.setWidth(100);
        tc6.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -6 : 6);
            tableViewer.refresh();
          }
        });

        TableColumn tc7 = new TableColumn(table, SWT.LEFT);
        tc7.setText("SickRoom");
        tc7.setWidth(80);
        tc7.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -7 : 7);
            tableViewer.refresh();
          }
        });

        TableColumn tc8 = new TableColumn(table, SWT.LEFT);
        tc8.setText("SickBed");
        tc8.setWidth(80);
        tc8.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -8 : 8);
            tableViewer.refresh();
          }
        });

        TableColumn tc9 = new TableColumn(table, SWT.LEFT);
        tc9.setText("Address");
        tc9.setWidth(100);
        tc9.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -9 : 9);
            tableViewer.refresh();
          }
        });

        TableColumn tc10 = new TableColumn(table, SWT.LEFT);
        tc10.setText("Login Time");
        tc10.setWidth(100);
        tc10.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            sort = !sort;
            ((PatientInfoSorter) tableViewer.getSorter()).doSort(sort ? -10 : 10);
            tableViewer.refresh();
          }
        });

      }

      @Override
      public void setFocus() {
      }

      // 注意:以下三个操作定义为内部类!
      // 原因是它们需要访问当前类的 TableViewer 对象,所以放在这个类里实现起来很方便!
      class ModifyPatientAction extends Action {
        public ModifyPatientAction() {
          // 设置提示文本
          this.setToolTipText("Modify Patient Information");
          // 设置图标
          this.setImageDescriptor(Activator.getImageDescriptor("/icons/Applications.ico"));
        }
        public void run() {
          IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
          Patient patient = (Patient) selection.getFirstElement();
          if (patient == null) {
            return;
          }
          // 调出 修改病人住院信息的dialog
          PatientFactory.setInstance(patient);

          //创建自定义的向导
          AddPatientInfoWizard wizard = new AddPatientInfoWizard();
          wizard.setType(PluginUtil.MODIFY);
          //设置向导中的patient是当前选中的patient
    //      wizard.setPatient(patient);//我想避免使用这些get和set
    //      PatientFactory.getInstance() = patient;//这样的代码不行!报错:左边不是变量
          //解决:在PatientFactory中添加一个setInstance方法
    //      
          //显示向导对话框
          WizardDialog dialog = new WizardDialog(Display.getDefault().getShells()[0], wizard);
          //设置对话框大小
          dialog.setPageSize(-1, 150);//注意:高度要足够的大,否则有些组件显示不出来
          //打开
          dialog.open();  
          //修改完成之后要刷新列表
          tableViewer.setInput(patientDAO.getPatientInfoList());
          tableViewer.refresh();
        }
      }

      class AddPatientAction extends Action {
        public AddPatientAction() {
          // 设置提示文本
          this.setToolTipText("Add Patient Information");
          // 设置图标
          this.setImageDescriptor(Activator.getImageDescriptor("/icons/small/add.gif"));
        }

        public void run() {
          // 调出 创建新的病人住院信息的dialog
          //创建自定义的向导
          AddPatientInfoWizard wizard = new AddPatientInfoWizard();
          wizard.setType(PluginUtil.ADD);
          //注意:每次打开向导页面时都要对PatientFactory的instance进行设置,不然会出现紊乱
    //      PatientFactory.setInstance(null);  //不能设置为null,不然后面的操作(判断操作类型,和设置值)
    //      PatientFactory.setInstance(new Patient());
          //显示向导对话框
          WizardDialog dialog = new WizardDialog(Display.getDefault().getShells()[0], wizard);
          //设置对话框大小
          dialog.setPageSize(-1, 150);//注意:高度要足够的大
          //打开
          dialog.open();
          //添加完成之后要刷新列表
    //      tableViewer.refresh();//这个方法不行!
          //还是得重新取出数据并刷新现实
          tableViewer.setInput(patientDAO.getPatientInfoList());
          tableViewer.refresh();
        }
      }

      class DeletePatientAction extends Action {

        public DeletePatientAction() {
          // 设置提示文本
          this.setToolTipText("Delete Patient Information");
          // 设置图标
          this.setImageDescriptor(Activator.getImageDescriptor("/icons/small/delete.gif"));
        }

        public void run() {
          IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
          Patient patient = (Patient) selection.getFirstElement();
          if (patient == null) {
            return;
          }
          if (MessageDialog.openConfirm(null, "Confirm to delete", "Are you sure to delete?")) {
            if (patientDAO.deletePatient(patient)) {
              @SuppressWarnings("unchecked")
              List<Patient> list = (List<Patient>) tableViewer.getInput();
              list.remove(patient);// 这里删除便于刷新时是最新的数据
              tableViewer.remove(patient);// 实时更新
            } else {//删除出错时提示
              MessageDialog.openInformation(null, "Error Information", "Fail to delete the Patient!");
            }
          }
        }

      }

      class RefreshAction extends Action {
        public RefreshAction() {
          // 设置提示文本
          this.setToolTipText("Refresh Patient Information");
          // 设置图标
          this.setImageDescriptor(Activator.getImageDescriptor("/icons/Refresh.ico"));
        }
        public void run() {
          tableViewer.setInput(patientDAO.getPatientInfoList());
          tableViewer.refresh();
        }
      }

    }
     
    2.编辑器的输入类EditorInput
    这个类只是简单的实现IEditorInput接口,同时实现getName和getTooltipText方法
    package com.yinger.patientims.editors.editorInput; 

    import org.eclipse.jface.resource.ImageDescriptor;
    import org.eclipse.ui.IEditorInput;
    import org.eclipse.ui.IPersistableElement;

    public class PatientInfoEditorInput implements IEditorInput {

      @Override
      public Object getAdapter(Class adapter) {
        return null;
      }

      @Override
      public boolean exists() {
        return false;
      }

      @Override
      public ImageDescriptor getImageDescriptor() {
        return null;
      }

      @Override
      public String getName() {
        return "Patient Information Management";
      }

      @Override
      public IPersistableElement getPersistable() {
        return null;
      }

      @Override
      public String getToolTipText() {
        return "Hospital Management/Patient Information Management";
      }

    }
     
    3.TabelViewer的内容和标签提供器
    内容提供器
    这里getElements方法写的不是很规范,可以参照上节内容
    package com.yinger.patientims.views.viewerProvider; 

    import java.util.List;

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

    /**
     * 记住,这里是一个TableViewer的内容提供器,一定要是实现IStructuredContentProvider接口
     * 而不是IContentProvider,IStructuredContentProvider接口中定义了getElements方法,这个
     * 方法是要实现的!将setInput时传入的list参数转换成Object数组
     */

    public class PatientInfoTableViewerContentProvider implements IStructuredContentProvider {

      @Override
      public Object[] getElements(Object inputElement) {
        return ((List)inputElement).toArray();
      }

      @Override
      public void dispose() {
      }

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

    }
     
    标签提供器
    需要注意的是Table有table的特点,实现getColumnText方法,给相应的列提供对应的文本
    package com.yinger.patientims.views.viewerProvider; 

    import org.eclipse.jface.viewers.ILabelProviderListener;
    import org.eclipse.jface.viewers.ITableLabelProvider;
    import org.eclipse.swt.graphics.Image;

    import com.yinger.patientims.model.Patient;

    public class PatientInfoTableViewerLabelProvider implements ITableLabelProvider {

      @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) {
      }

      @Override
      public Image getColumnImage(Object element, int columnIndex) {

        return null;
      }

      @Override//得到列中要显示的文本
      public String getColumnText(Object element, int columnIndex) {
        Patient patient = (Patient) element;
        switch (columnIndex) {//注意:列的索引是从0开始的
        case 0:
          return patient.getId().toString();
        case 1:
          return patient.getName();
        case 2:
          return patient.getSex();
        case 3:
          return patient.getAge()+"";
        case 4:
          return patient.getPhone();
        case 5:
          return patient.getDepartment().getName();
        case 6:
          return patient.getSickroom().getSickRoomNo()+"";
        case 7:
          return patient.getSickbed().getSickBedNo()+"";
        case 8:
          return patient.getAddress();
        case 9:
          return patient.getLogtime().toString();
    //    default:
    //      break;
        }
        return "";//默认返回空字符串
      }

    }
     
    整个流程的执行过程与上节类似
     
     
    4.还有一个重要的类:排序器,通过这个类可以实现对TableViewer的排序
    tableviewer通过调用doSort方法最终就可以调用到compare方法进行排序
    package com.yinger.patientims.editors.viewerSorter; 

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

    import com.yinger.patientims.model.Patient;
    /**
     * 表格查看器的排序器
     * 对于给定的列的索引进行排序
     * 
     * 我觉得有一个地方不好,那就是这里的数字!它固定了某一列就是在某列
     * 某一列的排序算法也是!还有就是这个compare方法太长了,过于复杂
     * ->可以在外部自定义一个类,用于设置列索引和排序方法的统一
     * 例如 IDASC=1 IDDSC=-1 
     */

    public class PatientInfoSorter extends ViewerSorter {

      private int column;

      public void doSort(int column) {
        this.column = column;
      }

      @Override // 处理排序的方法
      public int compare(Viewer viewer, Object e1, Object e2) {
        Patient patient1 = (Patient) e1;
        Patient patient2 = (Patient) e2;
        switch (column) {
        case 1:
          return patient2.getId().compareTo(patient1.getId());
        case -1:
          return patient1.getId().compareTo(patient2.getId());
        case 2:
          return patient2.getName().compareTo(patient1.getName());
        case -2:
          return patient1.getName().compareTo(patient2.getName());
        case 3:
          return patient2.getSex().compareTo(patient1.getSex());
        case -3:
          return patient1.getSex().compareTo(patient2.getSex());
        case 4:
          return (patient2.getAge() + "").compareTo(patient1.getAge() + "");
        case -4:
          return (patient1.getAge() + "").compareTo(patient2.getAge() + "");
        case 5:
          return patient2.getPhone().compareTo(patient1.getPhone());
        case -5:
          return patient1.getPhone().compareTo(patient2.getPhone());
        case 6:
          return patient2.getDepartment().getName().compareTo(patient1.getDepartment().getName());
        case -6:
          return patient1.getDepartment().getName().compareTo(patient2.getDepartment().getName());
        case 7:
          return (patient2.getSickroom().getSickRoomNo() + "").compareTo(patient1.getSickroom().getSickRoomNo() + "");
        case -7:
          return (patient1.getSickroom().getSickRoomNo() + "").compareTo(patient2.getSickroom().getSickRoomNo() + "");
        case 8:
          return (patient2.getSickbed().getSickBedNo() + "").compareTo(patient1.getSickbed().getSickBedNo() + "");
        case -8:
          return (patient1.getSickbed().getSickBedNo() + "").compareTo(patient2.getSickbed().getSickBedNo() + "");
        case 9:
          return patient2.getAddress().compareTo(patient1.getAddress());
        case -9:
          return patient1.getAddress().compareTo(patient2.getAddress());
        case 10:
          return patient2.getLogtime().compareTo(patient1.getLogtime());
        case -10:
          return patient1.getLogtime().compareTo(patient2.getLogtime());
        default:
          return 0;
        }
      }

    }
     
    5.其他的没有涉及的内容会在后面的内容中总结到...





  • 相关阅读:
    Largest Submatrix of All 1’s
    Max Sum of Max-K-sub-sequence
    Sticks Problem
    Splay模版
    B. Different Rules
    链表合并 leetcode
    K个一组翻转链表
    反转链表2 leetcode
    nodejs简单仿apache页面
    HTML 5 Web Workers
  • 原文地址:https://www.cnblogs.com/yinger/p/2255643.html
Copyright © 2011-2022 走看看