使用 jMaki 技术构建 Web 2.0/Ajax 应用程序

Sang Shin, sang.shin@sun.com, Sun Microsystems, www.javapassion.cn


借助 jMaki,Java 开发人员可以在基于 Java 的应用程序中将 JavaScript 作为 JSP 标记库或 JSF 组件使用。jMaki 融合了 Java 和 JavaScript 的优势,旨在交付富 Ajax 样式的部件。目前,jMaki 为许多组件提供了引导部件,这些组件包括 Dojo、Script.aculo.us、Yahoo UI 部件、Spry、DHTML Goodies 和 Google。jMaki 为这些部件库提供了一个公共接口并允许开发人员在同一个页面一起使用这些库。

您将通过本动手实验室了解如何使用 jMaki 部件开发基于 AJAX 的、快速响应的交互式 Web 应用程序。本文档旨在帮助您尽快入门。


预计时间:120 分钟

前提条件

本动手实验室假定您拥有以下技术的基本知识或者具备相关编程经验:

软件需求

在开始之前,您需要在计算机上安装以下软件。请注意本实验室要求的软件版本是 NetBeans IDE 5.5。如果您的计算机上只有 NetBeans IDE 5.0,就需要安装 NetBeans 5.5。在安装 NetBeans IDE 5.5 之前不必卸载 NetBeans IDE 5.0。NetBeans IDE 5.0 和 NetBeans IDE 5.5 可以共存在一台计算机上而不会有任何问题。



变更记录



实验室练习


下载并安装上述软件之后,完成本动手实验室内容将不再需要网络连接。

练习 0:安装和配置

在本练习中,先要安装 jMaki NetBeans 插件。也要将 Mozilla Firefox 浏览器配置为 NetBeans IDE 的缺省浏览器。在开始之前,要保证您已经下载并安装了 上述软件

    1. 在 NetBeans IDE 5.5 中安装 jMaki NetBeans 插件
    2. 将 Firefox 浏览器配置为 NetBeans IDE 的缺省浏览器(如果尚未这样做)
    3. 在 Firefox 浏览器中安装 FireBug 调试器(如果尚未这样做)

(0.1) 在 NetBeans IDE 5.5 中安装 Maki NetBeans 插件


1. 下载并保存 jMaki NetBeans IDE 5.5 插件(如果尚未这样做)或使用下面动手实验室压缩文件中包含的那个。 2. 启动 NetBeans IDE 5.5。3. 从菜单栏选择 Tools并选择 Update Center。(如图 0.10 所示)


图 0.10:选择 Update Center

4. 由于要安装手动下载的模块,请选择 Install Manually Downloaded Modules(.nbm Files) 。单击 Next。(如图 1.32 所示)


图 0.11:选择手动安装插件

4. 单击 Select Modules to Install (Continued) 页面的 Add 按钮。出现了 Select Directory or .nbm Files 对话框。(如下图 0.12 所示)
5. 浏览至已下载 org-netbeans-modules-sun-jmaki.nbm 文件的目录。(如下图 0.12 所示)
6. 选择 org-netbeans-modules-sun-jmaki.nbm。单击 确定 按钮。(如图 0.12 所示)


图 0.12:选择 org-netbeans-modules-sun-jmaki.nbm 文件

6. 在 Select Modules to Install (Continued) 窗格中单击 Next。(如下图 0.13 所示)


图 0.13:  选择 Modules to Install

7. 在 Select Modules to Install 窗格中单击 Next。(如图 0.14 所示)


图 0.14:选择 Modules to Install


故障排除:如果在 Include in Install 窗格下没看到 jMaki project support,且 Next 按钮为灰色,如下图 0.14.1 所示,这意味着您已经在 NetBeans IDE 上安装了 jMaki 插件模块。

解决方案:在继续下面所提到的步骤前,必须卸载之前安装的版本。
图 0.14.1:如果见到上述情形,在继续进行前就必须卸载之前安装的版本。


8. 注意到出现了 License Agreement 对话框。单击 Accept。(如下图 0.15 所示)


图 0.15:License agreement 对话框

9. 注意到出现了一个进度条。单击 Next。(如图 0.16 所示)


图 0.16:Download Modules 页面

10. 注意到出现了 View Certificates and Install Modules 页面。选中 Include 复选框。在 Unsigned Module 对话框中选择 Yes。(下图 0.17 所示)  当前版本为 1.6.9.3(2007 年 4 月 10 日)。


图 0.17:安装插件

10. 单击 完成
11. 您也许会注意到出现了 Restart the IDE 对话框。选择缺省项 Restart the IDE,并单击 确定。(如图 0.18 所示)


图 0.18:Restart the IDE

12.  注意到 NetBeans IDE 得以重启。为检查该模块是否已被安装,请单击顶层菜单的 工具 并选择 Module Manager


图 0.19:启动 Module Manager

13. 展开 AJAX。注意到 jMaki Ajax support 位于此处。在 Module Manager 中单击 关闭。 (将来,如果要卸载一个模块,请选择您想要卸载的模块然后单击对话框右上边的卸载按钮。事实上,在安装一个新版本前将必须卸载之前安装的版本。)  最新的版本是 2007 年 1 月 24 日发布的 1.6.9.3。


