JavaFX多用户在线应用实例:许愿树联机版

分类: JavaFX编程, 许愿树.
标签: ,

JavaFX作为RIA(Rich Internet Application)的开发语言,主要的特点在’R'和’I'两点上,即丰富的客户端和联网的应用。最近我把原来用JavaFX1.1写的许愿树程序改成了联机版,成为了一个3层架构应用,如下图所示,展现层是JavaFX实现的富客户端,中间层是Web Server和PHP,数据库层是MySQL。

这个新的许愿树程序可以让不同的人在许愿树上悬挂自己的愿望星,所有人看到的是同一棵树。你可以点击下图来试试这个最新联网版的许愿树啦,注意要输入email地址,以便以后修改愿望,每个人请最多留一个星星:

在JavaFX客户端的GUI部分,代码基本上和单机版的一样,已经在前面几篇文章中介绍了(参见文末的链接)。在和server通信的过程中采用了JavaFX 1.2的HttpRequest类来实现。Server的数据采用了JSON的格式(一种基于JavaScript的对象表达方式),在客户端可用javafx提供的PullParser类来解析。

首先,我们来看看客户端启动后首次加载数据的代码。在Main.fx中,我们有如下部分的代码:

var parser = PullParser {
    documentType: PullParser.JSON;

    onEvent: function(event: Event) {
      var content: String;
      var name: String;
      var id: String;
      var email: String;
      var color: Integer;
      var time: String;
      var location: String;

      // parse the JSON data and populate object
      if(event.type == PullParser.END_VALUE) {

        if(event.name == "name") {
          star.name = event.text;
        }
        else if ( event.name == "content" ){
          star.wish = event.text;
        }
        else if ( event.name == "id" ){
          star.id = event.text;
         }
        else if ( event.name == "color" ){
          star.whichColor = event.integerValue;
        }
        else if ( event.name == "time" ){
          star.time = event.text;
        }
        else if ( event.name == "location" ) {
          var pos = event.text.indexOf( "_" );
          var x = event.text.substring(0,pos);
          var y = event.text.substring( pos+1 );

          star.translateX = Float.parseFloat(x);
          star.translateY = Float.parseFloat(y);
        }
        else if ( event.name == "Star" ){
          star.changeStatus();
          star.onMousePressed = handleClick;

          insert star after stage.scene.content[currentIndex++];
          star = Star {};
        }

      }
    }
  }

  function getAllStar() {
    request = HttpRequest {
      method: HttpRequest.GET
      location: ServerConnector.serverURL1
      onInput: function(is: InputStream) {
        try {
          parser.input = is;
          parser.parse();
        } finally {
            is.close();
          }
      }
    }

    request.start();
 }

我们创建了一个PullParser的实例,用来分析JSON格式的数据(见后),然后在函数getAllStar()中,HttpRequest实例采用了GET的放式从服务器端获取幸运星的数据,代码很简单,只需要在onInput中把输入流传给parser即可。从Web服务器上传回的JSON数据格式如下,其中id是Server端数据库中唯一的标识,location是星星在窗口中的位置,color是星星的颜色编码,其它属性都比较一目了然:

{
 "Star": {
   "name" : "John Smith",
   "content" : "This is a wish",
   "id" : "2",
   "location" : "300.0_240.0",
   "time": "2009-08-21 17:38:37",
   "color": 3
 },
 "Star": {
   "name" : "Homer Simpson",
   "content" : "This is another wish",
   "id" : "3",
   "location" : "288.0_238.0",
   "time": "2009-07-18 18:38:28",
   "color": 4
 }
}

当客户端从Server数据库中获得了这些星星的数据之后,就可以把之前保存的星星和愿望在树上显示出来了。在用户增加一颗星星之后,客户端会把愿望的数据传到服务器保存起来,采用的是HTTP的POST方式,把相关数据发送出去。代码如下,

/*
 * ServerConnector.fx
 */
package wishtree;

import java.net.URLEncoder;
import wishtree.Star;
import java.io.*;
import javafx.io.http.*;

