Solaris, Java, JavaFX

星期一 九月 28, 2009

在线JavaFX应用完整例子:许愿树网络版

作为富互联网应用(Rich Internet Application)的开发语言JavaFX,其主要的技术特点在Rich和Internet上,即展现丰富的客户端和强互联能力。我把前段时间编写的单机版JavaFX许愿树改成了网络版,成为了三层架构的应用。如下图,展现层是JavaFX的富客户端,中间层是Web Server和PHP程序,数据库层是MySQL。


在这个网络版许愿树的应用中,不同的人可以通过互联网在许愿树上面挂上自己的愿望星,大家看到的都是同一棵树。请你点击下面截图来试试最新联网版的许愿树,需要输入email地址,这样可以修改愿望,每个人请最多留一个愿望:

我们一起来看看程序代码。客户端的GUI部分的JavaFX代码和单机版的基本一样,已在前几篇文章中介绍了(参见文末的链接)。这个版本增加了与server通信的部分,实现上采用了JavaFX 1.2的HttpRequest类。Server的数据采用了JSON的格式(一种基于JavaScript的对象表达形式),在客户端可用javafx API提供的PullParser class来解析。(US Immigration Application forms)


首先,我们看看客户端启动后首次加载愿望星数据的代码。在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;

      // This code is from http://www.javafxblogs.com
      // 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() {  // http://www.javafxblogs.com
    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是星星的颜色编码,其它属性都比较一目了然(http://www.javafxblogs.com ) :
{
 "Star": {
   "name" : "John Smith",
   "content" : "This is a wish from http://www.javafxblogs.com",
   "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 from http://javafxguy.javaeye.com",
   "id" : "3",
   "location" : "288.0_238.0",
   "time": "2009-07-18 18:38:28",
   "color": 4
 }
}


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

/*
 * ServerConnector.fx
 * @author Henry Zhang   http://www.javafxblog.com http://developers.sun.com.cn/blog/henry
 */
package wishtree;
import java.net.URLEncoder;
import java.io.*;
import javafx.io.http.*;

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的Effect功能例子:编写许愿树程序(1)
JavaFX的Effect功能例子:编写许愿树程序(2)
JavaFX的Effect功能例子:编写许愿树程序(3)
在JavaFX中的菜单
JavaFX技巧:Java调用JavaFX例子
JavaFX中菜单
Swing中调用JavaFX
纯Java代码调用JavaFX JavaFX Online Game Example


其它文章:
NASCAR Diecast Car
NASCAR Kasey Kahne Diecast Car NASCAR Diecast Car Kevin harvick NASCAR Diecast Car Jimmie Johnson
US Immigration Forms and Application
Free US Citizenship Practice Test American Citizenship Application Forms


评论:

发表一条评论:
该日志评论功能被禁用了。

Calendar

Feeds

Search

Links

Navigation

Referrers