图 0.20:Module Manager


(0.2) 将 Firefox 浏览器配置为 NetBeans IDE 的缺省浏览器(如果尚未这样做)


在本步骤中,您将选择 Firefox 浏览器作为 NetBeans IDE 的缺省浏览器。这意味着 NetBeans 每次启动浏览器,显示的都是 Firefox 浏览器。
1. 启动 NetBeans IDE。2. 从 NetBeans IDE 的顶层菜单栏选择 工具。3. 选择 选项。出现 选项对话框。4. 在 Web 浏览器 处选择 Firefox 。5. 单击 确定 关闭 选项对话框。(如图 0.14 所示)


图 0.14:将 Firefox 配置为 NetBeans 的缺省浏览器

(0.3) 在 Firefox 浏览器中安装 FireBug 调试器(如果尚未这样做)


在本步骤中,将把 FireBug JavaScript 调试器安装到 Firefox 浏览器。  对于本实验室中大部分的 JavaScript 调试将使用 FireBug 调试器。

注意:为防止您连接不到网络,本动手实验室压缩文件中提供了 FireBug JavaScript 调试器插件。文件位于 <LAB_UNZIPPED_DIRECTORY>/ajaxjmakiintro/FireBugDebugger/firebug-1.01-fx+fl.xpi。为在 Firefox 浏览器中进行安装,请从顶层菜单中选择 File 并选择 Open File (CTRL+O)。浏览至 firebug-1.01-fx+fl.xpi 文件并打开它。这样即可完成安装 FireBug 调试器。


1. 启动 Firefox 浏览器。2. 在浏览器中进入 FireBug JavaScript Debugger 下载站点。3. 单击 Install Now 链接。(如图 0.15 所示)


图 0.15:安装 FireBug Debugger

4. 在 Software Installation 对话框中单击 Install Now 按钮。(如图 0.16 所示)


图 0.16:Install FireBug Debugger

5. 单击 Restart Firefox。(如图 0.17 所示)


图 0.17:Restart Firefox


                                                                                                                        返回顶部



练习 1:通过 jMaki 演示应用程序探索 jMaki 部件

在本练习中,将构建和运行一个 jMaki 演示应用程序,您可以从中使用并探究各种由 jMaki 技术所支持的部件。此应用程序可以从 此处 在线访问。


(1.1) 构建和运行 jMaki 演示应用程序

0. 启动 NetBeans 5.5 IDE(如果尚未这样做)
1. 创建一个新的 jMaki NetBeans 项目


图 1.10:创建基于现有源代码的 Web 应用程序

图 1.11:选择现有源代码的位置

图 1.12:项目文件夹已经包含 WEB-INF 文件夹

图 1.13:提供一个新的项目文件夹

图 1.14:现有源代码和库窗格

2. 运行项目。


图 1.15:运行 jMakiDemo 项目

图 1.16:jMaki 演示应用程序

                                                                                                                        返回练习顶部

(1.2) 使用 DHTML Goodies 部件

在本步骤中,将使用 DHTML Goodies 部件

1. 尝试 Sliding Menu 部件


图 1.20:Sliding Menu 部件

图 1.21:DHTML Goodies Sliding Menu 测试

2.  试用 Tooltip 部件

图 1.22:Tooltip 测试

3. 改变 Tool Tip 框的消息内容

图 1.23:Tooltip 部件

图 1.24:您自己的工具提示

图 1.25:注意到已使用您自己的工具提示

                                                                                                                        返回练习顶部

(1.3)使用 Dojo 部件


在本步骤中,您将使用 Dojo 部件。
1. 使用 Editable Table 部件

图 1.30:探究 Editable Table 部件

图 1.31:对表格进行排序

图 1.32:编辑表格字段

2. 更改 Editable Table Widget 的表格内容。
图 1.33:Editable 表格部件
{
"columns": { "title" : "Title", "author":"Author", "isbn": "ISBN #", "description":"Description"},
"rows":[
 ['Life is good', 'Doris Chen','441234', 'You must be kidding!'],
 ['Save the earth', 'Me','441322', 'Some long description'],
 ['The Sun rises again','Whoever', '441234','Yes, indeed'],
 ['javapassion.com', 'Sang Shin', '441335', 'Some long description'],
 ['passion', 'Sang Shin', '451335', 'Some long description']
 ]
}
代码 1.34:经过修改的 books.json 的内容

图 1.34:新表格内容

3. 使用 JSF 标签试用 Editable Table 部件
4. 观察使用 JSF 标签的 JSP 页面

图 1.35:etable-jsf.jsp

5. 尝试 Fish Eye List Dojo 部件。
图 1.36:Fish Eye List 部件

6. 再添加几个 Fish Eye List 条目
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %>

<h2>Dojo Fish Eye List Test</h2>
<a href="index.jsp">Back to Samples</a>
<hr>

    <a:ajax name="dojo.fisheye"
            args="{items:[
                  {iconSrc:'images/JayashriVisvanathan.jpg',caption:'Jayashri', index:1},
                  {iconSrc:'images/chinnici.jpg',caption:'Roberto',index:2},
                  {iconSrc:'images/blog_murray.jpg',caption:'Greg',index:3},
                  {iconSrc:'images/edburns.jpg',caption:'Ed',index:4},
                  {iconSrc:'images/icon_browser.png',caption:'You are here!',index:5},
                  {iconSrc:'images/icon_calendar.png',caption:'my caption2',index:6},
                  {iconSrc:'images/icon_update.png',caption:'passion',index:7}
            ]}"

    />


