作者:梁祺 (eclipsesbs@gmail.com)
来自:http://www.benisoft.net/day9/index.html
WizardDialog称为向导对话框,当用户需要输入大量信息时,向导对话框可以循序渐进地引导用户, 使得用户在每一个向导对话框页面里只需要专注于输入少量信息。并且向导对话框可以根据用户的输入, 判断用户是否完成了该页面,决定下一个向导对话框页面。 由于向导对话框是用于帮助用户输入大量且复杂的信息,它本身就很复杂,所以它非常需要仔细的设计, 经验表明,一个设计不合理的向导对话框是很难通过后期修改来完全满足需求,往往需要重新设计。
在Itinerary的例子里,我们需要一个向导对话框来创建行程活动Itinerary Item。行程活动有三种, 交通(Transportation),住宿(Accommodation),和观光(Activity)。 我们不希望用三个独立的对话框来分别创建它们,而是用一个向导对话框。这个向导对话框有三页, 第一页选择活动类型,交通,住宿,还是观光;根据第一页中选择的内容, 用户在第二页输入交通,住宿或观光的详细内容;第三页输入该行程活动的备注信息。
创建向导对话框,首先创建继承自Wizard的NewItineraryItemWizard类, Wizard主要提供向导对话框所要处理的数据对象,并且控制所有向导对话框页面。 其次就是创建一系列继承自WizardPage的向导对话框页面类。
- NewItineraryItemWizard:保存向导对话框所要处理的数据对象,并且控制向导对话框页面
- NewItineraryItemTypeWizardPage:第一页,选择行程活动类型
- NewItineraryItemTransportationWizardPage:第二页,输入交通信息
- NewItineraryItemAccommodationWizardPage:第二页,输入住宿信息
- NewItineraryItemActivityWizardPage:第二页,输入观光信息
- NewItineraryItemDescriptionWizardPage:第三页,输入备注信息
用户选择主菜单的"Itinerary -> New Itinerary Item",会调用NewItineraryItemAction。 在这个Action类的run()中,先创建一个NewItineraryItemWizard对象,然后将该对象交给WizardDialog的构造函数, 最后调用WizardDialog.open()方法打开对话框。
WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
if (Window.OK == dialog.open()) {
// OK
}
NewItineraryItemWizard负责实例化所有的WizardPage,并调用addPage()把它们加到Wizard维护的页面列表中。 这里的WizardPage成员变量命名比较偷懒,但也一目了然,page2A,page2B,page2C就是第二页的三个可能的页面。
private NewItineraryItemTypeWizardPage page1;
private NewItineraryItemTransportationWizardPage page2A;
private NewItineraryItemAccommodationWizardPage page2B;
private NewItineraryItemActivityWizardPage page2C;
private NewItineraryItemDescriptionWizardPage page3;
public NewItineraryItemWizard() {
page1 = new NewItineraryItemTypeWizardPage("page.type");
addPage(page1);
page2A = new NewItineraryItemTransportationWizardPage("page.transportation");
addPage(page2A);
page2B = new NewItineraryItemAccommodationWizardPage("page.accommodation");
addPage(page2B);
page2C = new NewItineraryItemActivityWizardPage("page.activity");
addPage(page2C);
page3 = new NewItineraryItemDescriptionWizardPage("page.description");
addPage(page3);
}
当用户在第一页中选择了交通,住宿或者观光后,Wizard就知道第二页该使用哪个页面了。 getNextPage()和getPreviousPage()类似,都是根据当前页面以及行程活动类型来确定下一页或者上一页。
if (page == page1) {
String type = page1.getType();
if (type.equals("transportation")) {
return page2A;
} else if (type.equals("accommodation")) {
return page2B;
} else {
return page2C;
}
} else if (page == page2A || page == page2B || page == page2C) {
return page3;
}
return null;
}
接下来是WizardPage,也是代码量最多的地方。WizardPage主要负责提供界面与用户交互,检查用户的输入, 获取用户输入的数据。这个和普通的对话框没有什么区别。第一个NewItineraryItemTypeWizardPage非常简单, 只有一个Combo控件,用来选择行程活动的类型,也不需要检查输入。
第二页我们以NewItineraryItemTransportationWizardPage为例。这里我们需要检查一些必须输入的域, 其中我们还需要检查航班出发和到达时间的格式,如果没有输入或者输入格式不正确, WizardPage的标题区域会先显示红色的错误提示。
为了实时检查用户输入,我们需要为每个控件添加事件接收器,以便在控件内容改变时能接收到事件,实时检查输入的合法性。 一般文本控件可以使用ModifyListener,Combo控件可以使用SelectionListener。当收到事件时, 我们调用isInputValid()来检查控件里的用户输入,如果输入合法,isInputValid()返回true, 并调用setPageComplete()来告诉WizardPage,当前页已完成。
@Override
public void modifyText(ModifyEvent e) {
setPageComplete(isInputValid());
}};
textNumber.addModifyListener(listener);
textDepartureTime.addModifyListener(listener);
textDepartureStation.addModifyListener(listener);
textArrivalTime.addModifyListener(listener);
textArrivalStation.addModifyListener(listener);
这里简单看一下isInputValid(),每个输入项都有自己的合法性要求,如果不合法,调用setErrorMessage(), 设置错误消息提示用户,并返回false。如果所以输入项都合法,调用setErrorMessage(null)清除错误消息, 返回true。
if (comboType.getText().isEmpty()) {
this.setErrorMessage("Input transportation type.");
return false;
}
if (textNumber.getText().isEmpty()) {
this.setErrorMessage("Input " + comboType.getText().toLowerCase() + " number.");
return false;
}
if (! textDepartureTime.getText().isEmpty()) {
Date date = getValidDate(textDepartureTime.getText());
if (date == null) {
this.setErrorMessage("Input departure time in format yyyy-MM-dd HH:mm.");
return false;
}
}
...
this.setErrorMessage(null);
transportation = new Transportation();
transportation.setTransportationType(getType());
transportation.setNumber(textNumber.getText());
transportation.setDepartureTime(getValidDate(textDepartureTime.getText()));
transportation.setDeparturePlace(textDepartureStation.getText());
transportation.setArrivalTime(getValidDate(textArrivalTime.getText()));
transportation.setArrivalPlace(textArrivalStation.getText());
transportation.setDescription(textDescription.getText());
return true;
只有当调用setPageComplete(true)后,用户才可以点击Next进入下一页,或者点击Finish按钮完成整个向导对话框。 在上面这个例子里,第一页和第二页是必须的,第三页是可选的,所以第一页的Finish按钮非活动状态,不能点, 第二页和第三页Finish按钮处于活动状态。为了定制Finish按钮的行为,我们需要重载Wizard的canFinish()方法, 如果必选页都处于完成状态,向导对话框就可以Finish。
String type = page1.getType();
if (type.equals("transportation")) {
return page1.isPageComplete() && page2A.isPageComplete();
} else if (type.equals("accommodation")) {
return page1.isPageComplete() && page2B.isPageComplete();
} else {
return page1.isPageComplete() && page2C.isPageComplete();
}
}
第三页是可选页,比较简单,就不纍述了。
这里小结一下,为了开发一个逻辑清晰并具有良好用户体验的向导对话框:
- 仔细设计每个向导页面,包括页面的个数,每个页面是可选还是必选,每个页面的布局等;
- 在createControl()方法里布局页面控件
- 为需要输入检查的控件添加事件接收器以检查输入合法性,并调用isPageComplete()设置页面完成与否;
- 继承Wizard.canFinish()来定制Finish按钮活动与否,以便用户可以提前结束向导对话框。
应该讲向导对话框的工作量是非常巨大的,测试工作也很耗时,开发过程中遇到很多Bug也很常见。
相关推荐
* Ctrl+K:超级链接 * Ctrl+N:新建图形文件 * Ctrl+M:打开选项对话框 对象操作 * Ctrl+A:排列 * Ctrl+E:窗口缩放显示整个图形 * Ctrl+L:删除物体 * Ctrl+V:粘贴剪贴板上的内容 * Ctrl+X:剪切所选择的内容 *...
9. Alt+F8:打开“宏”对话框。 10. Alt+F11:打开VB编辑器。 11. Alt+Enter:在单元格内强制换行。 12. Ctrl+Enter:使用当前输入项填充选定的单元格区域。 13. Shift+Enter:活动单元格上移。 14. Tab:活动单元格...
CAD软件常用命令、快捷键和命令说明大全 在CAD软件操作中,为了方便用户,利用快捷键代替鼠标 clicks,可以利用键盘快捷键发出命令,完成绘图、修改、保存等操作。这些命令键就是CAD快捷键...* 显示第一个工具条【 】
AutoCAD 快捷键大全 AutoCAD 是一个功能强大且广泛应用的计算机辅助设计(CAD)软件,提供了大量的快捷键来提高用户的工作效率。下面是 AutoCAD 快捷键大全,涵盖了常用的快捷键、...* 显示第一个工具条 【Alt】+【1】
- Ctrl+K: 创建超级链接 - Ctrl+N: 新建图形文件 - Ctrl+M: 打开选项对话框 - Ctrl+1: 打开特性对话框 - Ctrl+2: 打开图像资源管理器 - Ctrl+6: 打开图像数据原子 - Ctrl+O: 打开图形文件 - Ctrl+P: 打开...
* Ctrl+K:超级链接 * Ctrl+N:新建图形文件 * Ctrl+O:打开图象文件 * Ctrl+P:打开打印对话框 * Ctrl+S:保存文件 * Ctrl+U:极轴模式控制(F10) * Ctrl+V:粘贴剪贴板上的内容 * Ctrl+W:对象追踪式控制(F11) ...
* Ctrl+K: 超级链接 * Ctrl+N: 新建图形文件 * Ctrl+M: 打开选项对话框 * Ctrl+1: 打开特性对话框 * Ctrl+2: 打开图象资源管理器 * Ctrl+6: 打开图象数据原子 * Ctrl+O: 打开图象文件 * Ctrl+P: 打开打印对说框 * ...
在Windows操作系统中,"超级管理员权限"通常被称为"管理员权限",这是系统中最高级别的用户权限,允许执行对系统有深远影响的操作。当一个程序或脚本需要超级管理员权限时,意味着它可能涉及到修改系统核心文件、...
Windows 7中的"超级终端"(HyperTRM)是一款基于旧版Windows操作系统(如Windows 9x和Windows XP)的"通信控制程序"(Terminal)的现代化版本。它是一个集成的命令行接口工具,允许用户通过串口、调制解调器或网络...
* CTRL+K:超级链接 * CTRL+N:新建图形文件 * CTRL+M:打开选项对话框 * CTRL+O:打开图象文件 * CTRL+P:打开打印对话框 * CTRL+S:保存文件 * CTRL+U:极轴模式控制 * CTRL+V:粘贴剪贴板上的内容 * CTRL+W:对象...
* Ctrl+K: 超级链接 * Ctrl+N: 新建图形文件 * Ctrl+M: 打开选项对话框 * Ctrl+1: 打开特性对话框 * Ctrl+2: 打开图象资源管理器 * Ctrl+6: 打开图象数据原子 * Ctrl+O: 打开图象文件 * Ctrl+P: 打开打印对话框 * ...
9. Ctrl+M:打开选项对话框,自定义CAD设置。 10. Ctrl+1:打开特性对话框,查看和修改对象属性。 11. Ctrl+2:打开图象资源管理器,管理图形资源。 12. Ctrl+6:打开图象数据原子,查看或编辑图形信息。 13. Ctrl+O...
11. **搜索和替换对话框**:自定义对话框提供更灵活的搜索选项,如正则表达式搜索,可以使用VB的`Form`控件和`InputBox`来实现。 12. **编码选择**:支持不同字符编码(如ASCII、UTF-8、GBK等)的读取和保存,VB...
9. **数据绑定**:在更复杂的应用场景中,超级列表框可能会与数据库或其他数据源绑定,这样数据的添加、删除和修改会直接影响到数据源。 10. **性能优化**:对于大量数据的展示,需要注意性能优化。可以考虑使用...
9. `AddManagerDlg`:处理添加管理员对话框。 这些类在业务逻辑层和数据服务层之间起到了桥梁作用,例如`UserDAO`提供了创建、删除、查询和更新用户的方法。 **第五部分:系统实现** 系统实现阶段将上述设计转化为...
然而,需要注意的是,自Windows 8开始,超级终端不再作为内置应用提供,用户需寻找第三方替代软件,如PuTTY,来实现类似的功能。PuTTY不仅支持串口通信,还支持SSH、telnet等多种协议,功能更为强大。 总的来说,...
在电脑对机升级过程中,超级终端是一个非常重要的工具,它主要用于串行通信,尤其是在旧式计算机或嵌入式系统中进行远程控制和诊断。本文将详细介绍如何设置超级终端的端口,以便顺利进行电脑对机升级操作。 首先,...
【计算机超级技巧】涵盖了一系列提高计算机使用效率和便利性的方法,包括快捷键、操作技巧以及系统功能的利用。以下是对这些技巧的详细说明: 1. **关闭多个窗口**:在同时打开多个窗口的情况下,按住 Shift 键,...
11. Acrobat的打印机功能:选择菜单“文件”》“打印”选项,在弹出对话框中“名称”一栏中选择Acrobat PDF打印,生成PDF文档。 12. PDF文档的修改加工:包括书签、超级链接、注释、文档初始化属性、电子书加密等...