第六天:天天用到的对话框是怎么做的

作者:梁祺 (eclipsesbs@gmail.com)

 

来自:http://www.benisoft.net/day6/index.html

 

昨天我们在介绍布局时,已经接触过对话框了,今天我们来看一下在实际应用中,对话框是怎么工作的。 对话框一般是提供给用户和应用程序交互的窗口,它分为模态对话框(Modal)和非模态对话框(Non-modal)。

  • 模态对话框:用户必须完成对话框内的操作,关闭对话框以后才能继续操作对话框以外的应用程序。
  • 非模态对话框:用户不必关闭对话框,也能继续操作对话框以外的应用程序。

一般情况,我们用到的都是模态对话框,所以我们主要介绍模态对话框,如果没有特别说明,对话框就指模态对话框。

在Itinerary的例子里,当用户创建一个出行计划时,我们使用对话框让用户输入新建出行计划的名称和简单描述, 点击OK来创建新的出行计划。

NewItineraryAction打开对话框New Itinerary(eclipse.tutorial.itinerary.dialogs.NewItineraryDialog), 当用户输入出行计划的名称,点击OK,从对话框对象dialog获取新创建的Itinerary对象,代码如下。

public  class NewItineraryAction  implements IWorkbenchWindowActionDelegate {
        ...
     public  void run(IAction action) {
        NewItineraryDialog dialog =  new NewItineraryDialog(window.getShell());
         int result = dialog.open();
         if (result == Window.OK) {
            Itinerary itinerary = dialog.getItinerary();
            ...
        }
    }

NewItineraryDialog有三个成员变量。

  • itinerary是新建的出行计划Itinerary对象,它是对话框的输出。
  • textName和textDescription是两个UI控件成员变量,分别用以接受用户输入出行计划名称和简单描述。
public  class NewItineraryDialog  extends Dialog {

     private Itinerary itinerary;
     private Text textDescription;
     private Text textName;

对话框一个重要的部分就是控件的布局,一般都需要花费大量精力来设计对话框的布局,并加以实现,我们这个例子比较简单。 使用一个两列的GridLayout,第一行布置出行计划名称的控件,第二行布置描述的控件。

     protected Control createDialogArea(Composite parent) {
        Composite composite =  new Composite(parent, SWT.NONE);
        GridLayout layout =  new GridLayout(2,  false);
        composite.setLayout(layout);
        composite.setLayoutData( new GridData(SWT.FILL, SWT.FILL,  truetrue, 1,
                1));

         // Name
        Label label =  new Label(composite, SWT.NONE);
        label.setText(\ "Name: \");
        label.setLayoutData( new GridData(SWT.BEGINNING, SWT.BEGINNING,  false,
                 false, 1, 1));

        textName =  new Text(composite, SWT.BORDER);
        textName.setLayoutData( new GridData(SWT.FILL, SWT.BEGINNING,  true,
                 false, 1, 1));

         // Description
        label =  new Label(composite, SWT.NONE);
        label.setText(\ "Description: \");
        label.setLayoutData( new GridData(SWT.BEGINNING, SWT.BEGINNING,  false,
                 false, 1, 1));

        textDescription =  new Text(composite, SWT.BORDER | SWT.MULTI);
        textDescription.setLayoutData( new GridData(SWT.FILL, SWT.FILL,  true,
                 true, 1, 1));

         return composite;
    }

对话框另一个部分是对用户输入进行验证,在很多应用里,这部分是比较繁琐的,关键是心里需要有个清晰的定义, 有文档描述就更好(这个好像只有产品级的应用里才会专门有人做这个设计)。这个例子里要求出行计划名称是必须输入的, 实现也很简单,如果用户没有输入出行计划名称,就把OK按钮变灰,无法创建出行计划。这样做不太严谨,好在例子程序 大家也能看明白,所以问题不大。比较好的做法是用TitleAreaDialog,用警告的方式告诉用户需要输入出行计划名称。

既然对话框一开始就没有出行计划名称,我们就需要在OK按钮创建完成后立刻将它变灰,这个需要重载createButtonsForButtonBar(), 先调用父类的createButtonsForButtonBar()来创建Cancel按钮和OK按钮,然后将OK按钮变灰。另外还需要为textName 添加事件处理器来获取文本框的修改事件,如果文本框内容为空,将OK按钮变灰,否则,恢复OK按钮。

     protected  void createButtonsForButtonBar(Composite parent) {
         super.createButtonsForButtonBar(parent);
        
        getButton(OK).setEnabled( false);
    }

     void addListeners() {
        textName.addModifyListener( new ModifyListener() {

             @Override
             public  void modifyText(ModifyEvent e) {
                getButton(OK).setEnabled(! textName.getText().isEmpty());
            }});
    }

对话框最后一部分是从控件中获取数据,通过某种方式返回给调用者。在这个例子里, 当用户输入出行计划名称和描述,点击OK按钮后,Eclipse会调用okPressed()方法。在这个方法里,从textName和 textDescription获取名称和简单描述后,创建Itinerary对象,保存在itinerary成员变量上, 最后通过getItinerary()方法传递出去。这是一个常规的做法。

     @Override
     protected  void okPressed() {
        String name = textName.getText();
        String description = textDescription.getText();
        itinerary =  new Itinerary(name);
        itinerary.setDescription(description);

         super.okPressed();
    }

对话框我们就介绍到这里,其实很简单,就三个部分,控件布局,输入验证,以及返回数据给调用者。不过实现和测试 的工作量都比较大,估计工作量的时候要有充分的余量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值