<script type="text/javascript">

  function fisheyeListener(item) {
      var targetDiv = document.getElementById("newpage");
      var responseText = "";
     var index = Number(item.index);
      switch(index){
        case 1:  responseText += '<img src="images/JayashriVisvanathan.jpg"/><p>I am Jayashri Visvanathan and I work on Java Studio Creator. My area of interest/expertise is JSF components. Before I joined Creator team, I used to work on the JSF Reference Implementation (RI). I have been part of JSF team since its inception and have contributed to various releases including the current release JSF 1.2. I was also managing the JSF project on java.net since its launch. Prior to joining the JSF team, I worked on various client and server side web products/technologies within Sun including Mozilla, WebTop Registry Server and HotJava Browser.';
    break;
        case 2:  responseText +='<img src="images/chinnici.jpg"/><p>Roberto Chinnici is a senior staff engineer at Sun Microsystems, Inc. where he works on the Java™ Platform, Enterprise Edition, with particular focus on Web Services and Ease of Development. He is the specification lead for the JAX-RPC 1.1 and JAX-WS 2.0 technologies, both developed under the Java Community Process. He is also Sun\'s principal representative in the Web Services Description Working Group at W3C and has been a member of the WS-I Basic Profile Working Group. Mr. Chinnici holds an M.S. in Computer Science from the University of Milan, Italy.';
    break;
        case 3: responseText += '<img src="images/blog_murray.jpg"/><p>Appointed as AJAX Architect for Sun Microsystems, Greg Murray is deeply involved in the AJAX movement through his participation in the OpenAJAX Alliance and contributions to the Dojo Foundation\'s open-source JavaScript toolkit. Within Sun, Greg lead a grass roots effort advancing the integration of client-side scripting with Java technologies and is the creator and principal architect of Project jMaki. jMaki uses the best parts of Java and the best parts of JavaScript to deliver rich AJAX style widgets through a singe, easy-to-use interface that accesses components from popular widget libraries such as Dojo, Script.aculo.us, Yahoo\'s UI Library, Spry, DHTML Goodies, and Google\'s Web Toolkit. Greg recently contributed to the design and development of the AJAX-based Java Pet Store 2.0 Demo and helped create Java BluePrints solutions for using AJAX with Java technologies.';
    break;
        case 4: responseText += '<img src="images/edburns.jpg"/><p>Ed Burns is a senior staff engineer at Sun Microsystems. Ed has worked on a wide variety of client and server side web technologies since 1994, including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat and, most recently JavaServer Faces. Ed is currently the co-spec lead for JavaServer Faces.  Ed has contributed JSF support to jMaki in the form of bug-fixes, nags, and tersely worded emails.</p>';
    break;
    default: responseText += '单击 on one of the photos above';
    break;
      }
      targetDiv.innerHTML = responseText;
  }
  jmaki.subscribe("/dojo/fisheye", fisheyeListener);
</script>
<p>
<h3><div id="newpage"></div></h3>
代码 1.37:经过修改的 fisheye.jsp

图 1.38:新添加的 Fisheye 条目

7.  尝试其他的 Dojo 部件。                                                                                                                         返回练习顶部

(1.4) 使用其他部件


使用 jMaki 演示应用程序中其他的部件



结束语

在本练习中,您构建和运行了 jMaki 演示应用程序,并通过该应用程序探讨了各种部件的用法。您也了解了这些部件如何由 JSP 和 JSF 标签来表现。   
                                                                                                                                   返回顶部


练习 2:使用各种 jMaki 部件构建您自己的应用程序

在本练习中,您将使用包括 Dojo Fish Eye List 在内的 jMaki 部件构建一个 Web 应用程序。您将了解如何使用部件定制器来配置部件。以及如何为应用程序选择 CSS 布局。

  1. 创建和运行一个使用 jMaki Dojo Fish Eye List 部件的应用程序
  2. 试用部件定制器
  3. 试用各种 CSS 布局

(2.1) 创建和运行一个使用 jMaki Dojo Fish Eye List 部件的应用程序

0. 如果尚未启动 NetBeans IDE 请启动它。
1. 创建一个新的 jMaki NetBeans 项目


图 2.10:创建 Web Application 项目


图 2.11:为项目命名

图 2.12:选择 jMaki Ajax Framework 和 CSS Layout

图 2.13:创建了 jMakiFisheye 项目


故障排除:如果因某种原因看不到组件面板,极有可能是之前关掉了组件面板窗口。
解决方案:为重新打开组件面板,请从顶层菜单选择窗口,再选择组件面板。

2. 将 Dojo Fish Eye List 部件添加到应用程序

图 2.14:Fish Eye List 部件被添加到应用程序

您可能会在没有网络连接的条件下运行该应用程序,请修改 index.jsp 以使用本地图片。

3. 将 images 目录从 jMakiDemo 项目复制到 jMakFisheye 项目中。


图 2.15:复制 images