/**
 * @author Henry Zhang   http://www.javafxblogs.com
 */

var baseURL = "http://localhost:8888/wishtree/";

public var serverURL1 = "{baseURL}getallstar.php";
var serverURL2 = "{baseURL}savestar.php";

public class ServerConnector extends HttpRequest {

  var star : Star = null;
  var paramString : String ;

  override var onOutput = function( os: java.io.OutputStream): Void {
        try {
            os.write(paramString.getBytes());
        } finally {
            os.close();
        }
    };

  override var onInput = function(is: java.io.InputStream) {
     try {
           var br = new BufferedReader( new InputStreamReader( is ) );
           var line: String;

           while ( ( line=br.readLine() ) != null )
           {
             if ( (star != null) and (star.id == "")  )
                star.id = line;
            }
        } finally {
            is.close();
        }
  };

public function saveStar( s: Star ) {
  if ( s.id.length() == 0 )
    star = s;

  paramString = encode("name", s.name);
  paramString += "&{encode("id", s.id)}&" ;
  paramString += encode("location", "{s.translateX}_{s.translateY}" );
  paramString += "&{encode("content", s.wish )}";
  paramString += "&{encode("email", s.email)}" ;
  paramString += "&{encode("time", s.time)}&" ;
  paramString += encode("color", "{s.whichColor}" );

  headers = [
        HttpHeader {
            name: HttpHeader.CONTENT_LENGTH;
            value: "{paramString.getBytes().length}";
        }
       ];

  method = POST;
  location = serverURL2;
  start();
 }
}

function encode( k: String, v:String): String {
    var result = URLEncoder.encode( k, "UTF-8");
    var value = URLEncoder.encode( v, "UTF-8");
    result += "={value}"
}

服务器端的php代码比较简单,这里就不一一介绍了,有兴趣的可以下载代码看看,注意README.txt的说明。如果有什么问题,请留言。

相关文章:

JavaFX技巧:Java调用JavaFX例子

在JavaFX中的菜单

Swing应用中使用JavaFX的功能

用纯Java代码调用JavaFX的功能

JavaFX Multi-User Game Demo

其它:

NASCAR Diecast Car and Drivers Collectibles

NASCAR Driver Tony Stewart Diecast Car

NASCAR Diecast Car Jimmie Johnson NASCAR Diecast Car Dale Earnhardt

New US Citizenship Test Questions

Best Online US Citizenship Practice Test

US Citizenship Application Forms

评论 (0) 2009年08月18日

JavaFX吃豆人游戏在JavaOne上演示

分类: JavaFX新闻, 吃豆人游戏.
标签: , , , ,

JavaOne 2009的内容可以下载了,链接是http://developers.sun.com/learning/javaoneonline/。其中JavaFX的讲座在“Rich Media Applications and Interactive Content”类别中,需要注册一个Sun Developer Network的帐号才能看到这些PDF文件。


JavaOne的演讲者之一Stephen Chin告知,我写的JavaFX Pac-Man(吃豆人)游戏在他的两个讲座中都作了现场演示,非常成功。这个游戏是Jim Weaver提出的一个挑战,他希望我把Pac-Man游戏改写成WidgetFX的widget,Stephen也答应在JavaOne上demo。虽然只有不够一周的时间,但好在WidgetFX的API比较易用,所以我仅用了2天就完成了(详见英文博客Challenge on Pac-Man Game Widget)。等WidgetFX SDK 1.2推出之后,再把代码更新后给大家分享一下。虽然不能亲临JavaOne,但是自己的游戏能登上大讲台,也是件很高兴的事。


JavaOne 吃豆人游戏演示
JavaOne 吃豆人游戏演示



这两个JavaOne演示吃豆人游戏的讲座是:

Pro JavaFX Platform: RIA Enterprise Application Development with JavaFX Technology

Getting Started with WidgetFX: Open-Source Widget Desktop Platform with JavaFX Technology



相关文章:

JavaFX吃豆人游戏编写过程详解(英文)

JavaFX吃豆子游戏编写过程(中文)

评论 (0) 2009年06月16日