SWT事件的四种写法

来源:互联网 发布:欣赏不来嘻哈 知乎 编辑:程序博客网 时间:2024/04/30 17:39
 

7.1  事件的四种写法

SWT的事件模型是和Java标准的AWT基本一样的。在第6章的例子中,如何来实现文本框的事件响应呢?比如:鼠标双击文本框弹出一个对话框。下面将按照事件的四种写法来实现它。

7.1.1  匿名内部类写法

在原来的代码行“text = new Text(shell, SWT.BORDER);”之下插入如下语句:

//addMouseListener加入鼠标事件的监听器

text.addMouseListener(new MouseAdapter() {

    public void mouseDoubleClick(MouseEvent e) {//鼠标双击事件的方法

         //打开一个信息框

        MessageDialog.openInformation (null,"","Hello World");

    }

});

new MouseAdapter()就是一个匿名内部类。我们建立了一个继承于MouseAdapter的类,但并没有给这个类命名,并且没有用通常的写法,而是直接在text.addMouseListener方法中写下了类的代码,这就是所谓的匿名内部类(更详尽的解释请参阅Java基础类书籍)。

使用匿名内部类来写事件代码简单方便,但也要注意它的一些缺点:

l           由于事件处理代码会随着组件一起分散在代码中的各个部份,不够集中,这样会导致代码阅读与维护上的不便。

l           各事件的处理全部由嵌套的程序块组成,视觉上会显示有些乱。如果事件处理代码很长,也会导致了阅读与维护上的不便。

l           当工具栏、菜单栏目等也需要处理相同的用户行为时,无法重用事件中的处理代码,导致了代码的臃肿。

7.1.2  命名内部类写法

事件代码使用命名内部类的方式,可以解决匿名内部类存在的问题:首先,事件处理代码都集中在一起,并且都具有有意义的名称,程序容易阅读与维护;另外,单个的事件处理程序也可以被工具栏、菜单栏等重用。实现代码如下:

public class HelloWorld {

    public static void main(String[] args) {

           ……

        Text text = new Text(shell, SWT.BORDER);

//加入鼠标事件监听器,并用下面代码所定义的内部类生成一个对象

        text.addMouseListener(new MyMouseDoubleClick());

        ……

    }

 

//定义一个名为MyMouseDoubleClick的内部类

    private static final class MyMouseDoubleClick extends MouseAdapter {

        public void mouseDoubleClick(MouseEvent e) {

            MessageDialog.openInformation(null, "", "Hello World");

        }

    }

}

7.1.3  外部类写法

这种写法和命名内部类有些相似,只不过是将MyMouseDoubleClick类从HelloWorld.java中拿出去,单独写成一个类文件。这种写法有和命名内部类一样的优点,但因为要单独写成一个文件,写起来会麻烦一些。实现代码如下

//文件1: HelloWorld.java

public class HelloWorld {

    public static void main(String[] args) {

              ……

        Text text = new Text(shell, SWT.BORDER);

//加入鼠标事件监听器,并用下面代码所定义的内部类生成一个对象

        text.addMouseListener(new MyMouseDoubleClick());

        ……

    }

}

 

//文件2:MyMouseDoubleClick.java

public class MyMouseDoubleClick extends MouseAdapter {

    public void mouseDoubleClick(MouseEvent e) {

        MessageDialog.openInformation(null, "", "Hello World");

    }

}

7.1.4  实现监听接口的写法

将HelloWorld类实现MouseListener接口,这样类本身就成了一个监听器,使得加入监听器的代码可以更简洁。这种方式适合加入监听器的组件较多,且要求监听器的事件处理代码可以被组件共用。这种方式还有一个要注意的地方:事件方法和其他方法混合在了一起,容易引起误读,所以应该在事件方法前加入详细的注释说明

实现MouseListener接口要写的事件方法多一些,当然没用的事件方法可以空实现。如果继承MouseListener接口的适配器MouseAdapter,则只写需要的方法就行了。另外要注意:只有接口才能有多继承的特性,所以如果HelloWorld已经是某个类的子类,就只能用实现接口的方式,而不能继承接口的适配器了。

给出示例代码如下:

public class HelloWorld extends MouseAdapter{//或implements MouseListener

    public static void main(String[] args) {

            ……

        Text text1 = new Text(shell, SWT.BORDER);

        Text text2 = new Text(shell, SWT.BORDER);

        text1.addMouseListener(this);

        text2.addMouseListener(this);

        ……

    }

 

    public void mouseDoubleClick(MouseEvent e) {

        MessageDialog.openInformation(null, "", "Hello World");

    }

}

7.1.5  总结