图 2.16:粘贴 images

4. 修改 Fish Eye jMaki 标签的图片源以使用本地图片。
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<link rel="stylesheet" href="jmaki-standard-no-sidebars.css" type="text/css"></link>

<html>
    <head>
        <title>Page Title</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body>
        <div class="outerBorder">
           
            <div class="header">
                <div class="banner">Application Name</div>
               
                <div class="subheader">
                    <div>
                        <a href="mailto:feedback@youraddress">Feedback</a> |
                        <a href="#">Site Map</a> |
                        <a href="#">Home</a>
                    </div>
                </div> <!-- subheader  -->
            </div> <!-- header -->


            <div class="main">
               
                <div class="content" style="height:400px">
                   
                    Main Content Area
                    <a:ajax name="dojo.fisheye"
                            args="{items:[
                            {iconSrc:'images/icon_browser.png',caption:'browser', index:1},
                            {iconSrc:'images/icon_calendar.png',caption:'calendar', index:2},
                            {iconSrc:'images/icon_email.png',caption:'email',index:3},
                            {iconSrc:'images/icon_texteditor.png',caption:'text editor',index:4},
                            {iconSrc:'images/icon_update.png',caption:'update',index:5}
                    ]}"/>
                   
                </div> <!-- content -->
       
            </div> <!-- main -->
     
        </div> <!-- outerborder -->
    </body>
</html>
代码 2.17:使用本地图片

5. 生成并运行应用程序。
图 2.18:Fish Eye

                                                                                                                        返回练习顶部

(2.2) 试用部件定制器

在本步骤中,您将了解如何通过部件定制器对每个部件进行配置

1. 右键单击部件标签中任意位置并选择 jMaki。(如下图 2.20 所示)


图 2.20:了解 Dojo Fish Eye List 部件的 jMaki 定制器

2. 注意到出现了 dojo.fisheye Customizer 对话框的 属性 窗格。阅读每个参数的 Description。(如图 2.21 所示)


图 2.21:dojo.fisheye Customizer, Properties

3. 单击 Usage标签。(下图 2.22 所示)


图 2.22:dojo.fisheye 的用法

                                                                                                                        返回练习顶部

(2.3)试用各种 CSS 布局


在本步骤中,将尝试使用不同的 CSS 布局的部件。
1. 创建一个新的 jMaki NetBeans 项目

图 2.29:创建一个新 Web 应用程序项目

图 2.30:Three Column 布局

2. 向 Three Column 布局中添加部件

图 2.31:向三栏式 CSS 布局中添加 3 个部件

3.  生成并运行项目

图 2.32:三栏格式

4. 删除部件的 height 属性。
图 2.34:删除 height 属性

5.  单击 全部保存 按钮保存更改。(如下图 2.35 所示)注意您不必重新构建或重新运行该项目。


图 2.35:保存更改

6. 在浏览器中,单击刷新按钮查看更改。(如下图 2.36 所示)


图 2.36:反映出更改


                                                                                                                        返回练习顶部



结束语

在本练习中,您构建和运行了几个使用不同 jMaki 部件的示例应用程序,这些部件可从 jMaki NetBeans 插件中获得。您也尝试了不同的 CSS 布局。

                                                                                                                        返回顶部




练习 3:使用 Publish 和 Subscribe 机制处理 jMaki 部件事件

在本练习中,您将了解如何通过使用 jMaki 框架的 "发布和订阅" 机制对应用程序的 jMaki 部件事件进行响应,从而实现部件处理程序。在本练习中,先要修改您在 练习 2 中创建的 fisheye 部件,其中,它将自己作为主题发布给能够订阅它的独立应用程序。稍后您将在应用程序中订阅该主题。

<致谢> 该练习基于 "Handling jMaki Widget Events Using the Publish and Subscribe Mechanism" 一文 发布于 java.net。

  1. 打开 "jMakiFisheye" NetBeans 项目
  2. 发布主题:修改 jMaki Fish Eye List 部件的模板文件
  3. 订阅主题
  4. 编译和运行项目


(3.0) 打开 "jMakiFisheye" NetBeans 项目

本步骤假定您已经如 练习 2 步骤 1 所述创建了 jMakiFisheye 项目。 如果 jMakiFisheye 项目已经处于打开状态,刚完成练习 2 时即如此,那么略过这一步到步骤 3.1。

0. 启动 NetBeans IDE。1. 选择 文件->打开项目(Ctrl+Shift+O)。此时将出现 打开项目 对话框。2. 向下浏览至在 练习2 中创建的  jMakiFisheye 项目的目录中。3. 选择 jMakiFisheye.
4. 单击 打开项目文件夹


(3.1) 发布主题:修改 jMaki Fisheye 部件的模板文件


在本步骤中,您将修改 fisheye 部件的模板文件 comment.js,来发布合适内容到主题。针对 fisheye 部件,需要指定用户选定的图标,以便应用程序能够对用户单击图标这一事件进行适当的响应。

1. 根据代码 3.21 修改 jMakiFisheye->Web 页->resources->dojo->fisheye 下的 component.js。需要添加的代码段突出显示为 蓝色粗 体字。需要取消注释的代码段突出显示为 红色粗 体字。 

dojo.require("dojo.widget.FisheyeList");

