作者:陈刚,桂林人,97年毕业于广西师范大学数学系,暂于IBM中国研究中心以外包人员身份从事软件开发(2004.2-?),专注基于java平台的软件开发。 email: [email protected]  blog: glchengang.yeah.net 
一、最简单的Dialog。 
  在上一章中我们的Hello World是调用了SWT中已写好的一个对话框,如果我们要自己写一个对话框怎么办呢。很简单只需要继承JFace中的Dialog类,然后重写相应的方法就可以了。代码如下: 
 
 
| 
 import org.eclipse.jface.dialogs.Dialog;  //注意这个是jface的Dialog,不是swt的Dialog import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; 
public class DialogSample extends Dialog { 
    /**      * 构造函数      * 注意:其范围由protected改为public,否则包外的类无法调用      */     public DialogSample(Shell parentShell) {         super(parentShell);     } 
    /**      * 在这个方法里构建Dialog中的界面内容      */     protected Control createDialogArea(Composite parent) {         getShell().setText("标题"); //设置Dialog的标头         Text text = new Text(parent, SWT.BORDER); //设置一个Text控件         text.setText("我爱JAVA"); //设置text中的内容         return parent;     } 
    /**      * 重载这个方法可以改变窗口的默认式样      * SWT.RESIZE:窗口可以拖动边框改变大小      * SWT.MAX: 窗口可以最大化      */     protected int getShellStyle() {         return super.getShellStyle() | SWT.RESIZE | SWT.MAX;     } 
}  |    
 这里出现了几个新的变量类型,在此简单解释如下: 
- Composite :本文中翻译成面板。任何SWT/JFace的界面控件都必须建立在某个面板上面,如上面的new Text(parent, SWT.BORDER),就是将文本框建立在参数传入的面板parent上。面板还能嵌套面板,在建立一个图形界面时常将各个面板层层叠叠的排放在一起。Composite 将是界面设计中使用最平凡的一个类。 
 - Control 是Composite 的父类,而Shell 是Composite 的一个子类。用到的场合不是太多,也没太必要了解很清其本质含义。要依着我的开发经验的理解Control (控制):如上面例程中createDialogArea方法就要返回一个Control 表示这些界面元素是由谁主控,或者是谁是主面板包含住了所有控件(我自己猜的)。Shell表示一个界面的外壳,它能得到比Composite 更多的功能。 
 - 希望通过如下继承关系图有助于您理解Control、Composite、Shell三者间的关系。
    
 然后将上一章的SampleAction.java中的run方法改写如下: 
 