匿名内部类方式在写起来方便些,但不适合事件代码太长太多的情况。从代码书写、阅读、维护以及程序的可扩展性角度来看,命名内部类写法最为值得推荐。外部类的写法主要是为了代码重用才考虑使用,如果包(package)外的类要用到此事件处理代码,这时外部类就派上用场了。而第四种写法,要求组件都可以共用事件代码时才能使用。

7.2  常用事件介绍

除了上例中用于响应鼠标事件的addMouseListener,Eclipse还有一些常用的监听器,它们在各组件中的使用方法相同(如果该组件支持此种事件的话)。在此将它们简单介绍如下:

l           addSelectionListener:这个监听器最最常用。

a)         widgetSelected方法:当组件被选择(鼠标单击、按回车键)时触发此方法的事件处理程序。

b)        widgetDefaultSelected方法:用于某些很少触发选择事件的组件,所以这个方法在实际开发中也很少用。比如,文本框回车事件、列表框双击事件等,就只能用widgetDefaultSelected方法,用widgetSelected方法无效。

l           addKeyListener(按键)

a)         keyPressed方法:当前焦点停在组件时,按下键盘任一键时触发。但对于某些组件(如按钮Button)按回车键无法执行此方法。

b)        keyReleased方法:按键弹起时触发。

l           addFocusListener(焦点)

a)         focusGained方法:得到焦点时触发。

b)        focusLost方法:失去焦点时触发

l           addMouseListener(鼠标)

a)         mouseDown方法:鼠标按下时触发

b)        mouseUp方法:鼠标放开时触发

c)        mouseDoubleClick方法:鼠标双击时触发

以上几个就是常用的事件了,很少吧,SWT的事件模型还是极容易掌握的。事实上除了addSelectionListener较常用之外,其他基本都很少用到。

7.3  在事件代码中如何访问类中的变量

7.3.1  访问类中的变量的三种方法

在写事件代码的时候,常常需要引用主类中的变量,要访问这些变量是需要一些技巧的。

方法一:加final修饰符。

public class HelloWorld {

    public static void main(String[] args) {

……

//将变量前加final,否则在事件代码里不能引用

final String str="陈刚"; 

text.addMouseListener(new MouseAdapter() {

            public void mouseDoubleClick(MouseEvent e) {

              System.out.println(str); //str变量前要加final

            }

});

……

    }

}

方法二:将变量str变成类的实例变量。但这种方法扩大了str变量的有效范围。

public class HelloWorld {

    //由于引用它的代码是在静态方法内才加static,否则不必要static。

static String str="陈刚";

    public static void main(String[] args) {

……

    }

}

方法三:将事件代码写成命名内部类,然后通过构造函数的参数来传入。这种方法较繁琐一些。

public class HelloWorld {

    public static void main(String[] args) {

        String str="陈刚"; 

        //通过构造函数参数将str值传入

        text.addMouseListener(new MyMouseDoubleClick(str));

    }

 

//匿名内部类MyMouseDoubleClick

    private static final class MyMouseDoubleClick extends MouseAdapter {

        private String string;//建一变量引用str的值

        public MyMouseDoubleClick(String str){ //通过构造函数参数接受str值

            this.string=str;          

        }

        public void mouseDoubleClick(MouseEvent e) {

            System.out.println(string);

        }

    }

}

7.3.2  Java中变量的称法和说明

此节中用到了一些Java变量方面的知识,在此一并附上。Java中有三种容易混淆的变量:局部变量、实例变量、类变量,如下程序所示:

public class Variable {

    static int allClicks = 0; //类变量

    String str = "广西桂林"; //实例变量

    public void method() {

        int i = 0; //局部变量

    }

}

类变量的定义前加有static,这表示它是一个静态的,因此类的多个实例共用一个类变量。实例变量定义在类的方法之外,一般处于类的起始位置,类的每一个实例都独自拥有一份实例变量的拷贝。局部变量的有效范围在程序块中,它的生命期仅限于此程序块内。

实例变量在有些书籍中也翻译成“域”或“成员变量”。在面向数据库的实体类(Hibernate中也称POJO - 简单原始的Java对象)中,被称之为“属性”或“字段”的变量,也是实例变量的一种。

使用变量的一般原则是,尽量使变量的有效范围最小化:优先考虑用局部变量,其次是实例变量,最后才是类变量。

另外,还有一种常量的写法,它比类变量写法仅多了个final,如下所示:

 final static int ALL_CLICKS = 0; //常量

注意ALL_CLICKS是全大写的,这是常量的规范命名方式。这时ALL_CLICKS被final约束,它不能再被赋值了。

7.4  本章小结

本章主要介绍了事件的四种写法,及事件访问类中变量的方法,这些知识在SWT编程中经常要用到。但是,读者可以不必太执着于本章的内容,可以快速浏览后,进入下一章的学习,当用到时,再回过头来查阅。

 

参考:http://cxykxl.blog.163.com/blog/static/30508002007329103015300/

Eclipse从入门到精通6.4