// define the namespaces
if (!jmaki.widgets.dojo) {
    jmaki.widgets.dojo = {};
}

jmaki.widgets.dojo.fisheye = {};

jmaki.widgets.dojo.fisheye.Widget = function(wargs) {

    // create the top level widget
    var container = document.getElementById(wargs.uuid);
    var dynaCallback = null;

    if (typeof _globalScope.DynaFaces != 'undefined') {
      // Find the form for this widget
      var containerForm  = container;
      while (null != containerForm &&
         -1 == containerForm.tagName.toLowerCase().indexOf("form")) {
          containerForm = containerForm.parentNode;
      }
      // Save it on the widget so we have access to it in the listener.
      wargs.form = containerForm;
    }

    var orientation = "horizontal";
    var labelEdge = "bottom";
    var items = ["item1","item2","item3"];

    if (typeof wargs.args != "undefined") {
        if (typeof wargs.args.orientation != "undefined"){
           orientation = wargs.args.orientation;
           if (orientation == "vertical") {
               labelEdge = "right";
           }
        }
        if (typeof wargs.args.labelEdge != "undefined"){
               labelEdge = wargs.args.labelEdge;
        }
       
        if (typeof wargs.args.topic != "undefined") {
            topic = wargs.args.topic;
        }
        if (typeof wargs.args.items != "undefined") {
            items = wargs.args.items;
        }
    }
    var fishEye =  dojo.widget.createWidget("FishEyeList",
        {     orientation : orientation,
            itemWidth:50,
            itemHeight:50,
            itemMaxWidth:200,
            itemMaxHeight:200,
            effectUnits:2,
            itemPadding:10,
            attachEdge:"top",
            labelEdge:labelEdge,
            enableCrappySvgSupport:false
        }, container);

    // default topic
    var topic = "/dojo/fisheye";
    // default values

    // programtically add FisheyeListItem children to the widget
    var counter = 0;
    while (true) {
        var i = items[counter++];
        if (i == null) break;
        var icon = dojo.widget.createWidget("FisheyeListItem", i);

        icon.on单击 = function () {
            //jmaki.publish(topic, {target:this, wargs:wargs});
            jmaki.publish(topic, this);
        }
        fishEye.addChild(icon);
    }

     this.destroy = function() {
        if (dynaCallback != null) {
            jmaki.unsubscribe("/dojo/fisheye", dynaCallback);
        }
     }
}
代码 3.21:经过修改的 component.js

如以上代码所示,脚本为 fisheye 中的每个图片创建一个新的图标部件。 调用中的 i 变量是要创建图标部件,带有从部件标签中传入的属性集(在 ajax fisheye 标签中回调 items 数组)。在 onclick 函数中,脚本调用了 publish 方法来传递主题,即 "dojo/fisheye",图标部件对单击的图标进行响应。包含所有传自标签的属性的图标正是发布的内容。
此时,应用程序可以订阅该主题。下一步描述如何订阅。
                                                                                                                        返回练习顶部


(3.2) 订阅主题:修改项目的 index JSP 文件


为订阅一个主题,应用程序需要完成两件事: 1.在 jMakiFisheye->Web 页 下修改 index.jsp 。需要添加的代码段突出显示为 蓝色粗 体字,如以下代码 3.32 所示。

<%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<link rel="stylesheet" href="jmaki-standard-no-sidebars.css" type="text/css"></link>

<html>
    <head>
        <title>Page Title</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body>
        <div class="outerBorder">
           
            <div class="header">
                <div class="banner">Application Name</div>
               
                <div class="subheader">
                    <div>
                        <a href="mailto:feedback@youraddress">Feedback</a> |
                        <a href="#">Site Map</a> |
                        <a href="#">Home</a>
                    </div>
                </div> <!-- subheader  -->
            </div> <!-- header -->


            <div class="main">
               
                <div class="content" style="height:400px">
                   
                    Main Content Area
                    <a:ajax name="dojo.fisheye"
                            args="{items:[
                            {iconSrc:'images/icon_browser.png',caption:'You are here!', index:1},
                            {iconSrc:'images/icon_calendar.png',caption:'my caption2', index:2},
                            {iconSrc:'images/icon_email.png',caption:'email',index:3},
                            {iconSrc:'images/icon_texteditor.png',caption:'text editor',index:4},
                            {iconSrc:'images/icon_update.png',caption:'passion',index:5}
                    ]}"/>
                   
                    <script type="text/javascript">
                   
                       function fisheyeListener(item) {
                           var targetDiv = document.getElementById("newpage");
                           var responseText = "";
    
                           var index = Number(item.index);
                           var caption = item.caption;
    
                           switch(index){
                              case 1:  responseText += '<img src="images/icon_browser.png"/><p>Caption is '+caption+'!';
                                        break;
                              case 2:  responseText += '<img src="images/icon_calendar.png"/><p>Caption is '+caption+'!';
                                        break;
                              case 3:  responseText += '<img src="images/icon_email.png"/><p>Caption is '+caption+'!';
                                        break;
                              case 4:  responseText += '<img src="images/icon_texteditor.png"/><p>Caption is '+caption+'!';
                                        break;
                              case 5:  responseText += '<img src="images/icon_update.png"/><p>Caption is '+caption+'!';
                                        break;
                              default: responseText += '单击 on one of the photos above';
                                        break;
                           }
                           targetDiv.innerHTML = responseText;
                      }
                      jmaki.subscribe("/dojo/fisheye", fisheyeListener);

                    </script> 

                    <h3><div id="newpage"></div></h3> 
             
                </div> <!-- content -->
      
            </div> <!-- main -->
    
        </div> <!-- outerborder -->
    </body>
