`
eclipsesbs
  • 浏览: 19867 次
社区版块
存档分类
最新评论

第九天:超级对话框

阅读更多

作者:梁祺 (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()方法打开对话框。

 

        NewItineraryItemWizard wizard = new NewItineraryItemWizard();
        WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
        if (Window.OK == dialog.open()) {
            // OK
        }

 

NewItineraryItemWizard负责实例化所有的WizardPage,并调用addPage()把它们加到Wizard维护的页面列表中。 这里的WizardPage成员变量命名比较偷懒,但也一目了然,page2A,page2B,page2C就是第二页的三个可能的页面。

 

public class NewItineraryItemWizard extends Wizard {
    
    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()类似,都是根据当前页面以及行程活动类型来确定下一页或者上一页。

 

    public IWizardPage getNextPage(IWizardPage page) {
        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,当前页已完成。

 

        ModifyListener listener = new ModifyListener() {

            @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。

 

    private boolean isInputValid() {
        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。

 

    public boolean canFinish() {
        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也很常见。

分享到:
评论

相关推荐

    易大漠教程之易语言基础教程

    01.mp4。02.mp4。03.mp4。04.mp4。05.mp4。06易基础(五).mp4。07易基础(六).mp4。第10课_时间操作.mp4。第11课_磁盘操作.mp4。第12课_文件读写A.mp4...第9课_文本操作A.mp4。第9课_文本操作B.mp4。@爱的凌迟。Tags

    VC特效制作100例

    第9章 动画按钮 实例33 avi动画按钮 实例34 实现图标按钮 实例35 实现一组图标按钮 实例36 绘制dib动画按钮 第10章 多彩按钮 实例37 位图按钮 实例38 带颜色的按钮 实例39 对鼠标敏感的按钮 实例40 可弹出...

    VC特效制作一百例

    第9章 动画按钮 实例33 avi动画按钮 实例34 实现图标按钮 实例35 实现一组图标按钮 实例36 绘制dib动画按钮 第10章 多彩按钮 实例37 位图按钮 实例38 带颜色的按钮 实例39 对鼠标敏感的按钮 实例40 可弹出...

    MAPGIS地质制图工具

    执行菜单“1辅助工具\参数(属性)筛选”,弹出筛选图元对话框: A、对于参数筛选图元:在筛选图元对话框中①列表框中选择图元类型;②然后在右侧的参数选项中选择一个参数项作为筛选参数;③再选择运算符及其值。...

    管家婆辉煌版.v9.0.简体中文破解版

    双击《管家婆》图标,第一次进入《管家婆》系统,您的身份是“超级用户”,不用输入密码,选择【确定】,出现日期对话框,选择【确定】,画面出现“如何开始?”简易教程,选择【退出】后,《管家婆》操作主菜单和...

    管家婆366版本

    6 j4 Y9 S9 d* Q+ D9 w+ S) _5 q l 银行帐户(工行城北分理处)。 : H9 s4 N( @; \( a* n& n L/ |2 S. \( Y: P A% `) c/ F l 往来单位(朋友,客户,供应商,分销商等)。 : r6 v4 l0 v R- k& U # i0 s0 d! O& j+ V m2 ...

    MicrosoftHTMLHelpWorkshopV1.3汉化版.rar

    则软件默认为“帮助”):按[Project]项目选项中左边第三个按钮“新建/编辑窗口显示风格”,在弹出的窗口类型中随便输入一个名字如“12”,按“OK”后就会进入“窗口属性”定义对话框。在[General]选项卡中的...

    JavaScript网页特效范例宝典源码

    第9章 页面特效 391 9.1 页面背景效果 392 实例252 背景固定居中 392 实例253 背景图片纵向重复显示 393 实例254 通过按钮变换背景颜色 395 实例255 背景自动变色 396 实例256 百叶窗 396 实例257 渐隐渐显的背景...

    Visual C++高级界面特效制作百例

    第9章 动画按钮 实例33 avi动画按钮 实例34 实现图标按钮 实例35 实现一组图标按钮 实例36 绘制dib动画按钮 第10章 多彩按钮 实例37 位图按钮 实例38 带颜色的按钮 实例39 对鼠标敏感的按钮 实例40 可弹出...

    VxWorks-开发简明培训教程Manual.pdf

    以使用 PC 机上的 COM3 为例,在 Windows 的开始菜单选择程序 -> 附件 -> 通讯 -> 超级终端,启动后,在弹出的"连接描述"对话框指定一个连接名称(可以是任意名字,以 方便记忆为宜)中,如图 1 - 2: VME crate ...

    《于博士之Cadence SPB 15.7 快速入门视频教程》共60集 网盘地址.txt

    第9讲 搜索操作使用技巧 1、搜索特定part 2、搜索特定net 3、搜索特定power 4、搜索特定flat nets 第10讲 元件的替换与更新 1、replace cache用法 2、update cache用法 3、replace cache与pdate cache区别 第11讲 对...

    e语言mp3源码

    然后数组清零,多文件对话框保存到音乐路径程序集变量中。默认选择第一个,然后获取焦点。定义个程序集数组变量存储路径 2:加入列表框:判断取数组成员数的音乐路径不等于0,在判断列表框的表项数不等于0,那么就取...

    用C语言开发手机软件-Windows CE 6.0开发者参考

    第9章 WindLOWSCE文件系统 9.1 WindowsCE文件系统API 9.1.1 标准文件VO 9.1.2 内存映射文件 9.1.3 文件系统浏览 9.2 存储处理 9.2.1 对象存储 9.2.2 使用文件API来访问卷 9.2.3 存储管理器 第10章 注册表 10.1 ...

    用C语言开发手机软件 -Windows+CE+6.0开发者参考

    第9章 WindLOWSCE文件系统 9.1 WindowsCE文件系统API 9.1.1 标准文件VO 9.1.2 内存映射文件 9.1.3 文件系统浏览 9.2 存储处理 9.2.1 对象存储 9.2.2 使用文件API来访问卷 9.2.3 存储管理器 第10章 注册表 10.1 ...

    flash shiti

    打开当前作品的第一个场景 B. 打开当前作品的上一个场景 C. 打开当前作品的下一个场景 D. 打开当前作品的最后一个场景 29.Flash中选择是否合并为单声道的属性是? A. Bit Rate B. Quality C. ExprotSettings...

    PPT操作练习答案培训资料.doc

    增加第九张幻灯片,插入一文本框,在文本框中输入文字"幻灯片放映结束",文字 字体为华文行楷。在文本框下插入一行一列式样的艺术字,内容为"谢谢!",内容字体 为隶书,字体大小为28磅。 方法与步骤 1、打开本题...

    易语言程序免安装版下载

    修改BUG:超级列表框在属性“整行选择”为真时,鼠标单击第一列右面也会导致第一列中的选择框被选中或取消选中。 21. 修改BUG:Sqlite3数据库支持库中“Sqlite数据库.取错误文本()”返回的文本是UTF-8编码(应是GB...

    PowerPoint 2000 Excel 2000 Word 2000 Windows 2000操作系统 计算机基础知识 计算机考试题库

    4.掌握动画和超链接技术:动画效果(幻灯片内动画设计,设置幻灯片切换效果),演示文稿中的超级链接(创建超级链接,编辑和删除超级链接)。 5.映和打印演示文稿:放映幻灯片(设置方式并执行演示),演示文稿的...

Global site tag (gtag.js) - Google Analytics