事件驱动模型实例详解(Java篇)或许每个软件从业者都有从学习控制台应用程序到学习可视化编程的转变过程,控制台应用程序的优点在于可以方便的练习某个语言的语法和开发习惯(如.net和java),而可视化编程的学习又可以非常方便开发出各类人机对话界面(HMI)。可视化编程或许是一个初学者开始对软件感兴趣的开始,也可能是一个软件学习的里程碑点,因为我们可以使用各类软件集成开发环境(IDE)方便的在现成的界面窗口上拖放各类组件(Component),这类组件包括我们常见的按钮(Button),单选按钮(RadioButton),复选框等(Checkbox)。这样的拖放式开发方式不但方便,而且窗口会立竿见影的显示在我们的面前,这对于一个软件初学者而言或许是一件非常有成就感的事情。但是很多软件学习者在学习可视化开发的过程中,只是非常表面的来理解可视化编程,他们可能认为能够使用拖放方式完成一个界面就非常值得称道,但是很少有人会认真的去理解编程语言对于可视化编程组件的支持和整合,在Softworks软件人才培训中心的两年教学过程,我深刻的感受到了这一点,因此下文将会结合我的教学经验来讲解可视化编程过程中最为关键的“事件驱动模型”。1.什么是事件驱动模型?在讲解事件驱动模型之前,我们现在看看事件驱动模型的三大要素:?事件源:能够接收外部事件的源体。?侦听器:能够接收事件源通知的对象。?事件处理程序:用于处理事件的对象。学员应该要理解任何基于事件驱动模型的开发技术都包含以上三大要素,不管是.net还是java技术,甚至是以前我们使用的VisualBasic和Delphi语言都有基于以上三大要素的事件驱动模型开发流程。现在我们来看一个生活中的示例,如果有一天你走在路上一不小心被天上掉下来的花瓶砸到了,并且晕死了过去。那么整个过程其实就是一个事件处理流程,而且我们可以非常方便的分析出刚才所提到的事件驱动模型中的三大要素。1.被砸晕的这个人其实就是事件源,因为他是能够接受到外部的事件的源体。2.侦听器就是这个人的大脑神经,因为它会感知到疼痛。3.事件处理就是这个人晕死了过去。由于事件驱动模型在我们日常生活中是无处不在的,因此Java和其他的编程语言都将这一过程运用到了可视化编程中了。2.Java编程语言中的事件驱动模型在Java编程技术中,最常用的可视化编程当属JavaSwing技术,JavaSwing为开发者提供了很多现成的组件,如:按钮(JButton),单选按钮(JRadioButton)等。为了管理用户与组成程序图形用户界面的组件间的交互,必须理解在Java中如何处理事件。假设用户单击了程序图形用户界面中的一个按钮,其实该按钮就是这个事件的源(可以引发事件的物体)。所有的JavaSwing对象都有感知自己被操作的能力,因此JButton按钮也具有这样能力。一个事件通常必须有一个源对象,这里就是JButton对象。当单击按钮时,JButton组件类会生成一个用于存放该事件参数的ActionEvent的对象,该对象包含了事件及事件源的信息。图1-1显示了这种机制。图1-1当JButton感知到自己被点击以后会将这种感觉传递给某个侦听器对象,该侦听器对象原先已被告知对该类事件感兴趣,侦听器对象仅是一种侦听特定事件的对象。这里的“将事件传递给侦听器”仅意味着事件源调用侦听器对象中的一个特定方法,并以事件对象作为实参。侦听器对象可以侦听一个特定对象的事件(比如一个按钮)。其实可以使任何类的对象成为侦听器对象,只要使该类实现侦听器接口。你将会发现有各种各样的侦听器接口,以满足不同类型事件的需要。在这个单击按钮的例子中,需要实现ActionListener接口以便接收按钮事件。在侦听器接口声明的方法中,实现了接受这个事件对象并响应该事件的代码。在本例中,在事件发生时,调用了ActionListener接口中的actionPerformed()方法。每种侦听器接口都定义了特定的方法,用来接收该侦听器计划要处理的事件。仅仅实现侦听器接口还不足以将侦听器对象连接到事件源上,仍需要把侦听器与希望处理的事件单个源或多个源连接起来。通过调用事件源对象的特定方法,可以注册带有事件源的侦听器对象。例如,为了注册侦听单击按钮事件的侦听器,需要调用JButton对象的addActionListener()方法,该操作可以使侦听对象和事件源绑定。每个事件响应时只涉及到对该事件感兴趣的侦听器。由于侦听器只要求实现一个合适的接口,所以实际上,可以在任何希望的地方接收和处理事件。在Java中使用侦听器对象处理事件的方式,称为委托事件模型,这是因为对于诸如按钮这种组件引起的事件响应,并不是由引起事件的对象本身处理,而是委托独立的侦听器对象进行处理,刚才的actionPerformed()其实就是一个委托处理方法。现在让我们来看一下,JButton是如何将用户的点击转化成方法处理的(如图1-2)。图1-2JButton组件初始化代码片断:privatevoidinitialize(){frame=newJFrame();frame.getContentPane().setLayout(null);frame.setBounds(100,100,247,165);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setTitle(事件驱动程序);//btnPress就是这次点击操作中的事件源btnPress=newJButton();btnPress.setText(Press);btnPress.setName(Press);btnPress.setBounds(63,98,99,23);//向事件源btnPress植入侦听器对象ButtonEventHandlerbtnPress.addActionListener(newButtonEventHandler(this));frame.getContentPane().add(btnPress);frame.getContentPane().add(txtMessage);}侦听器创建的代码片断://侦听器对象ButtonEventHandler(用来侦听按钮的点击操作)classButtonEventHandlerimplementsActionListener{//窗体对象privateEventDemoform=null;//通过构造体传入窗体对象,//作用在于让侦听器对象明白事件源处于//哪个窗体容器中publicButtonEventHandler(EventDemoform){this.form=form;}//委托方法publicvoidactionPerformed(ActionEvente){//该方法将会把事件的处理权交给窗体容器类的//btnPress_Click方法处理。this.form.btnPress_Click(e);}}真正的事件处理代码片断:/***按钮btnPress的事件处理方法。**@parame事件参数*/privatevoidbtnPress_Click(ActionEvente){Stringmessage=你点击的按钮名叫:+((JButton)e.getSource()).getName();this.txtMessage.setText(message);}按钮的事件处理程序代码片断:代码工作原理:JButton组件初始化代码片断已经明确阐述了按钮被创建后放置于窗体上,关键在于本代码片断的以下语句:btnPress.addActionListener(newButtonEventHandler(this));该语句就是向事件源植入了侦听器对象ButtonEventHandler,该类实现了ActionListener结构,因此JButton类的对象btnPress这个时候已经具有了处理用户点击按钮的能力了。当用户点击btnPress这个按钮的时候,按钮对象会直接把这次点击感觉传递给ButtonEventHandler的actionPerformed方法处理,为养成较好的编程习惯,我们中心并不建议学员直接在该委托方法中编写代码,而是需要将该事件处理再次转发给窗体中的某个方法来处理,这个方法的命名也必须是有规则的,就是事件源名+下划线+事件名(btnPress_Click),并且该方法必须具有事件参数ActionEvent,因为在该对象中明确指明了,哪个按钮受到了点击了。e.getSource()方法返回了被点击按钮的对象,由于这次被点击的是一个按钮,因此我们需要使用JButton对e.getSource()的返回值进行强转,随后通过getName()方法得到这个按钮的名字。至此整个点击事件处理完了。这篇文章主要的作用是为了阐述Java的事件处理机制,至于侦听器和事件源的内部工作原理,将会在我的下一篇技术文章《Java的观察者模式》中详细讲解,待续……上海Softworks软件人才培训中心电话:021-5308653053086531地址:上海市北京东路668号科技京城东楼9楼E座网址:来自:[收藏到我的网摘]集合框架(Collection)可以说是软件编程中过程中极其重要的一个概念,为什么我这里要用“极其”这个词呢?就是因为在我的14个项目研发经验中,几乎每个项目都需要使用集合框架,如果用好了集合框架,那么整个项目将会变得非常灵活,因此在我Softworks中心的培训经历中,我也非常注重对于这个概念的培训。其实比较喜欢在网上浏览技术的同学可能知道,网上有比较流行的32道经典Java面试考题,在这些考题中就有很多是用来考察学员对于集合框架的理解程度的。在授课的过程中,我借助了《人月神话》中的5W1H的学习分析方法对于集合框架进行了介绍:1.What:什么是集合框架,集合框架其实就是一个“垃圾桶”,因为任意对象都可以放入集合框架中。由于数组存在比较明显的缺陷(例如:一次声明所产生的数据类型必须是一致的,数据地址必须是连续的,数组长度是定长的等等),而集合框架比数组更灵活更实用,甚至可以将集合框架中的某些部分理解为数组的包装类。2.Why:集合框架比数组来的更灵活,可以说集合框架完全弥补了数组的一些缺点,虽然操作效率没有数组那么高,但是却可以大大提高软件的开发效率,而且不同的集合框架类可以适用于不同的场合。3.Where:我们在项目的任何一个角落中都可以使用集合框架,例如,现在我们有2个实体类:顾客类(Customer)和订单类(Order),根据现实情况我们可以明确,一个顾客拥有多张订单,而一个订单只能隶属于一个客户,这个时候由于客户包含了多张订单,那么顾客类就可以用集合框架来存放所有的订单对象了。4.When:集合框架顾名思义就是某些相关数据的整合个体,那么当我们需要将一些相同特性的个体整合或者说绑定在一起的时候,就可以考虑使用集合框架了,因为集合框架可以保存和帮定这样一些数据。5.Who:所有的Java,.Net程序员都可以使用集合框架,因为现今的面向对象的高级编程语言都提供了集合框架的处理类。6.How:在理解了集合框架的意义以后我们来看看如何来使用集合框架SUN为我们提供了功能强大的JDK(1.5)因此我们可以通过java.util包中看到几乎所有的集合框架类,在讲解具体的集合框架之前我们来看看一些常用的集合类之间的关联关系:通过上图我们可以看到常用的集合框架的继承支线,黑色的空心三角箭头表示的是接口之间的继承关系,而红色的空心箭头表示的是类对于接口的实现,就我个人的教学经验而言,我比较喜欢的是对比教学法,通过不同的对比教学来阐述类,接口之间的关系和区别,现在叙述如下:List接口和Set接口的区别在于,List接口可以顺序存放数据,并且数据是允许重复的,而Set接口正好与List接口相反,不能顺序存放数据,也不能存放相同数据。M