Vaadin 的历史和功能特性
Vaadin 是一款使用 Apache V2 许可协议的开源产品,它由位于芬兰的 IT Mill 公司开发。其前身是 IT Mill 公司由 2000 年起开始研发的 Millstone 用户界面类库。2006 年,IT Mill 公司以 IT Mill Toolkit 作为正式名称发布了它的 Release 4 版本,这个版本中包含了全新的基于 Ajax 的表现层引擎,使开发人员在开发 Ajax 应用程序时无需关注客户端与服务器端的通讯。2007 年末,IT Mill 使用 GWT 技术完全重写了 IT Mill Toolkit 的客户端界面渲染引擎并使用 Apache V2 协议将其开源,版本号为 IT Mill Toolkit Release 5。2009 年春季,为了消除命名的混淆 (IT Mill 是开发企业名称而不应是产品名称 ),IT Mill 以 Vaadin( 芬兰民间传说中的一种神话生物,是女神也是一种山岭驯鹿的神话祖先 ) 作为全新的名称发布了第六个版本,这个版本还提供了 Eclipse 和 Netbeans 插件的辅助开发工具,极大的提高了开发效率。目前最新的版本为 6.4 版。
Vaadin 6.x 版包含大量的功能特性,以下为其中最重要的几点:
除了上述的功能特性外 ,Vaadin 还拥有成熟的商业技术支持服务。表 1 针对 RIA 框架的主要技术特点和商业应用开发中需要关注的几个方面,将 Vaadin 与其它几种非常流行的 RIA 开发框架做一简单比较。
功能特性 | Vaadin 6.x | Ext GWT 2.0 | Flex 3 | GWT 1.7 | ICE Faces 1.8 | JQuery 1.3.2 | Smart GWT 1.3 | Wicket 1.4 |
---|---|---|---|---|---|---|---|---|
含有种类丰富的 Widget 组件 | *** | *** | *** | ** | ** | ** | *** | * |
不需要使用浏览器插件 | Y | Y | Y | Y | Y | Y | Y | |
不需要 Javascript 编程 | Y | Y | Y | Y | Y | Y | ||
使用 Java 语言扩展框架 | Y | Y | Y | Y | ||||
不需要使用 HTML | Y | Y | Y | Y | Y | |||
不需要 XML 配置 | Y | Y | Y | Y | Y | Y | ||
只需要进行服务器端编程 | Y | Y | Y | |||||
用户界面的业务逻辑保存在服务器上 | Y | Y | Y | |||||
框架适用于创建网站而不是应用程序 | Y | Y | ||||||
框架适用于展示多媒体、视频和广告 | Y | |||||||
框架的开发和维护由商业公司负责 | Y | Y | Y | Y | Y | Y | ||
有商业的客户支持和质量保证 | Y | Y | Y | Y | Y | |||
开发商提供框架的专家服务支持 | Y | Y | Y | |||||
开发商提供框架的 Add-On 扩展功能 | Y | Y | Y | |||||
可以在商业应用中免费使用 | Y | Y | Y | Y | Y | Y | Y | |
使用的开源许可证 | Apache 2.0 | GPL v3/Commercial | MPL 1.1 | Apache 2.0 | MPL 1.1 | MIT/GPL v2 | LGPL | Apache 2.0 |
在 Eclipse 和 Netbeans 中 Vaadin 开发环境的配置
Vaadin 是一个纯 Java 语言的 RIA 开发框架,所以原则上可以使用任意的 Java 编辑器来进行开发。但是 Vaadin 提供了 Eclipse 和 Netbeans 两种环境的集成插件,使用这两个插件,我们可以在相应的 IDE 中高效快捷的开发 Vaadin 应用,本节将依次介绍如何在这两种 IDE 中配置 Vaadin 开发环境。
Vaadin SDK 的下载和使用
通过访问地址 http://Vaadin.com/releases可以获得 Vaadin 各个版本的 SDK 文件 , 在 Vaadin Release 6.3 版之后 , 针对所有平台的 SDK 都统一打包在一个 zip 文件中 , 本节以 6.4 版本为例进行介绍。在已经打开的 Download 页面中点击Vaadin 6 for all platforms链接即可下载 Vaadin 6.4 版的 SDK 压缩文件,SDK 中包含开发所需的 jar 类库,开发文档以及一个 Demo 样例程序。解压下载的 zip 文件,可以得到下图所示的文件结构:
执行 start.bat (Windows 平台 ) 或 start.sh (UNIX 平台 ) 后 Vaadin SDK 会在浏览器窗口中 (http://localhost:8888/) 启动样例应用程序,在这个程序中包含了 Vaadin 的各种学习资料和 UI 组件的 demo 展示。图二为 Vaadin UI 组件 Demo 展示程序界面,在这个展示程序中列出了各种 UI 组件的外观及生成代码示例。
Eclipse 下 Vaadin 的环境配置和应用启动
配置 Eclipse 下 Vaadin 的开发环境过程非常简单,整个过程只需下载安装一个 Vaadin 开发 Plug-in 插件即可 (Eclipse 需为 3.5 GALILEO 以上版本 )。以下为具体过程:
启动 Eclipse,选择 Help 菜单下的“Install New Software”命令,在弹出的 Install 对话框中点击 Add 按钮,在 Add Site 弹出对话框的 Location 输入框中填入更新站点地址:http://Vaadin.com/eclipse,Name 输入框中填入 Vaadin 作为站点名称后点击 OK 按钮 , 如图三所示,Eclipse 会显示出这个更新站点中所有可用的功能特性。选择所有的功能特性后完成插件的安装。Eclipse 下的开发环境配置便全部完成了。
使用 Eclipse 创建 Vaadin 项目时只需在 File 菜单下选择 New -> project ->Vaadin ->Vaadin Project 即可建立一个 Vaadin 工程 , 图 4 为建立本文示例工程的配置对话框。需要注意的是本文的示例使用 Tomcat V6 作为 Vaadin 的运行时环境 , 在启动 Vaadin 项目之前须确保 Eclipse 中已经配置好了 Tomcat 服务器。
在 Eclipse 中启动 Vaadin 项目的过程同样非常简单,在 Eclipse 创建 Vaadin 项目时会预先创建好一个 Vaadin Application 的实现类并配置好相应的 servlet 信息。启动项目只需选中项目,并在 Run 菜单中选择 Run As- 〉 Run On Server 即可在地址 : http://localhost:8080/{ProjectName}/( 本示例程序中地址为 http://localhost:8080/DW_Vaadin_Project/) 访问建立的 Vaadin 应用程序
Netbeans 下 Vaadin 的环境配置和应用启动
使用 Netbeans 开发 Vaadin 首先需要在地址 :http://Vaadin.com/netbeans/org-Vaadin-support.nbm下载 Netbeans 的 Vaadin 开发插件 , 使用这个插件需要 Netbeans IDE 6.8 以上的版本。将插件下载到本地之后需要在 Netbeans 中安装,具体过程如下:
启动 Netbeans,选择 Tools 菜单下的“Plugins”命令,如图 5 所示,在弹出的 Plugins 对话框中切换到 Downloaded 面板下并点击 Add Plugins 按钮。在文件选择窗口中选中已经完成下载的插件文件后点击 OK 即可启动插件的安装。
在 Netbeans 中创建一个 Vaadin 项目需要以下步骤:
相对创建项目而言,在 Netbeans 中启动 Vaadin 应用非常简单,只需在 Projects 面板中右键点击项目,在弹出菜单中选择 Run 即可。默认情况下 Netbeans 会使用 Tomcat 在地址 :http://localhost:8084/{ProjectName}/Vaadin( 本示例程序中地址为 http://localhost:8084/DW_Vaadin_Project/Vaadin) 启动 Vaadin 应用。
Vaadin 应用程序用户界面的开发
图 7 是 Vaadin 应用程序的体系结构图。如该图所示,使用 Vaadin 开发的应用程序实际上是运行在容器中的 Java Servlet,应用程序的入口点是 Application 类,它会创建并且管理所有必须的 UI 组件。用户与 UI 组件的交互由事件监听器处理,应用程序所需的数据直接被绑定在 UI 组件上,应用程序的整体外观则是由 CSS 编写的主题来控制。在 Vaadin 应用程序中,图标、图片和其他可被用户下载的文件被当作资源 (resources) 来处理,这些资源可以是应用程序内部的,也可以是来自外部的。在程序运行时 ,Vaadin 框架会将同一个应用中的所有的 Http 请求都关联到同一个 session 会话里 , 一个 application 类的实例实际上是一个 session 对象。因此开发人员可以像开发桌面程序一样来开发 Vaadin Web 应用程序,无需考虑 Http 会话管理等通常需要在 Web 应用开发中关注的问题
在 Vaadin 应用程序中必须定义一个 Application 类来作为程序的入口,这个类需要继承 Vaadin 的抽象类 com.Vaadin.Application并且实现init()方法。当程序运行时,Vaadin 会执行 init() 方法中的代码来生成各个 UI 组件。除此之外,Application 类还提供了应用程序窗口管理,执行控制和主题选择的功能。在初始化 UI 组件时,至少需要建立一个主窗口 (Main Window), 这个主窗口是 Web 浏览器中最高层的 UI 组件 , 其他所有的 UI 部件都包含在主窗口中。由于 Vaadin 应用是一个单页面的 Web 应用程序 , 在整个应用的生命周期中 , 主窗口不会被再次装载 , 所以它和桌面应用程序的主窗口非常类似,是所有其他 UI 组件的容器。如清单 1 所示,可以使用 Application 类的 setMainWindow()方法来为应用程序添加主窗口。
import com.Vaadin.Application; import com.Vaadin.ui.*; public class Dw_Vaadin_projectApplication extends com.Vaadin.Application { public void init() { /*... 添加主窗口 ...*/ Window main = new Window("Dw_Vaadin_project Application"); setMainWindow(main); /*... 在主窗口中添加其他 UI 组件 ...*/ Label label=new Label("Hello Vaadin user"); main.addComponent(label); Window window = new Window("Sub Window"); main.addWindow(Window); } } |
在创建了主窗口之后,可以创建其他的 UI 组件并通过 addComponent方法将它们添加到主窗口中 , 也可以使用 addWindow方法在主窗口中添加子窗口对象。图 8 所示为清单 1 中代码所产生的 UI 界面,这段代码在主窗口中创建了一个 label 组件和一个子窗口。除了 UI 组件外,Vaadin 还提供了多种 Layout 对象用来控制程序的 UI 布局,结合使用各种 Layout 布局,界面 UI 控件以及 Theme 主题,可以使用 Vaadin 开发出外形绚丽并且功能接近桌面程序的 Web 应用。图 9 为一个使用 Vaadin 开发的真实应用的界面截图。 更多的 Vaadin UI 组件的介绍和示例代码 , 可以在 图 2 所示的 Vaadin UI 组件 Demo 展示程序中获得。
Vaadin UI 组件的事件监听和处理机制
当用户在程序 UI 界面中进行操作时 ( 例如选择下拉列表中的条目或者点击一个按钮 ),应用程序需要获知这些操作。Vaadin 使用 Observer 设计模式来处理用户界面操作和程序逻辑之间的通讯。这一模式使用两类元素:一个被观测的对象 (object) 和若干个监听与被观测对象相关的事件的观察者 (observer), 当一个与被观测对象相关的事件发生时,观测者会接受到该事件的消息通知,并且根据程序的业务逻辑执行后续操作。与 Java SE 中的 event-listener 框架相同 , 在 Vaadin 中 , 观测者被称作监听器 (listeners),而被观测者通常为程序中的 UI 组件。
在 Vaadin 中,Listener 由 AbstractComponent类管理 , 这个类是所有 UI 组件的父类,任何与 UI 组件相关的事件都可以被 Listener 监听。监听器通过方法addListener()被直接注册到 UI 组件上。大多数的的 UI 组件都有自己特定的事件类和事件监听接口。例如,Button类中有Button.ClickEvent事件来代表点击按钮的 UI 操作,这个事件可以被监听器接口 Button.ClickListener监听并处理。使用这种机制,Vaadin 应用程序可以在类的层面监听并区别各种不同种类的事件。清单 2 是一个使用 Button.ClickListener 监听器的代码示例,在这个例子中,当监听器收到一个左键点击的事件后,显示一个被隐藏的窗口控件。
import com.Vaadin.Application; import com.Vaadin.ui.*; import com.Vaadin.ui.Button.ClickEvent; public class Dw_Vaadin_projectApplication extends Application { Window window; public void init() { Window main = new Window("Dw_Vaadin_project Application"); setMainWindow(main); window=new Window("Sub Window"); main.addWindow(window); window.setVisible(false); Button button=new Button("Show window once"); /*... 在 Button 上注册左键点击监听器 ...*/ button.addListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { window.setVisible(true); } }); main.addComponent(button); } } |
Listener 接受到的 Event 对象中还包含了对发送事件的 UI 组件 Java 对象的引用,利用这个引用,可以使用一个监听器进行多个相同类型 UI 控件的事件处理。清单 3 中的方法 1演示了如何使用同一个监听器来处理两个不同 Button 控件的鼠标点击事件。另一种在同一个类中监听多个事件源的方法是使用 addListener() 方法将一个事件监听方法 ( 而不是监听器类 ) 直接注册在 UI 组件上。清单 3 中的方法 2是使用这种处理方式的代码示例。
/*... 方法 1 ... */ public class TheButtons implements Button.ClickListener { Button button1; Button button2; /*... 在给定的容器中创建 2 个 Button 控件 ... */ public TheButtons(AbstractComponentContainer container) { button1 = new Button ("Button1"); button1.addListener(this); container.addComponent(button1); button2 = new Button ("Button2"); button2.addListener(this); container.addComponent (button2); } /*... 在同一个监听器中处理多个 Button 对象的点击事件 ...*/ public void buttonClick (Button.ClickEvent event) { if (event.getButton() == button1){ /*... 对 button1 对象的点击事件处理逻辑 ...*/ }else if (event.getButton() == button2){ /*... 对 button2 对象的点击事件处理逻辑 ...*/ } } } /*... 方法 2 ... */ public class TheButtons { Button button1; Button button2; /*... 在给定的容器中创建 2 个 Button 控件 ... */ public TheButtons(AbstractComponentContainer container) { button1 = new Button ("Button1"); button1.addListener(Button.ClickEvent.class, this,"theButton1Click"); container.addComponent(button1); button2 = new Button ("Button2"); button2.addListener(Button.ClickEvent.class, this,"theButton2Click"); container.addComponent (button2); } public void theButton1Click (Button.ClickEvent event) { /*... 对 button1 对象的点击事件处理逻辑 ...*/ } public void theButton1Click (Button.ClickEvent event) { /*... 对 button2 对象的点击事件处理逻辑 ...*/ } } |
通常情况下事件是由 Vaadin 框架根据用户操作来发出的,但是在某些应用场景中需要应用程序自身来发出这些事件 ( 例如需要在没有用户操作的情况下自动更新 UI 界面的一部分 ),在这种情况下可以使用AbstractComponent的 fireEvent(Component.Event)方法来触发需要的事件。在这个方法执行后所有相应的监听器都将收到这一事件的触发通知。某些 UI 组件拥有一些默认的事件类型 ( 例如 Button 拥有内建的 Button.ClickEvent 事件和相应的 Button.ClickListener 监听器接口 ), 可以使用fireComponentEvent()方法来触发这些组件内置的事件。
Vaadin 的数据模型和数据绑定
Vaadin 的数据模型是整个 Vaadin 框架中的一个核心概念,使用这一模型可以将应用程序的数据源直接和 UI 界面组件绑定在一起,这样数据源中的数据可以直接在 UI 界面上显示或修改,无须通过中间层的转接。如图 10 Vaadin 数据模型的结构图所示 ,Vaadin 的数据模型包含三层嵌套的抽象对象:property,item和container。整套模型的实现位于包 com.Vaadin.data中。由接口 Property,Item,Container和其他一系列更加细化的接口和类组成。数据模型本身并不定义数据的表现形式而只是一些接口定义。具体的表现形式需要由容器的实现来定义。实现的形式可以是多种多样的,例如 Java POJO 对象,文件系统或是数据库查询等方式。Vaadin 框架提供了这几个接口的一些内置实现类来作为 UI 组件的默认数据模型。下面对这些接口和实现类做一简要介绍。
/*... 创建一个 Property 对象 (TextField 实现了 Property 接口 )... */ TextField tf = new TextField("Name"); /*... 为 Property 对象赋值 ... */ tf.setValue("The text field value"); /*... 设定监听器来处理 Property 对象值的变化 ... */ tf.addListener(new Property.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { /*... 读取 Property 对象的值并适当转型 ... */ String value = (String) tf.getValue(); } }); |
PropertysetItem item = new PropertysetItem(); item.addItemProperty("Name", new ObjectProperty("Wangychu")); item.addItemProperty("Age", new ObjectProperty(30)); /*... 绑定到 Form 组件上 ... */ Form form = new Form(); form.setItemDataSource(item); |
IndexedContainer ic = new IndexedContainer(); /*... 设定 Container 中 Item 的属性名称 ... */ ic.addContainerProperty("First Name", String.class, null); ic.addContainerProperty("Last Name", String.class, null); /*... 填充 Item 数据 ... */ ic.addItem(new Object[] {"FirstName1","LastName1"}, new Integer(1)); ic.addItem(new Object[] {"FirstName2", "LastName2"}, new Integer(2)); ic.addItem(new Object[] {"FirstName3","LastName3"}, new Integer(3)); /*... 将 Container 数据绑定到 Table UI 控件上 ... */ Table nameList = new Table(); nameList.setContainerDataSource(ic); |
结束语
本文是系列文章《 Vaadin- 来自北欧的 Web 应用开发利器》的第 1 部分 , 在这一部分中介绍了 Vaadin 的历史和基本功能,并且介绍了 Vaadin 开发环境的配置和基础的开发技术。通过阅读本文,读者能够对 Vaadin 这一优秀的基于 Java 技术的 RIA 开发框架有一个基本的了解,并且能够进行基本的系统开发。在第 2 部分中将会向您深入介绍 Vaadin 框架的体系结构、应用运行时的机制以及如何使用 Vaadin 的 Add-On 插件来扩展已有系统的功能。