    public void run(IAction action) {       /*       * 也可以new DialogSample(null); 传一个NULL这时是单开一个窗口       * 要看两者的区别,注意window操作系统任务条上的变化。       * 一般来说都应该传一个Shell类型的参数,至少这个Shell来自何处都一样。       */         Dialog dialog = new DialogSample(window.getShell());         dialog.open();      } |   
 然后用上一单运行插件的方法跑一下看。结果界面如下: 
  
 
二、如何设置与取得Dialog中的数据。 
  在我们开发中我们常需要设置对话框一些初值,另外Dialog点"确定"退出后,我们还想取得Text框的值。怎么做呢?我们可以在Dialog类中建立一个字符型的类变量来保存值。请看如下代码: 
 
| 
 public class DialogSample extends Dialog {      //类变量,设一个默认值      private String textValue = "我爱JAVA";      //将Text设为类变量,否则buttonPressed方法无法访问     private Text text;
      .......
      protected Control createDialogArea(Composite parent) {          .........         text = new Text(parent, SWT.BORDER); //将text的定义Text去掉         text.setText(textValue); //改成变量          .........     }      ........ 
    /**      * Dialog点击按钮时执行的方法      */     protected void buttonPressed(int buttonId) {         //如果是点了OK按钮,则将值设置回类变量         if (buttonId == IDialogConstants.OK_ID)             textValue = text.getText();         super.buttonPressed(buttonId);     }
  
    public String getTextValue() {  //增加两个类变量的设值取值方法         return textValue;      }      public void setTextValue(String string) {          textValue = string;      }  }  |   
  
然后将SampleAction改为如下。 
 
        DialogSample dialog = new DialogSample(null);          dialog.setTextValue("我也爱Eclipse");          if (dialog.open() == Window.OK) {              System.out.println("新的值是:" + dialog.getTextValue());          } |   
这时我们发现dialog启动后Text的值变成了“我也爱Eclipse”,然后我们在Dialog重新改一下Text框的值,点OK按钮,在原“控制台”窗口打印出了Dialog中新修改的字符。 
三、如何增加按钮。 
  默认的Dialog只有两个按钮,有时候我们可能增加一些按钮。有两种方法。 
1、方法一(稍复杂)。下面增加一个退出按钮,只须在原有DialogSample 类中重载父类Dialog的两个方法,这种方法可以调整三个按钮的前后位置并可以修改原来默认两个按钮(确定、取消)的设定(如文字、id值等)。 
 
 /**    * 重载默认的按钮建立方法,让其在本地的执行失效    */   protected Button createButton(Composite parent, int buttonId, String buttonText, boolean defaultButton) {    return null;   }   /**    * 利用父类的createButton方法建立按钮    */      protected void initializeBounds() {       /*        * 参数1:取得放按钮的面板,        * 参数2:定交按钮的id值,id值的作用见上面的buttonPressed方法        * 参数3:按钮上的文字        * 参数4:是否为Dialog的默认按钮        */          super.createButton((Composite) this.getButtonBar(), IDialogConstants.CANCEL_ID, "退出", true);          super.createButton((Composite) this.getButtonBar(), IDialogConstants.OK_ID, "确定", false);          super.createButton((Composite) this.getButtonBar(), IDialogConstants.CANCEL_ID, "取消", false);          super.initializeBounds();      } |   
 2、方法二(简单)。就重载一个父类函数,在原来两个按钮后加上一个“退出”按钮,但这个方法就无法调整三个按钮的位置了。 
 
    protected void initializeBounds() {          super.createButton((Composite) this.getButtonBar(), IDialogConstants.CANCEL_ID, "退出", true);          super.initializeBounds();      } |   
  
四、带提示栏的对话框。如下图
   
  很简单将继承类从Dialog改为TitleAreaDialog 就行了。如下: 
 
public class DialogSample extends TitleAreaDialog { ....... } |   
 当然这还不够,我们还要对输入的值进行有效性检查,并根据检查判断是否要提示用户你的输入有误。 
-  在这里我们加一个文本框修改的监听事件。 
        text.addModifyListener(new ModifyListener() {             public void modifyText(ModifyEvent e) {                 if (text.getText().equals("123")) {                     setErrorMessage("你不能输入123");                     getButton(IDialogConstants.OK_ID).setEnabled(false);  //让OK按钮的置灰失效                 } else {                     setErrorMessage(null);                     getButton(IDialogConstants.OK_ID).setEnabled(true);                 }             }         }); |   
  
 -  很多情况下,还有一种限定文本框只能输入数字的方法。
  
 
        text.addVerifyListener(new VerifyListener() {             public void verifyText(VerifyEvent e) {                 e.doit = "0123456789".indexOf(e.text) >= 0;             }         }); |   
  
源程序打包下载: myplugin2.rar 
下一章预告:5.SWT的布局管理器 
后记:这一章写了一个星期,平时工作很忙,写得真够累的,不知道对大家有没有帮助。有人开始在用Eclipse做插件开发了吗?还是在仅仅限于用Eclipse来写JSP吗?这一系列文章希望得到大家的反馈:太简单?太粗略?太难了?还想了解那些方面的?希望直接来信何在文章下跟帖。 
   
 
  |