</html>
代码 3.32:监听器函数被添加到 index.jsp 中

注意到,由 JavaScript 函数 fisheyeListener 传入的 item 包含图片图标的所有属性。您可以从 item 属性中获取数组条目属性,如图标 index 数和标题 name
注意到有一个函数 fisheyeListener 订阅 "/dojo/fisheye" 主题。当用户单击一个图片图标时,该图片和与图标匹配的消息显示在同一页面中。index 号被用来标识每个图片图标。
经过修改的 index.jsp 如下图 3.33 所示。(为最大化窗口,请双击 index.jsp 标签。再次双击将最小化窗口。)


图 3.33:经过修改的 index.jsp 文件

                                                                                                                        返回练习顶部


(3.3) 编译和运行项目


1. 右键单击 jMakiFisheye 项目节点并选择 运行项目。(下图 3.40 所示)
2. 单击其中一个 Fisheye 图标,如本例中的 Calendar 图标。
3.注意更大尺寸的图标显示出来,并伴随在浏览器左下边出现了 Caption is calendar 消息。(如下图 3.30 所示)
4.注意到 glue.js 中的一条警告消息。
下面就是所发生的情况。首先,fisheye 部件呈现的是它本身。用户单击 fisheye 部件中的图标时,该点中图标的所有属性都被发布到主题。然后 JSP 页面会检查图标的 index 属性,找出被点中的是哪个图标,然后用适当的消息替换 div 标签。


图 3.30:单击图片图标后出现了消息和图片


                                                                                                                        返回练习顶部


解决方案


针对此练习的解决方案作为可运行的 NetBeans 项目包含在动手实验室的压缩文件中。项目文件位于 <LAB_UNZIPPED_DIRECTORY>/ajaxjmakiintro/samples/jMakiFisheye-solution. 您可以将其作为一个 NetBeans 项目打开并运行。

结束语


在本练习中,您了解了如何使用发布和订阅机制将事件处理程序添加到 jMaki Fisheye 部件中。
                                                                                                                        返回顶部

 



练习 4:了解 List 部件

在本练习中,您将构建和运行一个使用 List 部件的 jMaki 示例应用程序。然后将介绍 List 部件的构成。本练习选择 List 部件是因为它是最简单的部件之一。在练习 5,您将构建自己的 HelloWorld 部件。

    1. 创建和运行使用 List 部件的 jMaki 应用程序
    2. 深入了解 List 部件
    3. 了解如何使用 List 部件


(4.1)  创建和运行使用 List 部件的 jMaki 应用程序

0. 如果尚未启动 NetBeans IDE 请启动它。
1. 创建一个新的 jMaki NetBeans 项目。


图 4.10:创建 jMakiList 项目

图 4.11:使用 jMaki Ajax Framework
2. 将 jMaki List 部件添加到应用程序

图 4.12:添加了 List 部件

3. 生成并运行该应用程序。
图 4.13:运行使用 List 部件 的 jMaki 应用程序

4. 从清单中删除条目

图 4.14:删除条目

图 4.15:条目被移除

                                                                                                                        返回练习顶部



(4.2)  深入了解 List 部件


在本步骤中,将深入了解以上使用的 List 部件。注意每个部件都是由以下文件组成。
1.  了解 List 部件的构成。
图 4.20:List 部件具有 list 目录,其中包含了必要文件

2. 学习 List 部件的 component.css
component.css 定义了部件的风格。
.plain {
 color: yellow;
 height:25px;
 font-size:18px;
 font-weight: bold;
 font-family: Arial;
 background: blue;
}

.over {
 color: white;
 height:25px;
 font-size:18px;
 font-weight: bold;
 font-family: Arial;
 background: #0099FF;
 cursor: pointer;
}


.listDiv {
 color: blue;
 position: relative;
 width: 300px;
 height: 275px;
 overflow: auto;
}

.listContainer {
 width: 300px;
 height: 275px;
}
代码 4.21:component.css

图 4.22:使用了不同颜色方案

3.学习 List 部件的 component.htm
<学习要点> jMaki 框架给页面中的每个部件实例分配一个 uuid (全球唯一标识符) 。在 component.htm 中,由 ${uuid} 所表示。也要注意 submitData() 定义在 component.js 中,并在用户单击 Add to List 按钮或按 回车 键时被调用。
<div id="${uuid}" class="listContainer">
    <form onsubmit="jmaki.attributes.get('${uuid}').submitData(); return false;">
        <input id="${uuid}_entryField" type="text" size="20" value="Enter new Value">
        <input type="button" onclick="jmaki.attributes.get('${uuid}').submitData(); return false;" value="Add to List">
    </from>
   
    <div id="${uuid}_list" class="listDiv"></div>
</div>
代码 4.22:component.htm

