您的位置:首页 > 其它

RCP之病人信息系统开发总结(6):MVC模式之View层—编辑器

2011-11-19 23:25 471 查看
项目中大致有三个编辑器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.其他的没有涉及的内容会在后面的内容中总结到...

通过 Wiz 发布
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: