首先按照如下方式写,在弹出的窗口中不管点击什么都是关闭窗口

shell = new Shell(display);
   shell.addShellListener(new ShellAdapter() {
    @Override
    public void shellClosed(ShellEvent e) {
       MessageBox mb = new MessageBox(shell,SWT.ICON_QUESTION | SWT.OK| SWT.CANCEL);
                   mb.setText("提示");
                   mb.setMessage("确定要关闭吗?");
                  int rc = mb.open();
                         if (e.doit == (rc == SWT.OK)) {
                         System.exit(0);
                    }
                   else if(e.doit == (rc == SWT.CANCEL)) {
                     return;
                    }
    }
   });改为如下方式,则可以达到要求
 
shell = new Shell(display);
   shell.addShellListener(new ShellAdapter() {
    @Override
    public void shellClosed(ShellEvent e) {
       MessageBox mb = new MessageBox(shell,SWT.ICON_QUESTION | SWT.OK| SWT.CANCEL);
                   mb.setText("提示");
                   mb.setMessage("确定要关闭吗?");
                              e.doit = mb.open() == SWT.OK;
                               }
   });

===========================================================================================

1.在shell中禁用最大化按钮

    我在尝试写SWT代码的时候遇着这样的一个问题:我希望将shell的最大化按钮禁用,于是我回想原来在写AWT的时候用到的一个方法,Resizable()(貌似是这样,记不清莫怪),于是我在API文档中查找shell的相关方法,希望能够找到这样的一个方法,但是很不幸,我没有找到。后来我慢慢领悟到,其实SWT中大部分组件的表现形式都是通过他们构造方法中的style参数(所有的style都在org.eclipse.swt包中)来控制,于是我查看了API文档,在shell中找到了几个关于shell表现的style:

SWT.CLOSE   SWT.TITLE    SWT.MIN    SWT.MAX   SWT.RESIZE

如果我们希望在shell中禁用最大化按钮,只需在源码中写这样的代码:

Display display = new Display();
 shell = new Shell(display,SWT.CLOSE|SWT.MIN|SWT.SYSTEM_MODAL); //创建窗体禁用最大化按钮

    2.键盘的字母监听

    前言:监听回车键之类的东东很好办,因为有现成的keyCode,比如说我们在一个文本框中监听回车键,代码如下:

text1.addKeyListener(new KeyAdapter(){    //添加按键监听器于text1上
     public void keyPressed(KeyEvent e) {    //监听键盘按键
     if(e.keyCode == SWT.CR)   //当按回车键键时触发
      text2.setText(text1.getText());}});

OK,这样就搞定.。但是如果我们监听字母A键呢,查找API文档,没有SWT.A这样的style,所以看来这样是行不通了。

但是我们可以用下面的方法解决,代码:

text1.addKeyListener(new KeyAdapter(){
    public void keyPressed(KeyEvent e) {
     if(e.keyCode == (int)(e.character = 'a')) //当按键为字母A键时触发
      text2.setText(text1.getText());}});

在上面的代码中我们使用了Event类的character,他返回一个字符型,我们只需要将它强制转化为int类型在和keyCode做比较就ok。个人认为这个方法比较复杂,但是是我目前摸索到的方法,如果其他朋友有更好的方法,希望能够提出来大家共享。
 

     3.在MessageBox中判断点击。

     MessageBox是一个消息对话框(详见API文档),他有几种style:

ICON_ERROR, ICON_INFORMATION, ICON_QUESTION, ICON_WARNING, ICON_WORKING
OK, OK | CANCEL
YES | NO, YES | NO | CANCEL
RETRY | CANCEL
ABORT | RETRY | IGNORE
我是在处理一个shell关闭的事件中遇到的问题,未改之前的代码如下:

shell.addShellListener(new ShellAdapter() {
   public void shellClosed(ShellEvent e) {
      MessageBox msgbox = new MessageBox(shell,SWT.YES|SWT.NO|SWT.ICON_QUESTION);
      msgbox.setText("退出");
      msgbox.setMessage("你确定要退出吗?");
      msgbox.open();    });

上面那一段代码的作用是:在点击shell的关闭按钮(即左上角的“X”时),会弹出一个对话框,为你“你确定要退出吗?”,我的本意是:在点击“是”的时候关闭窗口,不然则不关闭窗口。但是很不幸,无论我是点击“是”还是“否”,窗口都会义无反顾的消失。所以从这里我们可以看出,我们需要做一个判断,那么怎么判断呢,仔细思考我们可以发现,msgbox.open()返回的是一个int值,而我们的style便就是int值,好了,方法在瞬间找到了,我们只需要在open的时候判断到底是SWT.YES还是SWT.NO就可以确定我们点击为“是”或者“否”,重写代码如下:

shell.addShellListener(new ShellAdapter() {
  public void shellClosed(ShellEvent e) {
     MessageBox msgbox = new MessageBox(shell,SWT.YES|SWT.NO|SWT.ICON_QUESTION);
     msgbox.setText("退出");
     msgbox.setMessage("你确定要退出吗?");
     if(msgbox.open() == SWT.YES) {  //打开的时候判断值为YES
      e.doit = true;  //执行操作
     } else {
      e.doit = false;
     }
     }
   });

在上面的代码中,我判断了在打开的时候为“YES”,然后将doit值设为ture,即执行操作,否则为false。好了,问题又来了,这个doit是个什么东东呢,不要着急,下面接着讲,不过现在我们的msgbox是真的可以判断我们的意图来执行操作了。 ^_^

     4. Event中的doit

     在上面的问题中我们看到了这样的代码段:

if(msgbox.open() == SWT.YES) {  //打开的时候判断值为YES
      e.doit = true;  //执行操作
     } else {
      e.doit = false;
     }


那么doit到底是何方神圣可以主宰我们事件的“真假”呢?这里揭开谜底,doit是Event类中的一个参数,

API中的定义:

boolean doit

API中的state:

depending on the event, a flag indicating whether the operation should be allowed.

从state中可以看出:doit依赖于event(事件),是一个指示操作是否被允许的标志。

当doit值为true时为允许,反之则不被允许。在上面的代码中,doit为true的时候,就被允许执行shellClosed的操作,所以当我们按下“是”的时候,shell被销毁了,而按下“否”的时候,shell便不会销毁。