4.学习 List 部件的 component.js
<学习要点>component.js 中有两个函数 —— submitData()removeItem()。submiData() 函数在用户单击 Add to List 按钮时被调用,而 removeItem() 函数则在用户从删除列表中选择条目时被调用。在这两个函数中,XMLHttpRequest 都被用于和后端服务之间进行基于 Ajax 的通信。
// define the namespaces
if (!jmaki.widgets.jmaki) {
    jmaki.widgets.jmaki = {};
}
jmaki.widgets.jmaki.list = {};

jmaki.widgets.jmaki.list.Widget = function(wargs) {
  
    // The uuid variable contains uuid value of the widget instance
    var uuid = wargs.uuid;
    // The service variable contains the value of the service attribute specified, listService.jsp, for example
    var service = wargs.service;
   
    // Create XMLHttpRequest differently depending on the browser type
    function getXHR(url) {

        if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
   
    // submitData() function submits the data entered to the
    // service, listService.jsp.
    this.submitData = function() {
        var list = document.getElementById(uuid + "_list");
        var req = getXHR(service);
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    list.innerHTML = req.responseText;
                }
            }
        };
        req.open("POST", service, true);
        var entryField = document.getElementById(uuid + "_entryField");
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        req.send("command=add&entry=" + entryField.value + "&uuid=" + uuid);
    }
   
    // removeItem() function sends the index of the item
    // for removal
.
     this.removeItem = function(index) {
        var list = document.getElementById(uuid + "_list");
        var req = getXHR(service);
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    list.innerHTML = req.responseText;
                }
            }
        };
        req.open("POST", service, true);
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        req.send("command=remove&index=" + index  + "&uuid=" + uuid);
    }
}
代码 4.23:component.js

                                                                                                                        返回练习顶部


(4.3)  了解如何使用 List 部件


部件在 JSP 页面中是以 JSP 标签(或 JSF 标签)的格式被使用。在本步骤中,您将了解 JSP 标签是如何被用于使用 jMaki 部件。
1. 学习 index.jsp
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %>
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>JSP Page</h1>
       
        <a:ajax name="jmaki.list"   service="listService.jsp"  />
       
    </body>
</html>
代码 4.30:index.jsp

2. 根据代码 4.31 修改 index.jsp。需要修改的代码段突出显示为 蓝色粗 体。做这样的修改主要是为了使用一个名称为 myOwnlistService.jsp 的后端服务来代替 listService.jsp
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %>
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>JSP Page</h1>
       
        <a:ajax name="jmaki.list"   service="myOwnlistService.jsp"  />
       
    </body>
</html>
代码 4.31:经过修改的 index.jsp

3. 创建 myOwnListService.jsp

图 4.32:创建一个新的 JSP 文件
<ol>
<%
java.util.ArrayList list = (java.util.ArrayList)session.getAttribute("list");
String command = request.getParameter("command");
String uuid = request.getParameter("uuid");
String service = request.getParameter("service");

if (list == null) {
    list = new java.util.ArrayList();
    session.setAttribute("list", list);
}

if ("add".equals(command)) {
    String item = request.getParameter("entry");
    // list.add(item);
    list.add(item.toUpperCase());
}

if ("remove".equals(command)) {
    String indexString = request.getParameter("index");
    if (indexString != null) {
        int index = Integer.valueOf(indexString);
        list.remove(index);
    }
}
java.util.Iterator it = list.iterator();
int counter=0;
while(it.hasNext()) {
  out.println("<li><div class=\"plain\" onmouseover=\"this.className ='over';\" onmouseout=\"this.className ='plain';\" onclick=\"jmaki.attributes.get('" + uuid + "').removeItem('" + counter++ + "')\">" + it.next() + "</div></li>");
}
%>
</ol>
代码 4.33:myOwnlistService.jsp

4. 生成并运行应用程序

图 4.34:运行该应用程序的结果

                                                                                                                        返回练习顶部


解决方案


针对此练习的解决方案作为可运行的 NetBeans 项目包含在动手实验室的压缩文件中。项目文件位于 <LAB_UNZIPPED_DIRECTORY>/ajaxjmakiintro/samples/jMakiList-solution. 您可以将它作为 NetBeans 项目打开并运行。 

结束语

在本练习中,您先使用 List 部件构建和运行了一个简单的 jMaki 应用程序。然后了解到部件由三个文件组成 —— component.css 用于风格、component.htm 用于显示和 component.js 用于行为。也了解了如何改变一个现有的部件。在下一个练习中,您将创建自己的部件。

                                                                                                                        返回顶部


练习 5:创建您自己的 HelloWorld jMaki 部件

在本练习中,您将创建一个属于您自己的简单 "HelloWorld" jMaki 部件。"HelloWorld" jMaki 部件是一个具有 AJAX 行为的输入文本字段 —— 无论您在该文本字段中输入什么,都会几乎立即重新显示为 "Hello, <whatever-you-typed>!"。

    1. 创建 "jMakiHelloWorld" 项目
    2. 为 HelloWorld jMaki 部件创建模板文件
    3. 创建 helloService.jsp
    4. 创建 index.jsp
    5. 编译和运行应用程序


(5.1)  创建 "jMakiHelloWorld" 项目


0. 启动 NetBeans IDE 5.5.(如果尚未这样做)
1. 创建一个新的 jMaki NetBeans 项目
                                                                                                                        返回练习顶部


(5.2)  为 HelloWorld jMaki 部件创建 jMaki 模板文件


在本步骤中,您将在 jMakiHelloWorld->Web 页->resources->jmaki->helloworld 目录下创建以下三个模板文件。resources 目录包含所有 jMaki 部件。 1.  在 resources 下创建 helloworld 文件夹

图 5.21:创建一个新文件夹

图 5.22:创建一个新文件夹

图 5.23:创建 helloworld 文件夹

2. 创建 component.htm 模板文件

图 5.24:创建空文件

图 5.25:给出一个文件名
<form>
 <input id="${uuid}_name" type="text" size="20" value="Enter your name"
            onkeyup="jmaki.attributes.get('${uuid}').submitData()">
</from>

<div id="${uuid}_hello" class="helloDiv"></div>
</div>
代码 5.22:HelloWorld jMaki 部件的 component.htm

3.  创建 component.css 文件

图 5.23:创建 component.css
.plain {
 color: black;
 height:25;
 font-size:18px;
 font-weight: bold;
 font-family: Arial;
 background: white;
}

.over {
 color: white;
 height:25;
 font-size:18px;
 font-weight: bold;
 font-family: Arial;
 background: blue;
 cursor: pointer;
}


.helloDiv {
    position: relative;
    width: 400px;
    height: 300px;
    overflow: auto;
}
代码 5.24:HelloWorld jMaki 部件的 component.js

4. 创建 component.js

// define the namespaces
if (!jmaki.widgets.jmaki) {
    jmaki.widgets.jmaki = {};
}
jmaki.widgets.jmaki.helloworld = {};

jmaki.widgets.jmaki.helloworld.Widget = function(wargs) {
    // The jMaki framework must have created widget JavaScript object.
    var uuid = wargs.uuid;
    var service = wargs.service;
  
    function getXHR(url) {
        if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
  
    // This function gets called when a user typed some characters
    // in the input text field whose id is set as ${uuid}_hello in
    // component.htm template file.
    this.submitData = function() {
        var target = document.getElementById(uuid + "_hello");
        var req = getXHR(service);
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    target.innerHTML = req.responseText;
                }
            }
        };
        req.open("POST", service, true);
        var name= document.getElementById(uuid + "_name");
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        req.send("name=" + name.value + "&uuid=" + uuid);
    }
  
}
代码 5.25:HelloWorld jMaki 部件的 component.js

                                                                                                                        返回练习顶部



(5.3) 创建 helloService.jsp


在本步骤中,您将创建一个名称为 helloService.jsp 的服务页面。
1. 创建 helloService.jsp

图 5.30:helloService.jsp

2. 用以下代码 5.31 中的代码替换由 IDE 生成的  helloService.jsp 文件。
<ol>
<%
String name= request.getParameter("name");
out.println("Hello, " + name + "!");
%>
</ol>
代码 5.31:helloService.jsp

                                                                                                                        返回练习顶部

(5.4) 修改 index.jsp


在本步骤中,您将修改 index.jsp,以使用刚刚创建的 HelloWorld jMaki 部件。
1. 根据代码 5.32 修改 jMakiHelloWorld->Web Pages 下的 index.jsp。需要添加的代码段突出显示为蓝色粗体。
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@ taglib prefix="a" uri="http://java.sun.com/jmaki" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>

        <h1>Use my own HelloWorld jMaki widget</h1>
        <a:ajax name="jmaki.helloworld"   service="helloService.jsp"  />

    </body>
</html>
代码 5.32:经过修改的 index.jsp

                                                                                                                        返回练习顶部



(5.5) 保存更改并刷新浏览器


1. 右键单击 jMakiHelloWorld 并选择 运行。2. 在文本字段中,键入如 Sang(不按回车键),如下图 5.50 所示。 
3. 注意到应出现 Hello, Sang! 消息。


图 5.50:注意到键入的值被重新显示

4. 观察请求和响应值。
图 5.51:运行使用 HelloWorld jMaki 部件的应用程序的结果

图 5.52:观察服务器返回值

                                                                                                                        返回练习顶部



解决方案


针对此练习的解决方案作为可运行的 NetBeans 项目包含在动手实验室的压缩文件中。项目文件位于 <LAB_UNZIPPED_DIRECTORY>/ajaxjmakiintro/samples/jMakiHelloWorld-solution. 您可以将其作为一个 NetBeans 项目打开并运行。

结束语


在本练习中,您创建了自己的名称为 helloworld 的 jMaki 部件,并将其用于您的应用程序中。您也通过 Firebug 调试器观察到 helloworld 的基于 Ajax 的响应。


                                                                                                                        返回顶部



课外练习(针对 Sang Shin “AJAX 在线课程” 的学习者)


1. 课外练习是通过对以上创建的 helloworld jMaki 部件略为修改,创建一个新的 jMaki 部件,如下所示:
2. 将以下文件以 AJAXHomework-ajaxjmakiintro 作为 发送主题 发送至 ajaxhomework@sun.com




原文链接: http://www.javapassion.com/handsonlabs/ajaxjmakiintro/