Apache Maven 3.1.0 安装、部署、使用

2013-09-03 Java Maven

##一、下载

下载页面http://maven.apache.org/download.cgi 找到最新的 ,本例为Maven 3.1.0

http://mirrors.cnnic.cn/apache/maven/maven-3/3.1.0/binaries/apache-maven-3.1.0-bin.zip

##二、安装

1.解压zip ,将apache-maven-3.1.0文件夹拷贝至C:\Program Files\Apache Software Foundation 目录下

2.在环境变量中添加一个用户变量(如果不成功,也可以添加到系统变量中)

变量:M2_HOME

值:C:\Program Files\Apache Software Foundation\apache-maven-3.1.0

3.在环境变量中的系统变量的path添加一个

%M2_HOME%\bin

4.校验

Cmd 模式下 输入

mvn --version

出现以下画面,则安装成功!

##三、配置

建一个文件夹作为仓位: 我的是在d:\ workspaceMaven

C:\Program Files\Apache Software Foundation\apache-maven-3.1.0\conf目录下找到 settings.xml文件,

打开文件找到被注释的 <localRepository>/path/to/local/repo</localRepository>

将它启动,写上仓库的路径,

即为<localRepository>D:\workspaceMaven</localRepository>

如下效果

打开cmd,输入

mvn help:system

如果配置正确,将开始从中央仓库下载文件至4中配置的本地仓库。该过程持续时间因网络带宽影响可能持续时间很长。

见下图,则配置成功

仓库下会多出很多文件

##四、使用

找一个maven的项目。本例为“cat78”,放到任意目录下

2.cmd 下 执行cd cat78到该目录下

运行

mvn clean compile

此时,项目开始编译

又需要一段时间来下载相关jar包、pom文件

3.编译完成 ,会生产.bat可运行文件,双击运行就行了~

完整的使用教程,请访问使用maven编译Java项目


MySQL 在 Windows 平台下的安装、使用(图解)

2013-08-19 MySQL Windows

一、 首先电脑要具备.Net Framework 4 以上环境 二、 MySQL下载、安装、执行

  1. 下载http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.13-win32.zip
  2. 安装 点击“install MySQL products” 选中“I accept the licence terms”,点击next

选中“Skip the check for updates” ,Next

选中“custom”,Next

Next

Execute

Next

Execute

Next

Next

Next

设置root密码“root”,Next

Next

Next

Next

Finish

  1. 使用 这个是主页面

Databases->Query Database

连接本地实例“Local instance MySQL 56”,OK

填密码,选中保存,OK

输入查询语句,CREATE DATABASE waylau DEFAULT CHARACTER SET ‘utf8’; use waylau; create table users (user_no char(5) not null, user_name char(50) ); 执行

刷新左侧树形栏,出现刚刚执行的库和表,则说明使用成功!!


2013-8-11惠州——三洲田、大梅沙骑行,作业贴,骑行攻略

2013-08-12 Outdoor

这次骑行找不到队友啊,只能独骑闯大梅沙了~
七点出发,经过仲恺、 镇隆镇 、 新圩镇 、 坪地镇基本上九点多到深圳龙岗界内。进行了第一次休整 。
发觉市区的环境确实很恶劣,特别是骑行道,很多障碍。提不起速度。
建议走汽车道。尾气很重,差点熏死我~
在市区内就要开启导航了。因为要转拐的路段较多。
干,竟然走到了绝路,晕。。
经过三洲田大桥就要注意了,因为很快三洲田的入口就要出现了。
有个十字路口,但是 没有提示,左拐过去看了牌子才发现有“东部华侨城”“xx酒店”字样的,就是入
口了。
预示着一段艰辛的爬坡路段开始了......
盘上公路直插云霄啊,喜欢爬坡的车友鸡冻了,有木有......
居然有女汉子。。。猛!
吓尿了吧。。。。。
高架桥攀爬完毕,给小so留个念。
高兴太早了,后面的路段更曲折。
顾不上拍照了,直喘气。神马房车酒店、主题公园、欧式风情、小火车都是一瞟而过。攀顶。攀顶。
见“江山如此多娇”,恭喜,攀顶成功!俯瞰群山和大海吧~
稍作修息,准备下山了。最好先检查刹车,要速降了 。妖~
半山腰,寻一水潭,比较隐蔽,纯天然矿泉水,喝上五瓶先~
正直当午,果断宽衣解带,泡潭咯~ 太凉了,鸡皮疙瘩都起来了。爽!!
爽完就要下山了。速降了,一路刹~车很多,要注意安全。~
下到山脚,左拐 ,沿着海边骑行道走就可以了,可以经过大、小梅沙海滩。
人忒多了,实现没有下海的冲动了。~
很多免费的海滩也很不错哦,好清新
回程了,肚子果断叫唤了,才发觉没有吃午饭,我汗。。。秀色可餐啊~
貌似也过了吃饭的店,饭店没啥吃的了。到葵涌镇补充干粮
其他返程的就不多说了,一路飙回惠州吧》~
另外,回程路上遇上一个骑友,说是要上北京 。吓到,
但看他没有专业的山地车,没有防护装备,坐垫还是棉被裹的,我汗。估计有点悬
他是深圳出发的,要经过惠州,一路看地图找不到路。于是,我他带到惠州。
离别了嘱咐他多跟家人保持联系。长路漫漫多珍重~
总结:龙岗市区环境很恶劣,做好防护准备
从三洲田速降大梅沙的时候,刹车一定要检查好
全程往返170公里左右
花费:
纯天然矿泉水 450 ml * 5 0元
XX糕点 5只装 4元
雪碧2L 8元
康师傅矿泉水550ml 2元
共计: 14元
用最少的钱走最远的路

 


纯AS3项目利用 Adobe AMF3 协议与 Java 交互,示例

2013-08-03 ActionScript3 Java

package 
{ 
    import flash.net.NetConnection; 
    import flash.net.ObjectEncoding; 
    import flash.net.Responder; 

    public class Amf3ServiceInvoker  
    {              

       private var nc : NetConnection = new NetConnection();    
       private var responder : Responder = null; 
       private const amf3URL : String = http://gcc.waylau.com:8080/messagebroker/amf; 

       public function Amf3ServiceInvoker(result : Function, error : Function) 
       {                     
           responder = new Responder(result, error);  
           super(); 
       } 

       public function getWeather2(city: String) : void{ 
           nc.objectEncoding = ObjectEncoding.AMF3;  
           nc.connect(amf3URL);      
           nc.call(amf3ServiceInvoker.getWeather2, responder, city); 
       } 

    } 
}

2013-7-28惠州——东莞大岭山松山湖骑,作业贴,骑行攻略

2013-07-29 Outdoor

一行三人,出门还有丝丝细雨。于是放弃了防晒装备(后面因此付出代价) 骑行的线路大致是酱紫滴 惠州学院对面,华康医院附近出发, 沿演达大道,向北 下演达立交,进入三环南路,经过师大立交,进入仲恺大道 下面的路段,基本上是闭着眼睛也不会走错啦~

补过,过仲恺的时候确实应该发下牢骚, 这路确实是太狗血了~啦~见图~

并且在这途中,还遗失了一位队友, 顶。~

后来 还是 找回来啦~ 咔咔

托了高铁的福,我一直叫他沿着高铁柱子走。~

继续出发

仲恺五路、仲恺六路、仲恺八路,过沥林镇,谢岗镇,樟木头镇,黄江镇一路都是笔直的 樟木头和黄江有一大坡相隔,需要冲坡!!

只要沿着大道走,就不会走X 。 出黄江镇再走一段,就要准备左转了。~ 地图导航显示的位置大概是 金朗南路的杨涌村,往西南方向走, 擦~ 全是 村间小道 ,感觉地图导航坑了我~ 不过经过新马莲村,却意外看到了一池子 好荷花! 正是好景六月中,风光不与四时同也~

一直吧,跨过那漫漫的田野, 擦~ 人迹开始罕见~ 晴空开始骄阳 除了几个工业区。 最后竟然还走到了路的尽头~

。。。汗。没路了后,只好右拐穿过莞佛高速~ 到达东莞水平商贸城,

看地图离目的地址不远,遂先填饱肚子 一碗木桶饭顶住先~

饭饱后继续前行,沿着美景西路(X241) 到达西牛陂广场 ,就要往小路往西走了~

直到 环湖路 环湖路 环的就是松山湖啊 ,亲,差不多到了~

再往西走一段路程,就能看到大门,进了门,就 尽情的绕湖吧~~~~~~~~

景区内还有马术场,不错,威远

回程路线:

绕完湖,沿着大学路朝大朗方向走,

无需约定,路程中,总能相会~

沿美景中路、美景东路,到达大朗镇,

至此与队友分别,

这些哥们实在是顶不住了。 独自再沿金朗中路、黄江方向 直线 飚回惠州, 期间口渴的不行, 买了瓶2L美年达,呼呼一口气干了二分之一,爽啊!!!!!

行吧,最后一张金华火腿

总结: 去程约77公里,全程往返154公里左右(数据来源百度地图) 花费: 康师傅矿泉水550ml 2元 木桶饭 8元 美年达 汽水2L 7元 共计17元


AsWing 应用之JTable的例子

2013-07-26 ActionScript3 AsWing

package
{
	import flash.display.Sprite;
	import org.aswing.ASColor;
	import org.aswing.JScrollPane;
	import org.aswing.JTable;
	import org.aswing.VectorListModel;
	import org.aswing.event.SelectionEvent;
	import org.aswing.table.PropertyTableModel;
	import org.aswing.table.sorter.TableSorter;
	/**
	 * 一个AsWing JTable的例子
	 *@author waylau.com
	 *@data 2013-7-26
	 */
	public class JTableExample extends Sprite
	{
		private var data:Array = [];  //表格数据源
		private var columns:Array = [];  //列项
		private var table:JTable;
		/**
		 * PropertyTableModelJTable的表格模型之一,常常用于把一个对象列表中的对象数据,以对象为行,
		 * 以对象属性为列来显示,它提供默认方式把属性值以直接字符串化显示,也提供转换器(PropertyTranslator Function
		 * 把值转换成期望的字符串格式来显示
		 */
		private var tableModel:PropertyTableModel; 
		/**
		* VectorListModelAsWing自带的ListModel 实现,它的行为类似一个Vector 
		* 可以随意在任何位置插入/删除数据,并且在数据改变时,会自动触发对应的事件,使得JList 自动更新界面显示。
		*/
		private var modeList:VectorListModel; 
		/**
		 * TableSorter表格排序器。它是TableModel 接口的一个实现,通过包装一个现有的 TableModel 来实现排序。
		 * 实现原理为:以选择排序方式为基准,变换原始TableModel 类的行的值,以达到变换行顺序的目的。
		 * 排序所采用的值比较函数,可以通过给指定列设定列类型,然后给指定列类型设定比较函数来达到。
		 * 默认情况下,所有列的类型都是Object 类型,TableSorter 自带String Number 类型的比较函数,
		 * 对于没有指定比较函数的列,默认将采用String 类型的比较函数
		 */
		private var sorter:TableSorter;

		public function JTableExample()
		{
			super();
			init();
		}

		private function init():void
		{		
			this.stage.frameRate = 25;
			data = [{name:"iiley", sex:1, age:26, score:99},
				{name:"Comeny", sex:0, age:24, score:100},
				{name:"Tom", sex:1, age:30, score:98},
				{name:"Lita", sex:0, age:16, score:36}]
			;
			modeList = new VectorListModel(data);
			columns = ["Name", "Sex", "age", "Score"] ;
			tableModel = new PropertyTableModel(modeList,columns,["name","sex","age","score"],[null,sexTranslator,null,null,]);
			sorter = new TableSorter(tableModel);

			this.table = new JTable(sorter);
			this.table.setRowHeight(22);
			//水平间隔线
			table.setShowHorizontalLines(false);
			//竖直间隔线
			table.setShowVerticalLines(false);
			//设置字体颜色,前景色
			 table.setForeground(new ASColor(0xffffff));
			//设置选中行的时候的字体颜色
			table.setSelectionForeground(new ASColor(0x123456));
			//拉伸的模式,随意拉伸
			this.table.setAutoResizeMode ( JTable.AUTO_RESIZE_OFF );
			//只能选择一行
	 		this.table.setSelectionMode ( JTable.SINGLE_SELECTION );
			//设置表格底色
			this.table.setBackground(new ASColor(0x000000));
			//设置监听row选中
			this.table.addEventListener(SelectionEvent.ROW_SELECTION_CHANGED,__rowSelectHandler);

			var panel:JScrollPane = new JScrollPane();
			panel.setSizeWH(200, 100);
			panel.append(this.table);
			this.addChild(panel);
		 	panel.validate();
		}
		/**
		 * row选择执行事件
		 */
		private function __rowSelectHandler(e:SelectionEvent):void
		{
			var rowCount : int = this.table.getSelectedRow();

			if(rowCount&gt;0)
			{
				var row:Object = modeList.getElementAt(sorter.modelIndex(rowCount));
			}
			if(row!=null)
			{
				trace("Human"+" Name:"+row.name+",Sex:"+row.sex+",Age:"+row.age+",Score:"+row.score);
			}
		}
		/**
		 * 性别转换器
		 */
		private function sexTranslator(info:*, key:String):String
		{
			if(info[key]=="1")
			{
				return "男";
			}
			else
			{
				return "女";
			}
		}
	}
}  参考:

http://www.aswing.org/?tag=jtable

http://wiki.9ria.com/index.php/Aswing

http://www.ebibi.com/i/study/2010/0913/1262.html


纯AS3项目导入fl包的方法以及fl.controls.DataGrid的详细应用

2013-07-05 ActionScript3

在Flash CS4中打开“D:\Program Files\Adobe\Adobe Flash CS4\Common\Configuration\Components\”目录下的“User Interface.fla”文件 进入文件—发布设置—Flash—勾选“导出SWC” 点“导出影片”,输入文件名,确定之后就出现了swc文件 进入Flash builder,在ActionScript项目属性中引用刚刚导出的swc文件 这时就可以在源代码中 import fl.controls.* 并使用Flash CS4中的UI组件了

另外fl.controls.DataGrid的详细应用

参见:http://edutechwiki.unige.ch/en/Flash_datagrid_component_tutorial

http://crazyrabbit.blogbus.com/logs/38711416.html


AS3使用thrift的与JHava servlet服务器端通信

2013-06-22 ActionScript3 Java

##一、基本概念

Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。

Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

官网地址:http://thrift.apache.org

###1.数据类型

基本类型: bool:布尔值,true 或 false,对应 Java 的 boolean byte:8 位有符号整数,对应 Java 的 byte i16:16 位有符号整数,对应 Java 的 short i32:32 位有符号整数,对应 Java 的 int i64:64 位有符号整数,对应 Java 的 long double:64 位浮点数,对应 Java 的 double string:utf-8编码的字符串,对应 Java 的 String 结构体类型: struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean 容器类型: list:对应 Java 的 ArrayList set:对应 Java 的 HashSet map:对应 Java 的 HashMap 异常类型: exception:对应 Java 的 Exception 服务类型: service:对应服务的类

###2.服务端编码基本步骤:

实现服务处理接口impl 创建TProcessor 创建TServerTransport 创建TProtocol 创建TServer 启动Server 3.客户端编码基本步骤:

创建Transport 创建TProtocol 基于TTransport和TProtocol创建 Client 调用Client的相应方法 4.数据传输协议

TBinaryProtocol : 二进制格式. TCompactProtocol : 压缩格式 TJSONProtocol : JSON格式 TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析 tips:客户端和服务端的协议要一致

##二、as3与java通信示例

test.thrift namespace java com.xzw.thrift namespace as3 com.xzw.thrift struct User{ 1:i32 userId, 2:string loginName, 3:string password, 4:string name }

exception UserNotFound{ 
    1:string msg  //as3中由于message是关键字,所以避免使用message关键字。 
} 

service UserService{ 
    User getUser(1:string loginName) throws (1:UserNotFound unf), 
    list&lt;User&gt; getUsers() 
}  通过命令生成java代码

thrift –gen java test.thrift

以上命令会生成gen-java的目录拷贝里面的代码到你的项目中。如图com.xzw.thrift就是

工具生成java类。

其中我们需要去实现UserService类中的IFace接口。代码如下: /* * To change this template, choose Tools Templates * and open the template in the editor. */ package com.xzw.service;
import com.xzw.thrift.User; 
import com.xzw.thrift.UserNotFound; 
import com.xzw.thrift.UserService; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.logging.Logger; 
import org.apache.thrift.TException; 

/** 
 * 
 * @author xzw 
 */ 
public class UserServiceHandler implements UserService.Iface{ 

    public User getUser(String loginName) throws UserNotFound, TException { 
        if(!"xuzhiwei".equals(loginName)){ 
            UserNotFound e = new UserNotFound("用户无法找到!"); 
            throw e; 
        }  
        User user = new User(); 
        user.setUserId(100); 
        user.setLoginName("xuzhiwei"); 
        user.setPassword("123456"); 
        user.setName("user1"); 
        Logger.getLogger("user=&gt;"+user.toString()); 
        return user;  
    } 

    public List&lt;User&gt; getUsers() throws TException { 
       List&lt;User&gt; list = new ArrayList&lt;User&gt;();   
        User user = new User();   
        user.setUserId(100);   
       user.setLoginName("xuzhiwei"); 
        user.setPassword("123456"); 
        user.setName("user1");   
        list.add(user);   
        User user2 = new User();   
        user2.setUserId(200);   
        user2.setLoginName("login2");   
        user2.setPassword("pwd2");   
        user2.setName("user2");   
        list.add(user2);   

         Logger.getLogger("user list=&gt;"+list.toString()); 
        return list;   
    } 

}
编写servlet,servlet需要继承thrift提供的类包TServlet即可,不需要去重写doGet,doPost方法。 /* * To change this template, choose Tools Templates * and open the template in the editor. */ package com.xzw.service;
import com.xzw.thrift.UserService; 
import org.apache.thrift.protocol.TBinaryProtocol; 
import org.apache.thrift.server.TServlet; 

/** 
 * 
 * @author xzw 
 */ 
public class UserServlet extends TServlet{   

     public UserServlet(){   
         super(new UserService.Processor(new UserServiceHandler()),new TBinaryProtocol.Factory(true, true)); 
     }        
}

以上就完成服务器端的编写了。

可以使用junit测试一下: /* * To change this template, choose Tools Templates * and open the template in the editor. */
import com.xzw.thrift.User; 
import com.xzw.thrift.UserService; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import org.apache.thrift.TException; 
import org.apache.thrift.protocol.TBinaryProtocol; 
import org.apache.thrift.protocol.TProtocol; 
import org.apache.thrift.transport.THttpClient; 
import org.junit.*; 

/** 
 * 
 * @author xzw 
 */ 
public class TestServlet { 

     @Test 
    public void test(){ 
        String serveltUrl = "http://localhost:8080/test_thrift/userServlet"; 
        try { 
            THttpClient thc = new THttpClient(serveltUrl); 
            TProtocol lopFactory = new TBinaryProtocol(thc); 
           UserService.Client client = new UserService.Client(lopFactory); 

           List users = client.getUsers(); 
           System.out.println("--&gt;&gt;"+users.toString()); 
        } catch (TException ex) { 
            Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex); 
        } 
   } 

    @Test 
    public void test2(){ 
        String serveltUrl = "http://localhost:8080/test_thrift/userServlet"; 
        try { 
            THttpClient thc = new THttpClient(serveltUrl); 
            TProtocol lopFactory = new TBinaryProtocol(thc); 
           UserService.Client client = new UserService.Client(lopFactory); 

           User user = client.getUser("xuzhiwei"); 
           System.out.println("--&gt;"+user.toString()); 
        } catch (TException ex) { 
            Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex); 
        } 
   } 
}

接下来生成as3代码

thrift –gen as3 test.thrift www.it165.net

以上代码会生成gen-as3的目录,拷贝目录下的代码到你的工程中。

编写as3客户端类:

package { 
import com.xzw.thrift.User; 
import com.xzw.thrift.UserNotFound; 
import com.xzw.thrift.UserService; 
import com.xzw.thrift.UserServiceImpl;

    import flash.display.Sprite; 
    import flash.net.URLRequest; 
    import flash.text.TextField; 

    import org.apache.thrift.protocol.TBinaryProtocol; 
    import org.apache.thrift.protocol.TProtocol; 
    import org.apache.thrift.transport.THttpClient; 

    public class testthrift extends Sprite 
    {  
        private const SERVER_URL:String = "http://localhost:8080/test_thrift/userServlet";  
        private var textField:TextField; 

        public function testthrift() 
        {  
            init(); 
            connServer();  
        } 

        private function init():void 
        { 
            textField = new TextField();  
            textField.width = 300; 
            textField.height = 500;  
            textField.autoSize = "left"; 
            addChild(textField); 
        } 

        private function connServer():void 
        {   //实例化URLRequest 
            var urlRequest:URLRequest = new URLRequest(SERVER_URL); 
            //实例化THttpClient 
            var thc:THttpClient = new THttpClient(urlRequest); 
            var protocol:TProtocol = new TBinaryProtocol(thc); 

            var usImpl:UserService = new UserServiceImpl(protocol); 
            usImpl.getUser("xuzhiwei",onError,onUserSuccess); 
            //usImpl.getUsers(onError,onSuccess); 
        } 

        private function onError(e:UserNotFound):void{ 
            trace(e); 
        } 

        private function onUserSuccess(user:User):void{ 
            trace("success:"); 
            trace(user); 
            textField.text = user.toString(); 
        } 

        private function onSuccess(user:Array):void{ 

            trace(user); 
            textField.text = user.toString(); 
        } 

    } 
}

写完了,测试结果

参考:http://xuzhiwei.blog.51cto.com/978424/1184540

http://jnb.ociweb.com/jnb/jnbJun2009.html


由“JasperReports 4.1.2升级到5.1.2对flex项目的解析”到AS3 带命名空间的XML的操作

2013-06-21 JasperReports

项目中,对JasperReports-4.1.2核心包进行了升级,发现,前端flex无法对JasperReports的格式进行解析了~

iReport 4.1 设计的模版可以解析,而iReport 4.6 设计的模版就不行了~

断点后,对比了从后台传过来的JasperReports 的xml数据,发现存在差异

4.1.2包生成的xml数据jasperPrint标签为:

<jasperPrint name="report13" pageWidth="842" pageHeight="842" topMargin="0" leftMargin="0" bottomMargin="0" rightMargin="0" locale="zh_CN" timezone="Asia/Shanghai"> 5.1.2包生成的xml数据jasperPrint标签为:

<jasperPrint xmlns="http://jasperreports.sourceforge.net/jasperreports/print"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/print
http://jasperreports.sourceforge.net/xsd/jasperprint.xsd" name="report13"
pageWidth="842" pageHeight="842" topMargin="0" leftMargin="0" bottomMargin="0"
rightMargin="0" locale="zh_CN" timezone="Asia/Shanghai">

后期版本的JasperReports核心包多生成了命名空间

而之前官方提供JasperReports 的flex解析包net.sf.jasperreports.flex (来自JasperReports的项目示例jasperreports-flash-4.0.0-project.zip)任然停留在2010年的版本未更新(估计JasperReports放弃了对flash的支持),导致无法对新版本的xml数据进行解析

AS3对于带命名空间的XML的解析操作上有很大的差异,例如以下来自JasperReports的ReportFactory.as

var props:XMLList = xml.property;
		for each (var prop:XML in props)
		{
			if ([email protected] == "net.sf.jasperreports.export.xml.start.page.index")
			{
				report.startPageIndex = int([email protected]);
			}
			if ([email protected] == "net.sf.jasperreports.export.xml.end.page.index")
			{
				report.endPageIndex = int([email protected]);
			}
			if ([email protected] == "net.sf.jasperreports.export.xml.page.count")
			{
				report.pageCount = int([email protected]);
			}
		}

由于新版本多了命名空间,所以 直接xml.property 是无法获取到property的。要带上命名空间

var ns:Namespace = new Namespace("http://jasperreports.sourceforge.net/jasperreports/print");
trace(xml.ns::property);    //输出带名字空间的XML

由于 涉及到多个 命名空间,这种方式在该项目中不合适,且要修改后续的其他操作。

最简单的方式,就是 干掉命名空间,这样后续操作不变。

这个就涉及到XML的操作了。查XML api发现了removeNamespace(ns:Namespace):XML方法,以为轻松搞定,实验后 ,发现 不行。默认的命名空间(如 xmlns=”http://jasperreports.sourceforge.net/jasperreports/print”)无法删除。

用xml.children()方法取他孩子,发现,每个孩子也带上了命名空间。

最后用上了正则表达式。限定类型的命名表达式可以删除了。而且用了两次。汗。。

       var str:String = oldxml.toString();

       var str2:String = str.replace(/xmlns(.*?)="(.*?)"/gm, "").replace(/xsi(.*?)="(.*?)"/gm, "");

        xml = new XML(str2);

FlashBuilder4.7更新AIR SDK方法

2013-06-15 AIR

默认情况下,Flash Builder 4.7安装了AIR SDK 3.4。如果你想使用别的SDK版本,你覆盖掉它就行了。下面就来介绍一下如何覆盖。 下载合适的AIR SDK文件:http://labs.adobe.com/downloads/asc2.html ,然后保存到AIR SDK的根目录(是SDK的根目录)。 注意了:这个AIR SDK包含了:Adobe AIR SDK、ActionScript编译器以及其它必需的组件和文件。 在进入以下步骤前,先退出Flash Builder: 在Flash Builder里更新AIR SDK的步骤: 1.(可选)备份旧的AIR SDK,把整个SDK目录都复制一份吧。AIR SDK的目录是在(因人而异,但大概一样): Windows 7: C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flash.compiler_4.7.0.349722 Mac OS: /Applications/Adobe Flash Builder 4.7/eclipse/plugins/com.adobe.flash.compiler_4.7.0.349722

  1. 在备份完后,删除SDK文件夹里的所有文件(译者注:这个SDK文件夹的名字为“AIRSDK”。只删除SDK文件夹里的文件,不要把SDK文件夹也删除了)。
  2. 下载的SDK通常是一个压缩包(zip/tbz2)。解压这个包,提取所有文件,把文件复制到那个名为“AIRSDK”的文件夹。

参考Adobe 原文:http://helpx.adobe.com/flash-builder/kb/overlay-air-sdk-flash-builder.html


一个用于检测FPS和内存占用的小例子

2013-06-14 ActionScript3

用于实时检测FPS(实际上可以算是检测CPU)和内存占用情况。

使用方法,在application的Document Class(或者Application Class)上构建一个检测器实例(MonitorKit)并addChild即可,所含参数比较简单,不再一一赘述:

 var monitor:MonitorKit = new MonitorKit(MonitorKit.MKMODE_T);
addChild(monitor);
package 
{
  import flash.display.Sprite;
  import flash.display.Stage;
  import flash.events.Event;
  import flash.system.System;
  import flash.text.TextField;
  import flash.text.TextFieldAutoSize;
  import flash.text.TextFormat;
  import flash.utils.getTimer;

  public class MonitorKit extends Sprite{
    public static const MKMODE_T:String = "MKMODE_T";
    public static const MKMODE_B:String = "MKMODE_B";
    public static const MKMODE_L:String = "MKMODE_L";
    public static const MKMODE_R:String = "MKMODE_R";
    public static const MKMODE_TL:String = "MKMODE_TL";
    public static const MKMODE_TR:String = "MKMODE_TR";
    public static const MKMODE_BL:String = "MKMODE_BL";
    public static const MKMODE_BR:String = "MKMODE_BR";

    private static var stageInstance:Stage;

    private var lastTime:uint = getTimer();
    private var frames:Number = 0;
    private var monitorKitTextField:TextField;
    private var mode:String;
    private var textColor:uint;
    private var backgroundColor:uint;
    private var transparent:Boolean;
    public static var delay:Number = 0;
    public function MonitorKit(_mode:String = MKMODE_T,
        _transparent:Boolean = true,
        _textColor:uint=0xffffff,
        _backgroundColor:uint=0x000000) {
      mode = _mode;
      transparent = _transparent;
      textColor = _textColor;
      backgroundColor = _backgroundColor;
      // Initialize it when rendered on the stage.
      addEventListener(Event.ADDED_TO_STAGE, initMonitorHandler);
    }

    private function initMonitorHandler(event:Event):void {
      // Unregister the event handler
      removeEventListener(Event.ADDED_TO_STAGE, initMonitorHandler);
      stageInstance = this.stage;
      monitorKitTextField = new TextField();
      monitorKitTextField.selectable = false;
      monitorKitTextField.background = transparent;
      monitorKitTextField.textColor = textColor;
      monitorKitTextField.backgroundColor = backgroundColor;
      monitorKitTextField.autoSize = TextFieldAutoSize.LEFT;
      var format:TextFormat = new TextFormat();
      format.font = "Courier New";
      format.size = 15;
      monitorKitTextField.setTextFormat(format);
      monitorKitTextField.defaultTextFormat = format;
      monitorKitTextField.text = "[ Loading... ]";
      addChild(monitorKitTextField);
      stageInstance.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }

    public function enterFrameHandler(evt:Event):void {
      frames++;
      var currentTime:uint = getTimer();
      var deltaTime:uint = currentTime - lastTime;
      var fps:Number = frames / deltaTime * 1000;
      monitorKitTextField.text = "FPS: " + fps.toFixed(1);
      monitorKitTextField.appendText("\nMem: " + Number(System.totalMemory/1024/1024).toFixed(3)+"(M)");
      frames = 0;
      lastTime = currentTime;
      // Replace the monitor object
      switch (mode) {
        case MKMODE_T:
          monitorKitTextField.x = stageInstance.stageWidth / 2 - monitorKitTextField.width / 2;
          monitorKitTextField.y = 0;
          break;
        case MKMODE_B:
          monitorKitTextField.x = stageInstance.stageWidth / 2 - monitorKitTextField.width / 2;
          monitorKitTextField.y = stageInstance.stageHeight - monitorKitTextField.height;
          break;
        case MKMODE_L:
          monitorKitTextField.x = 0;
          monitorKitTextField.y = stageInstance.stageHeight / 2 - monitorKitTextField.height / 2;
          break;
        case MKMODE_R:
          monitorKitTextField.x = stageInstance.stageWidth - monitorKitTextField.width;
          monitorKitTextField.y = stageInstance.stageHeight / 2 - monitorKitTextField.height / 2;
          break;
        case MKMODE_TL:
          monitorKitTextField.x = 0;
          monitorKitTextField.y = 0;
          break;
        case MKMODE_TR:
          monitorKitTextField.x = stageInstance.stageWidth - monitorKitTextField.width;
          monitorKitTextField.y = 0;
          break;
        case MKMODE_BL:
          monitorKitTextField.x = 0;
          monitorKitTextField.y = stageInstance.stageHeight - monitorKitTextField.height;
          break;
        case MKMODE_BR:
          monitorKitTextField.x = stageInstance.stageWidth - monitorKitTextField.width;
          monitorKitTextField.y = stageInstance.stageHeight - monitorKitTextField.height;
          break;
        default:
        break;
      }
    }
  }
} 

AIR SDK 0 AIR SDK location does not exist 解决

2013-06-05 AIR

导入AS3项目时提示 “AIR SDK 0.0: AIR SDK location "D:\Program Files\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\devsdks\AIRSDK\Win" does not exist.”

是AS3项目找不见AIR SDK. 打开项目配置 ActionScript Build Path ,路径出错。

他默认是去Flash Builder 4.7安装目录下的..\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\devsdks\AIRSDK\Win去找。

但是 我的Builder根本没有这个Win文件

##解决步骤:

###1. 先去官网下载下载和更新SDK

可参考此文http://www.waylau.com/update-air-sdk-flash-builder

###2. 如果上述方法无效

..\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\ 目录下创建 devsdks文件夹,再在devsdks创建AIRSDK,再在AIRSDK下创建Win 即创建它搜索的那个路径

###3.将下载的AIRSDK中的文件复制进新建的Win文件夹下。

###4.回到配置界面ActionScript Build Path移除之前的AIRSDK,再点击“ADD AIR SDK”


iReport 5.1.0下载、安装、创建数据源、制作报表

2013-05-22 iReport

一、ireport下载最新版

本例为5.1.0 http://sourceforge.net/projects/ireport/files/?source=navbar

二、安装,直接下一步

三、ireport连接数据库,创建数据源

默认数据源是空的 ,需要自己创建数据源,当然也可以选择他的测试数据库

 

1.点击图中按钮,弹出窗,点击 new

 

2.这里选择的是 Database JDBC Connection

 

3.iReport默认的数据库驱动为黑色字体部分,红色字体需另外导入包

 

4.工具à选项

 

5.在Classpath添加数据库驱动包

这里我们连接的是sql2000数据库,填加一个jtds-1.2.2.jar

 

6.再回到之前的那个数据源设置界面

net.sourceforge.jtds.jdbc.Driver 变成了黑色。选中它

 

7.JDBC URL中填入数据库的地址和库名,并填入正确的用户名和密码。

本例选用了一个已经存在的数据库。

点击Test,提示test succesful则说明连接成功。

输入Name, 本例为”EEMS”。

点击Save保存设置。

 

四、新增报表模版

1.文件 –>new file,选择blank A4 ,点击 launch report wizard

 

2.填入报表名称,选择输出的目录

 

3.直接填入查询sql语句,或者选择load query导入已有的sql文件

本例选用design query 采用可视化界面来设计sql语句

 

双击选中的数据库表,选择要查询的字段

 

点击OK,自动生成了sql语句

 

4.选择要参与的字段

 

这里向右移入所有字段

 

5.选择要分组的字段

这里选择loginName字段

 

6.出现下面提示,说明模版创建成功!

 

五、设计报表

 

报表的结构包括如下部分:Title、Page Header、Column Header、Detail、Column Footer、Page Footer、Summary.下面一一的介绍各个部分。

Title:为报表的标题部分,如果报表有多页,则只显示在第一页。

Page Header :为报表每页的一个头部名称,如果报表有多页,则每页都会显示。

Column Header:可以理解成表头,如果报表有多页,则每页都会显示。

Detail:详细记录,迭代列出所有的查询结果,有多少数据都会显示出来(分页)。

Column Footer:相当于表尾,如果报表有多页,则每页都会显示。

Page Footer:与Page Header对应,每页都会显示。

Summary:报表的一些统计信息。比如共有多少页,当前是第几页等信息。

设计报表的要求是:列出所有用户的信息,(查询语句决定。)

1.从组件面板中,拖出一个 Static Text 组件来,放置在报表的Title部分,输入”用户列表”。

 

2.在Page Header 也同样拖入一个 Static Text 组件,输入”管理员”

3.展开左侧的 Report Inspector,展开Fields子项,

 

将图所示的字段,拖入Detail项中,此时会发现,Column Header项中自动填充了Static Text的表头,如图所示:

 

在右侧”属性”,也可以对表头进行编辑,重命名等操作。可以调整各组件的位置、大小等信息。

 

4.选择 预览方式,这里选HLML

 

5.点击预览,选择Preview

 

6.显示数据库数据啦,成功啦。~


Activiti 5.12.1 下载、安装和运行

2013-05-18 Activiti

一、下载和安装

activiti下载:

本例子版本:activiti-5.12.1.zip

http://www.activiti.org/download.html

 

JDK 下载 JDK 6+

本例子版本:jdk7

http://www.oracle.com/technetwork/java/javase/downloads/index.html

eclipse下载 Eclipse Indigo and Juno:

本例子版本:Eclipse Juno (4.2)

http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/juno/SR2/eclipse-jee-juno-SR2-win32.zip

 

解压activiti-5.12.1.zip获取activiti-explorer.war

001

 

activiti-explorer.war 拷贝至Tomcat.(或其他java web服务器,本例为Tomcat 6.0)的webapps目录下

二、运行

启动tomcat,在浏览器打开项目(本例子tomcat端口为8089)

http://localhost:8089/activiti-explorer/

 

003

 

见到这个界面说明项目运行成功了!

默认使用的是内存数据库 H2,下面为数据库表

Table 用户和分组

UserId

Password

Security roles

kermit

kermit

admin

gonzo

gonzo

manager

fozzie

fozzie

user

 

可以使用上面的账号登入系统(本例为kermit)

004

 


Flex4.6 textArea 文字换行 示例

2013-05-13 Flex

###flex4.6 textArea 文字换行 有 几种实现形式,

####法1:在text文字里面直接加 “&#13;”

<s:TextArea  text="这是个 TextArea 分行的例子&amp;#13; http://www.waylau.com "/>

####法2:采用了 TLF 标记 形式

<s:TextArea  width="100%" height="340"   >
		<s:content >
			flex 4.6	<s:span color="#FF0000" fontWeight="bold">这是个 TextArea 分行的例子 </s:span><s:br/>
			<s:span color="#008800"> 采用了 TLF 标记 形式  </s:span> <s:br/>

			<s:a href="http://www.waylau.com" target="_blank">技术支持:www.waylau.com </s:a>.</s:content>
	</s:TextArea>

Flex4.6项目本地右键编译正常,部署后访问不了图片资源。解决

2013-05-11 Tomcat

###问题: 如题 遇到 一个 奇怪的 问题, 项目右键运行 图片显示正常。 但 部署到 web服务器 就 显示不正常了。

PS:图片命名用了中文。 用了英文的貌似显示 都正常。

###解决 初步 认定 可能是 web 服务器 编码所致使

在tomcat/conf/server.xml中找到 Connector 在后面加上 URIEncoding=”UTF-8” 即可

<Connector port="8089" protocol="HTTP/1.1" 
           connectionTimeout="20000" 
           redirectPort="8443"  URIEncoding="UTF-8"/>

惠州(惠州学院)——大亚湾(霞冲镇\金海岸)骑行路线图

2013-05-10 Outdoor

1.惠城区出发时,先骑(新S254)惠南大道 2.到了永湖镇后,左转进入(旧S254)惠澳大道,直走 3.到大亚湾的疏港大道, 4.1 快到石化大道前的一个十字路口(有指往霞冲镇的路标),转左直走就能到达霞冲镇,这是一条新路,左边有一条绿道直达霞冲镇 4.2 或到澳霞立交 左转,进入石化大道,直达霞冲镇 5.过了霞冲镇直走约3公里就是金海岸海滨浴场


SOAP webserivce 和 RESTful webservice 对比及区别

2013-04-25 REST Web

简单对象访问协议(Simple Object Access Protocol,SOAP)是一种基于 XML 的协议,可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME),基于“通用”传输协议是 SOAP的一个优点。它还支持从消息系统到远程过程调用(Remote Procedure Call,RPC)等大量的应用程序。SOAP提供了一系列的标准,如WSRM(WS-Reliable Messaging)形式化契约确保可靠性与安全性,确保异步处理与调用;WS-Security、WS-Transactions和WS-Coordination等标准提供了上下文信息与对话状态管理。

</wbr>

相对而言,SOAP协议属于复杂的、重量级的协议,当前随着Web2.0的兴起,表述性状态转移(Representational State Transfer,REST)逐步成为一个流行的架构风格。REST是一种轻量级的Web Service架构风格,其实现和操作比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。REST架构对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法,这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST架构尤其适用于完全无状态的CRUD(Create、Read、Update、Delete,创建、读取、更新、删除)操作。

基于REST的软件体系结构风格(Software Architecture Style)称之为面向资源体系架构(Resource-oriented Architecture,ROA)。按照REST原则设计的软件、体系结构,通常被称为“REST式的”(RESTful),在本文中以下称之为RESTful Web服务,以便于和基于SOAP的Web服务区别。 </wbr>

服务器端采用J2EE,客户端采用JSP、Flex、JavaFX、AIR等可以直接调用Servlet,其他的实现技术基本上不能直接调用,但是无论是那种客户端,对于基于SOAP的Web服务或者基于RESTful Web服务务都是支持的,如AJAX的 XMLHttpRequest、Flex的HTTPService等。如下图所示:

客户端和服务器端的通讯方式

 

SOAP
HTTP 的 GET、HEAD 请求本质上应该是安全的调用,即:GET、HEAD 调用不会有任何的副作用,不会造成服务器端状态的改变。对于服务器来说,客户端对某一 URI 做 n 次的 GET、HAED 调用,其状态与没有做调用是一样的,不会发生任何的改变。 HTTP 的 PUT、DELTE 调用,具有幂指相等特性 , 即:客户端对某一 URI 做 n 次的 PUT、DELTE 调用,其效果与做一次的调用是一样的。HTTP 的 GET、HEAD 方法也具有幂指相等特性。 HTTP 这些标准方法在原则上保证你的分布式系统具有这些特性,以帮助构建更加健壮的分布式系统。 安全控制 为了说明问题,基于上面的在线用户管理系统,我们给定以下场景: 参考一开始我们给出的用例图,对于客户端 Client2,我们只希望它能以只读的方式访问 User 和 User List 资源,而 Client1 具有访问所有资源的所有权限。 如何做这样的安全控制? 通行的做法是:所有从客户端 Client2 发出的 HTTP 请求都经过代理服务器 (Proxy Server)。代理服务器制定安全策略:所有经过该代理的访问 User 和 User List 资源的请求只具有读取权限,即:允许 GET/HEAD 操作,而像具有写权限的 PUT/DELTE 是不被允许的。 如果对于 REST,我们看看这样的安全策略是如何部署的。如下图所示: 图 4. REST 与代理服务器 (Proxy Servers) REST 一般代理服务器的实现根据 (URI, HTTP Method) 两元组来决定 HTTP 请求的安全合法性。 当发现类似于(http://localhost:8182/v1/users/{username},DELETE)这样的请求时,予以拒绝。 对于 SOAP,如果我们想借助于既有的代理服务器进行安全控制,会比较尴尬,如下图: 图 5. SOAP 与代理服务器 (Proxy Servers) REST 所有的 SOAP 消息经过代理服务器,只能看到( http://localhost:8182/v1/soap/servlet/messagerouter , HTTP POST)这样的信息,如果代理服务器想知道当前的 HTTP 请求具体做的是什么,必须对 SOAP 的消息体解码,这样的话,意味着要求第三方的代理服务器需要理解当前的 SOAP 消息语义,而这种 SOAP 应用与代理服务器之间的紧耦合关系是不合理的。 关于缓存 众所周知,对于基于网络的分布式应用,网络传输是一个影响应用性能的重要因素。如何使用缓存来节省网络传输带来的开销,这是每一个构建分布式网络应用的开发人员必须考虑的问题。 HTTP 协议带条件的 HTTP GET 请求 (Conditional GET) 被设计用来节省客户端与服务器之间网络传输带来的开销,这也给客户端实现 Cache 机制 ( 包括在客户端与服务器之间的任何代理 ) 提供了可能。HTTP 协议通过 HTTP HEADER 域:If-Modified-Since/Last- Modified,If-None-Match/ETag 实现带条件的 GET 请求。 REST 的应用可以充分地挖掘 HTTP 协议对缓存支持的能力。当客户端第一次发送 HTTP GET 请求给服务器获得内容后,该内容可能被缓存服务器 (Cache Server) 缓存。当下一次客户端请求同样的资源时,缓存可以直接给出响应,而不需要请求远程的服务器获得。而这一切对客户端来说都是透明的。 图 6. REST 与缓存服务器 (Cache Server) REST 而对于 SOAP,情况又是怎样的呢? 使用 HTTP 协议的 SOAP,由于其设计原则上并不像 REST 那样强调与 Web 的工作方式相一致,所以,基于 SOAP 应用很难充分发挥 HTTP 本身的缓存能力,图 7. SOAP 与缓存服务器 (Cache Server) REST 两个因素决定了基于 SOAP 应用的缓存机制要远比 REST 复杂: 其一、所有经过缓存服务器的 SOAP 消息总是 HTTP POST,缓存服务器如果不解码 SOAP 消息体,没法知道该 HTTP 请求是否是想从服务器获得数据。 其二、SOAP 消息所使用的 URI 总是指向 SOAP 的服务器,如本文例子中的 http://localhost:8182/v1/soap/servlet/messagerouter ,这并没有表达真实的资源 URI,其结果是缓存服务器根本不知道那个资源正在被请求,更不用谈进行缓存处理。 关于连接性 在一个纯的 SOAP 应用中,URI 本质上除了用来指示 SOAP 服务器外,本身没有任何意义。与 REST 的不同的是,无法通过 URI 驱动 SOAP 方法调用。例如在我们的例子中,当我们通过 getUserList SOAP 消息获得所有的用户列表后,仍然无法通过既有的信息得到某个具体的用户信息。唯一的方法只有通过 WSDL 的指示,通过调用 getUserByName 获得,getUserList 与 getUserByName 是彼此孤立的。 而对于 REST,情况是完全不同的:通过 http://localhost:8182/v1/users URI 获得用户列表,然后再通过用户列表中所提供的 LINK 属性,例如 <link>http://localhost:8182/v1/users/tester</link> 获得 tester 用户的用户信息。这样的工作方式,非常类似于你在浏览器的某个页面上点击某个 hyperlink, 浏览器帮你自动定向到你想访问的页面,并不依赖任何第三方的信息 REST 构建的系统其系统的扩展能力要强于 SOAP,这可以体现在它的统一接口抽象、代理服务器支持、缓存服务器支持等诸多方面, 而SOAP的成熟性可以给需要提供给多开发语言的,多传输方式的,对于安全性要求较高的接口设计带来便利。   原文载自:http://luckykapok918.blog.163.com/blog/static/20586504320123238260833/

自行车骑行装备的选择

2013-04-24 Outdoor

一、骑行人员装备 从上至下,依次为: 1、骑行头盔:为轻质头盔,以高强度泡沫压制而成,用于头部防护; 2、骑行头巾:多种用途,主要用于排汗遮阳阻隔灰尘; 3、骑行眼镜:按照佩带时间段,镜片可分为多种颜色,一般为深灰色、黄色、白色。深灰色-适合于中午阳光照射充足的时间佩带,以阻隔刺眼的眼光;黄色-适合清晨、黄昏阳光照射相对较暗的时候佩带;白色,适合天气阴暗或晚上佩带。其主要功能在于,阻隔阳光、阻隔风尘; 4、骑行服:骑行人员专用衣服,由多种面料制作而成,可按需选用。其功能主要功能为保暖、速干、透气; 5、骑行袖套:又称为臂套,主要和短袖骑行服搭配穿着,方便拆解,其主要功能为保暖、防晒; 6、骑行手套:为骑行人员专用手套,有半指与全指之分,手掌部位做加厚处理,高档骑行手套均垫有硅胶层,主要用于摔车时,减少伤害,防止擦破手; 7、骑行背包或腰包:骑行背包并没有做特殊规定,主要用于盛装骑行过程所需之物,满足需求即可,并不做特殊要求; 8、骑行裤:为骑行者专用裤子,有长短之分并在臀部配有坐垫,其功能主要为高弹减少腿部于自行车之间的摩擦,同时配备的坐垫减少长时间骑行屁股会疼的状况,提高骑行的舒适性; 9、骑行腿套:如直筒一般,与骑行短裤搭配使用,方便拆解,主要功能为保暖、防晒; 10、骑行袜:为骑行者专用袜子,按照COOLMAX含量可分为多种,骑行者可按照骑行时间的长短和骑行活动的强度来选用适合穿着的骑行袜; 11、绑腿:又名束带主要用于扎结裤腿角,防止裤腿绞进链条,以保障骑行的安全; 12、骑行鞋:为骑行者专用鞋子,同样可分为多种,有山地骑行鞋与公路骑行鞋之分,可按照所骑自行车款式进行选择,如自行车配备专用脚蹬,则骑行鞋必须选用锁鞋; 13、骑行鞋套:骑行鞋套用于骑行锁鞋的搭配,有减少风阻,防污保暖等用途。

 

二、车载装备 从自行车前头往后依次有: 1、打气桶:一般为便携装,安置于前叉部位; 2、车首包:又名车把包、车前包常见于山地车装备中。适合长途骑行装载物品之用; 3、车灯\尾灯:常见于夜间骑行的自行车中,照明警示用; 4、喇叭:有气喇叭与电喇叭之分,可按需取用,功能并无太大差别,只是发声装置不同; 5、三角包:隶属于包裹类,作用同于车首包,只是安装部位不同,另还有尾包-安装于自行车座立管部位,驮包安装于自行车后坐部位;车架包,位于车头与车管部位 6、水壶:有多种可选,无需专门配备,主要用于盛装在骑行过程中所需要饮用的水。

  1. 水壶架:放置水壶
  2. 码表:显示里程,测速
  3. 扶把(副把):减少手部疲劳 10.货架(后车架):用于长途骑行装载驮包用 11.挡泥板:雨天必备 12.硅胶坐垫:保护小DD,长途适用 13.护链贴:防止链条脱落与车架激烈摩擦 14.车锁:不多说 15.修补工具:翘胎棒、摩擦片、胶水、补胎片、内六角、一字十字螺丝刀、扳手。。太多了,见下图

 

 


DOM4J介绍与代码示例

2013-04-18 Java

原文摘自:http://zhangjunhd.blog.51cto.com/113473/126310

DOM4J是dom4j.org出品的一个开源XML解析包。Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。

DOM4J下载jar包:http://downloads.sourceforge.net/dom4j/dom4j-1.6.1.jar
JAXEN(对XPath的支持):http://dist.codehaus.org/jaxen/distributions/jaxen-1.1.1.zip
1.DOM4J主要接口
DOM4J主要接口都在org.dom4j这个包里定义。
-Node为所有的dom4j中XML节点定义了多态行为;
-Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为;
|-Element 定义XML 元素;
|-Document定义了XML文档;
-DocumentType 定义XML DOCTYPE声明;
-Entity定义 XML entity;
-Attribute定义了XML的属性;
-ProcessingInstruction 定义 XML 处理指令;
-CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text;
|- CDATA 定义了XML CDATA 区域;
|-Text 定义XML 文本节点;
|- Comment 定义了XML注释的行为;
2.创建XML文档
示例xml:students.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="students.xsl"?>
<students>
<!--A Student Catalog-->
<student sn="01">
<name>sam</name>
<age>18</age>
</student>
<student sn="02">
<name>lin</name>
<age>20</age>
</student>
</students>
下面是用dom4j创建上述文档,通过两种方式创建,一种是调用dom4j提供的方法,一种是通过字符串转换。
XmlGen.java
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
public class XmlGen {
public Document generateDocumentByMethod() {
Document document = DocumentHelper.createDocument();
// ProcessingInstruction
Map<String, String> inMap = new HashMap<String, String>();
inMap.put("type", "text/xsl");
inMap.put("href", "students.xsl");
document.addProcessingInstruction("xml-stylesheet", inMap);
// root element
Element studentsElement = document.addElement("students");
studentsElement.addComment("An Student Catalog");
// son element
Element stuElement = studentsElement.addElement("student");
stuElement.addAttribute("sn", "01");
Element nameElement = stuElement.addElement("name");
nameElement.setText("sam");
Element ageElement = stuElement.addElement("age");
ageElement.setText("18");
// son element
Element anotherStuElement = studentsElement.addElement("student");
anotherStuElement.addAttribute("sn", "02");
Element anotherNameElement = anotherStuElement.addElement("name");
anotherNameElement.setText("lin");
Element anotherAgeElement = anotherStuElement.addElement("age");
anotherAgeElement.setText("20");
return document;
}
public Document generateDocumentByString() {
String text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<?xml-stylesheet type=\"text/xsl\" href=\"students.xsl\"?>" +
"<students><!--An Student Catalog--> <student sn=\"01\">" +
"<name>sam</name><age>18</age></student><student sn=\"02\">" +
"<name>lin</name><age>20</age></student></students>";
Document document = null;
try {
document = DocumentHelper.parseText(text);
} catch (DocumentException e) {
e.printStackTrace();
}
return document;
}
public void saveDocument(Document document, File outputXml) {
try {
// 美化格式
OutputFormat format = OutputFormat.createPrettyPrint();
/*// 缩减格式
OutputFormat format = OutputFormat.createCompactFormat();*/
/*// 指定XML编码
format.setEncoding("GBK");*/
XMLWriter output = new XMLWriter(new FileWriter(outputXml), format);
output.write(document);
output.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] argv) {
XmlGen dom4j = new XmlGen();
Document document = null;
// document=dom4j.generateDocumentByMethod();
document = dom4j.generateDocumentByString();
dom4j.saveDocument(document, new File("output.xml"));
}
}
方法generateDocumentByMethod()通过调用方法构建xml文档:
1.使用DocumentHelper得到Document实例
Document document = DocumentHelper.createDocument();
2.创建Processing Instruction
document.addProcessingInstruction("xml-stylesheet", inMap);
3.创建元素Element
Element studentsElement = document.addElement("students");
4.为元素添加注释Comment
studentsElement.addComment("An Student Catalog");
5.为元素添加属性
studentsElement.addComment("An Student Catalog");
6.为元素添加文本值Text
ageElement.setText("18");
方法generateDocumentByString()通过字符串转换直接构建xml文档,使用DocumentHelper.parseText()来实现.
document = DocumentHelper.parseText(text);
方法saveDocument(Document document, File outputXml)将文档输出到文件保存,可指定字符编码,可指定格式化输出。
3.修改XML文档
这里使用xpath来定位待修改的元素和属性,需要jaxen的支持。
示例中将students-gen.xml的第一个student元素的sn属性改为001,其子元素name内容改为jeff。
XmlMod.java
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XmlMod {
public void modifyDocument(File inputXml) {
try {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputXml);
List list = document.selectNodes("//students/student/@sn");
Iterator iter = list.iterator();
while (iter.hasNext()) {
Attribute attribute = (Attribute) iter.next();
if (attribute.getValue().equals("01"))
attribute.setValue("001");
}
list = document.selectNodes("//students/student");
iter = list.iterator();
while (iter.hasNext()) {
Element element = (Element) iter.next();
Iterator iterator = element.elementIterator("name");
while (iterator.hasNext()) {
Element nameElement = (Element) iterator.next();
if (nameElement.getText().equals("sam"))
nameElement.setText("jeff");
}
}
XMLWriter output = new XMLWriter(new FileWriter(new File(
"students-modified.xml")));
output.write(document);
output.close();
}
catch (DocumentException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] argv) {
XmlMod dom4jParser = new XmlMod();
dom4jParser.modifyDocument(new File("students-gen.xml"));
}
}
1.使用File定位文件资源,并基于此获得Document实例
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputXml);
2.Document实例的selectNodes方法可以传入xpath,并返回一个List实例,基于此使用迭代器,完成特定的应用
List list = document.selectNodes("//students/student/@sn");
4.遍历XML文档
这里提供两种遍历方法,一种是基于迭代的遍历,一种是基于Visitor模式的遍历。
XmlTra.java
import java.io.File;
import java.util.Iterator;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ProcessingInstruction;
import org.dom4j.VisitorSupport;
import org.dom4j.io.SAXReader;
public class XmlTra {
private File inputXml;
public XmlTra(File inputXml) {
this.inputXml = inputXml;
}
public Document getDocument() {
SAXReader saxReader = new SAXReader();
Document document = null;
try {
document = saxReader.read(inputXml);
} catch (DocumentException e) {
e.printStackTrace();
}
return document;
}
public Element getRootElement() {
return getDocument().getRootElement();
}
public void traversalDocumentByIterator() {
Element root = getRootElement();
// 枚举根节点下所有子节点
for (Iterator ie = root.elementIterator(); ie.hasNext();) {
System.out.println("======");
Element element = (Element) ie.next();
System.out.println(element.getName());
// 枚举属性
for (Iterator ia = element.attributeIterator(); ia.hasNext();) {
Attribute attribute = (Attribute) ia.next();
System.out.println(attribute.getName() + ":"
+ attribute.getData());
}
// 枚举当前节点下所有子节点
for (Iterator ieson = element.elementIterator(); ieson.hasNext();) {
Element elementSon = (Element) ieson.next();
System.out.println(elementSon.getName() + ":"
+ elementSon.getText());
}
}
}
public void traversalDocumentByVisitor() {
getDocument().accept(new MyVisitor());
}
/**
* 定义自己的访问者类
*/
private static class MyVisitor extends VisitorSupport {
/**
* 对于属性节点,打印属性的名字和值
*/
public void visit(Attribute node) {
System.out.println("attribute : " + node.getName() + " = "
+ node.getValue());
}
/**
* 对于处理指令节点,打印处理指令目标和数据
*/
public void visit(ProcessingInstruction node) {
System.out.println("PI : " + node.getTarget() + " "
+ node.getText());
}
/**
* 对于元素节点,判断是否只包含文本内容,如是,则打印标记的名字和 元素的内容。如果不是,则只打印标记的名字
*/
public void visit(Element node) {
if (node.isTextOnly())
System.out.println("element : " + node.getName() + " = "
+ node.getText());
else
System.out.println("--------" + node.getName() + "--------");
}
}
public static void main(String[] argv) {
XmlTra dom4jParser = new XmlTra(new File("students-gen.xml"));
// dom4jParser.traversalDocumentByIterator();
dom4jParser.traversalDocumentByVisitor();
}
}
方法traversalDocumentByIterator()提供一种基于迭代的遍历实现,每个Element通过elementIterator()和attributeIterator()取代其子元素和属性的迭代器。
Visitor是GOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。DOM4J中的Visitor模式只需要自定一个类实现Visitor接口即可。
public class MyVisitor extends VisitorSupport {
public void visit(Element element) {
System.out.println(element.getName());
}
public void visit(Attribute attr) {
System.out.println(attr.getName());
}
}
调用: root.accept(new MyVisitor())
Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,一般比较常用的就是这两个。VisitorSupport是DOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。
注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。
5.使用ElementHandler
XmlHandler.java
import java.io.File;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;
public class XmlHandler {
public static void main(String[] args) {
SAXReader saxReader = new SAXReader();
File file = new File("students.xml");
try {
// 添加一个ElementHandler实例。
saxReader.addHandler("/students/student", newStudentHandler());
saxReader.read(file);
} catch (DocumentException e) {
System.out.println(e.getMessage());
}
}
/**
* 定义StudentHandler处理器类,对<student>元素进行处理。
*/
private static class StudentHandler implements ElementHandler {
public void .Start(ElementPath path) {
Element elt = path.getCurrent();
System.out.println("Found student: " + elt.attribut.ue("sn"));
// 添加对子元素<name>的处理器。
path.addHandler("name", new NameHandler());
}
public void .End(ElementPath path) {
// 移除对子元素<name>的处理器。
path.removeHandler("name");
}
}
/**
* 定义NameHandler处理器类,对<student>的<name>子元素进行处理。
*/
private static class NameHandler implements ElementHandler {
public void .Start(ElementPath path) {
System.out.println("path : " + path.getPath());
}
public void .End(ElementPath path) {
Element elt = path.getCurrent();
// 输出<name>元素的名字和它的文本内容。
System.out.println(elt.getName() + " : " + elt.getText());
}
}
}
6.使用XSLT转换XML
这里必须使用JAXP的支持。
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
……
public Document styleDocument(Document document, String stylesheet)
throws Exception {
// load the transformer using JAXP
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(newStreamSource(stylesheet));
// now lets style the given document
DocumentSource source = new DocumentSource(document);
DocumentResult result = new DocumentResult();
transformer.transform(source, result);
// return the transformed document
Document transformedDoc = result.getDocument();
return transformedDoc;
}
……
 

SecurityError Error 2148 SWF 不能访问本地资源

2013-04-13 Flash

##错误提示:

SWF 文件不能被本地访问 不能访问本地 只有仅限于文件系统的 SWF 文件和可信的本地 SWF 文件可以访问本地资源

##错误信息:

SecurityError: Error #2148: SWF 文件 D:\demo\demo.swf 不能访问本地资源 D:\demo\demo\bin-debug\textLayout_4.0.0.10485.swf。只有仅限于文件系统的 SWF 文件和可信的本地 SWF 文件可以访问本地资源。

##解决方法:

###第一种办法

在Flash插件上右键->全局设置->高级->开发人员工具->受信任的位置设置->添加 ,然后添加你的文件或者文件夹即可。

说明:在本地测试期间,Flash Player 可以显示阻止应用程序正常运行的安全警告。您可以使用“受信任位置设置”面板将您自己的 SWF 或 FLV 内容指定为可信内容,从而解决这一问题。您可以将个别文件的路径指定为可信路径,或者指定文件夹为可信文件夹。可信文件夹中的所有文件及其任何子文件夹也会受信任。使用此选项卡可指定您计算机上包含您信任的 SWF 或 FLV 内容的位置。可信内容不遵循阻止内容访问 Internet 和本地计算机文件系统的安全规则。

###第二种方法:

在C:\WINDOWS\system32\Macromed\Flash\FlashPlayerTrust目录下添加一个文件,比如:1.txt(文件名可任意起),文件内容为项目的路径,当然也可以设置为“D:\” 说明: 为了让你的Flash在用户硬盘中拥有同时访问网络和本地的能力,你必须在用户计算机的FlashPlayerTrust目录中为你的Flash添加权限. FlashPlayerTrust 配置文件。 这些是列出受信任路径的简单文本文件。这些文件由可执行的安装程序创建。当安装程序将 SWF 安装到用户的计算机时, 它能够安装信任的配置文件并指定 SWF 是受信任的。


Flex4.6 用Lable自定义LinkButton

2013-04-08 Flex

很简单,先是继承Lable ,而后 设置相关属性,比如 小手鼠标、下划线等

package com.waylau.eagleos.components
{
	import spark.components.Label;

	public class LinkButton extends Label
	{
		public function LinkButton()
		{
			super();

			this.useHandCursor = true ;
			this.buttonMode = true ;
			this.mouseChildren = false ;

			this.setStyle("textDecoration","underline");
		}
	}
}

Golang strings.Split获取字符串中的url/域名的简易方法

2013-04-07 Golang

package main

import (
	"fmt"
	"strings"
)

func main() {
	fmt.Println("Hello World!")

	a := "golang strings.Split获取字符串中的url/域名的简易方法http://www.waylau.com/golang-strings-split-get-url/"
	a1 := strings.Split(a, "//")[1]
	a2 := strings.Split(a1, "/")[0]

	fmt.Println(a1) //输出为:www.waylau.com/golang-strings-split-get-url/
	fmt.Println(a2) //输出为:www.waylau.com
}

惠州——平海古城、海滨温泉、巽寮湾-旅游攻略

2013-04-06 Outdoor

1.在惠州汽车站。乘坐惠州——惠东汽车到达惠东汽车站(18元),转乘惠东——港口专线巴士(18元),至平海镇下车,下车向巷子里走约200米 ,见 城墙,即是古城

其实,平海镇方圆不大,东南西北四个门都见完了也就 几十分钟的事情。城内有几个庙。 恰逢清明节,百姓插旗烧香祭祖,院门大开,也算是领略了风俗民情。 城内无吃饭的地方,吃饭在下车的大路边。 在沙县吃了一碗鸡腿饭13元。

2.平海古城转车去海滨温泉就有所不便,没有的士,也没有班车,上了摩托35元,也只能认了,自己走的话大概要十几公里。 一路狂飙,披头散发,直接送到海滨温泉旅游区门口。

海滨温泉门票是团购的100+,因为是过节临时加多了10元,不限时,貌似营业到晚上12点 去到那里 大概是下午1点半左右,里面大大小小温泉40多个,各种药池,花池,酒池 ,不过里面的温水是不是地热的水就不好说了~ 提供免费的花生小吃还有饮料,橙汁兑水的吧,淡出鸟来 还有花生都不脆,感觉过气的。 另外有小番薯提供,这个不错。 吃了串鱼丸,三颗10元。

泡了一圈,发觉才2点多,休息了一下又去平泡了一圈。其实不能泡太久。 熬到四点过,有歌舞看,走了,不看了。 出门,发现搭车又不便了。决定走到巽寮镇。距离也就是十几公里。(其实是有去惠东的巴士可以搭的) 走了一半路程,天已经暗了。有哥们停车顺了一段路,都是来泡泉的,有亲切感。还是有车好,一脚油门,几分钟就到了酒店。 我是团购的海景山庄,100+标双,到店需要观海的房间的又要对加钱。 酒店内的设施一般,晚上定点放热水。 位置不错,基本上躺床上就能见到海 附近没有吃货,全是酒店。走约两三公里就到镇上。淡季,海鲜还是这么贵~

3.第二天起来,约了隔壁的几个家伙一起去巽寮湾出海打鱼。 一出门就下雨了,我汗。 酒店附近不能直接下海,要走一两公里到滨海度假村有入口可以进海滩。 也没捡贝壳,光避雨去了。附近都是待建的工地。一片荒凉。 天晴上了渔船打鱼,80元包船,打到都是自己的。 结果一趟来回就是几个濑尿虾,不够吃啊。又买了条鱼,叫渔家帮忙煮了。 坐渔家的快艇还是有快感,擦,一条鱼带加工费要了120元

4.附近还有天后宫岭南民俗文化商业街, 酒吧一条街还在招商,人影木有。 商业街有妈祖庙。 天又下雨,走出街到大路,坐车回惠东17元 总结: 路费 100+ 打鱼 80 吃饭 200+ 交通不是很方便。 2013-4-5


Golang 实现的一个小游戏--猜数字

2013-04-06 Golang Game

随机生成一个数字,输入一个数字看是否匹对,匹配则结速,反之提示是大了还是小了,

代码如下: package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)
var (
	endNum int //设置生成数的范围
)
func main() {
	i := createRandomNumber(endNum)
	//fmt.Println("生成规定范围内的整数:", i)    //本句调试用

	fmt.Println("请输入整数,范围为:0-", endNum)

	flag := true
	reader := bufio.NewReader(os.Stdin)

	for flag {
		data, _, _ := reader.ReadLine()

		command, err := strconv.Atoi(string(data)) //string to int,并作输入格式判断
		if err != nil {
			fmt.Println("格式不对,请输入数字")
		} else {

			fmt.Println("你输入的数字:", command)

			if command == i {
				flag = false
				fmt.Println("恭喜你,答对了~")
			} else if command &lt; i {
				fmt.Println("你输入的数字小于生成的数字,别灰心!再来一次~")
			} else if command &gt; i {
				fmt.Println("你输入的数字大于生成的数字,别灰心!再来一次~")
			}
		}
	}
}
func init() {
	endNum = 10
}

//生成规定范围内的整数
//设置起始数字范围,0开始,endNum截止
func createRandomNumber(endNum int) int {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	return r.Intn(endNum)
}

golang实现字符串逆序,不允许临时变量的原地逆序

2013-04-06 Golang

package main

import (
	"fmt"
)

var (
	s1    string
)
func main() {
	fmt.Println(s1)
	fmt.Println(converString(s1))
}
func init() {
	s1 = "我爱你waylau.com"
}
func reverseString(s string) string {
	str := []rune(s)

	for i, j := 0, len(str)-1; i &lt; j; i, j = i+1, j-1 {
		str[i], str[j] = str[j], str[i]
	}

	return string(str)
}

后台输入为

我爱你waylau.com
moc.ualyaw你爱我


Flex的一些总结

2013-03-26 Flex

##Loader与URLLoader,SWFLoader

(1) Loader Loader 类可用于加载 SWF 文件或图像(JPG、PNG 或 GIF)文件。 使用 load() 方法来启动加载。 被加载的显示对象将作为 Loader 对象的子级添加。 (2)URLLoader URLLoader 类以文本、二进制数据或 URL 编码变量的形式从 URL 下载数据。 在下载文本文件、XML 或其它用于动态数据驱动应用程序的信息时,它很有用。URLLoader 对象会先从 URL 中下载所有数据,然后才将数据用于 ActionScript。 它会发出有关下载进度的通知,通过 bytesLoaded 和bytesTotal 属性以及已调度的事件,可以监视下载进度。在加载非常大的视频文件(如 FLV 的视频文件)时,可能会出现内存不足错误。

区别:一个用来加载可显示数据,一个用来加载非显示数据因为loader是继承与容器类的,所以首先它是个容器,而URLLoader 是继承与EventDispatcher,它不是容器URLLoader 类以文本、二进制数据或 URL 编码变量的形式从 URL 下载数据,在加载非常大的视频文件(如 FLV 的视频文件)时,可能会出现内存不足错误,返回的数据在data属性里面而loader多加载图片,swf等可视化对象,加载后作为唯一的子对象显示在列表上。

应用范围 Loader: 多用于swf,图片(jpg,png,gif) URLLoader: 多用于文本文件(xml,php,jsp…) 使用方法

    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
    private function loadComplete(event:Event)
    { 
        trace("done");
        addChild(loader);
    }

    //URLLoader:
    xmlLoader.dataFormat=URLLoaderDataFormat.TEXT; 
    xmlLoader.addEventListener(Event.COMPLETE,xmlLoaded); 
    private function xmlLoaded(event:Event) { 
        try {
            myXML = XML(event.target.data);area.text=myXML;
        }catch (e:TypeError) 
        {
            area.text="Load faild:\n"+e.message;
        } 
    }  Loader 在使用Loader来加载数据时,添加侦听事件时,注意一定要给Loader的 contentLoaderInfo属性增加事件,而不是给Loader对象增加事件。
 var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITYERROR, securityErrorHandler); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IOERROR, ioErrorHandler);

(3)可以使用SWFLoader和Loader两个类来加载子应用程序,多数情况下我们使用SWFLoader。它是Loader的一个包装类,提供了很多附加功能,使加载子应用程序更简单。 SWFLoader有如下特征: 支持flex的样式和特效;而Loader类却不支持任何固有的样式和特效。 方便管理加载进度;如果使用Loader则首先要获取LoaderInfo引用。

是一个UIComponent组件。SWFLoader它自己管理了所有子显示对象,不需要添加多余的代码。 自动缩放显示内容的大小

可以加载Application以外的实现类,如果检测到不是一个Application,会自动进行处理。 可以处理不同的版本。Loader不支持加载不同的编译版本

当使用Loader加载不是受信任区域的swf时,必须提供一个遮罩来重新定位,否则它会显示在屏幕外面: 代码 import flash.display.*; import flash.net.URLRequest; var rect:Shape = new Shape(); rect.graphics.beginFill(0xFFFFFF); rect.graphics.drawRect(0, 0, 100, 100); addChild(rect); var ldr:Loader = new Loader(); ldr.mask = rect; var url:String = “http://www.unknown.example.com/content.swf”; var urlReq:URLRequest = new URLRequest(url); ldr.load(urlReq); addChild(ldr);

SWFLoader加载外部swf是一个很好的方法,在进行Flex游戏开发的时候,我们通常会需要很多Flash提供的游戏角色,这些角色可以每个都是一个单独的swf,也可以是存在于一个swf文件中的各个元件。两种方法各有优劣: 1. 单独的swf,每个角色独立性很强,可以在需要的时候才加载。未来修改角色也不会影响到其它角色。但是会有很多的swf需要管理。 2. 每个角色是一个元件,存在于一个swf中,这种方法比较容易管理资源,比较干净。但是修改一个角色都需要重新编译swf,可能会误操作影响其它的元件。而且一次加载所有角色,可能会加载许多不必要的元件,浪费带宽。

两种方法怎么选择,根据项目读者根据以下几个问题考虑: 1. 你的所有元件相互之间是否又很多公用元件?如果是的话,可以考虑放到一个swf中,因为这样会降低所有元件的文件量。 2. 你的所有元件是否都继承同一些类,实现同一些接口,调用同一些类?如果是的话,可以考虑放到一个swf中,这样比较容易管理类包,而且降低swf的文件量,因为共有的类只编译一次。 3. 你的所有元件是否完全独立,没有任何关系?如果是的话,你可以考虑每个角色独立的swf。 具体实现代码如下:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               creationComplete="init()"
               >
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import mx.controls.SWFLoader;
            import mx.core.UIComponent;

            private var swfLoader:SWFLoader = new SWFLoader();
            private function init():void{
                swfLoader.addEventListener(Event.COMPLETE,swfLoadComplete);
                swfLoader.load("assets/fishmomo.swf");
            }
            private function swfLoadComplete(e:Event):void{
                /**
                 * 将整个swf都加载到flex舞台上
                 * 此方法将每个flex要用的资源做成单独的swf,需要时才加载进来
                 */ 
                addElement(swfLoader);
                var swf:MovieClip = swfLoader.content as MovieClip;
                //fish 是 swf主舞台上的一个鱼对象,属性命名为fish
                //调用舞台上fish元件的say方法
                swf.fish.say("Load a swf");

                /**
                 * 此方法可以把所有的flex要用的资源放到一个swf中
                 * 把需要在flex中使用的元件链接到一个类,并将此元件拖到flash舞台
                 * 通过类名,随意显示其中一个元件到flex舞台
                 */ 
                var FishSymbol:Object = swfLoader.content.loaderInfo.applicationDomain.getDefinition("Fish");
                var f:MovieClip = new FishSymbol() as MovieClip;
                //调用元件的say方法
                f.say("Load a symbol within a swf");
                var ui:UIComponent = new UIComponent();
                ui.addChild(f);
                addElement(ui);
            }
        ]]>
    </fx:Script>
</s:Application>

##导致内存泄露的一些情况:

事件监听: 对父级对象加了监听函数,会造成内存泄露,例:

override protected function mouseDownHandler(…):void { 
systemManager.addEventListener(“mouseUp”, mouseUpHandler); …… 
}  解决: 在销毁对象的时候,remove掉这些监听,虽然弱引用也可以避免这些问题,但自己掌控感觉更好。 但以下几种情况不会造成内存泄露: 弱引用:

someObject.addEventListener(MouseClick.CLICK, handlerFunction, false, 0, true);  对自己的引用:

this.addEventListener(MouseClick.CLICK, handlerFunction);  子对象的引用: 

private var childObject:UIComponent = new UIComponent; addChild(childObject); childObject.addEventListener(MouseEvent.CLICK, clickHandler);  总之…有addEventListener,就removeEventListener一下吧,要为自己做的事负责~哈哈

清除引用 remove掉子对象后并不会删除该对象,他还保留在内存中,应该将引用设置为null removeChildren(obj); obj = null;

静态成员 Class (或MXML)中有: public static var _eventService : MyService=new MyService(); 解决:在dispose时,需要设置: _eventService =null;

module (未解决) moduleLoader unloadModule后 ModuleInfo 并不会被GC. Garbage Collection in a MultiCore Modular Pipes Application 这篇文章介绍了一种GC策略,感觉对于ModuleInfo 的GC无效。 (未尝试、未遇到)

CSS样式 module 中如果使用了shell的CSS定义或是 这样的定义,那么这个module将不能GC. 弹出的窗口应该是同样的结果. 解决方法,使用动态CSS文件 module init中 StyleManager.loadStyleDeclarations(“css/myStyle.swf”); module dispose中 StyleManager.unloadStyleDeclarations(“css/myStyle.swf”);

TextInput/Textarea(未解决) 如果module中有window使用了TextInput/Textarea控件,不点击没有问题,只要点上去,那么很遗憾了,module和所在窗体将不能被GC. 这个BUG非常严重,目前还没有解决方法。 memory leak when using TextInput and TextArea when click the keyboard 这里面附加的解决方法无效。 通过profiler分析,应该和Focusmanager有关,只有一点击就不会释放。

CursorManager.setCursor 使用了 cursorID = CursorManager.setCursor(iconClosed); dispose时要 CursorManager.removeCursor(cursorID);

Bitmap 如果使用Bitmap,结束时需要调用其dispose方法,否则内存消耗巨大。 另外,BitmapData是可以共享使用的,多个Bitmap可以使用同一BitmapData,节省不少内存。 var bmp:Bitmap =new Bitmap(); …….. if (bmp.bitmapData!=null) { bmp.bitmapData.dispose(); } Image 包含了Image对象时,在removeChildren时会造成不能释放(测试多次,结果不一,建议还是做如下处理)。 解决: img.source = null; this.removeChild(img); img = null;

Loader、SWFLoader、声音、视频、Effect等… 如果是加载SWF文件,先停止播放。 停止声音的播放 停止正在播放的影片剪辑(Movieclip) 关闭任何连接的网络对象,例如Loader正在加载,要先close。 取消对摄像头或者麦克风的引用 取消事件监听器 停止任何正在运行的定时器,clearInterval() 停止任何Timer对象,timer.stop() 停止正在播放的效果(Effect) 其他

binding也疑似有memory leak 问题。 引用以及内存泄露相关博文和资料: http://blogs.adobe.com/aharui/2007/03/garbagecollectionandmemory.html http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/ http://www.cnblogs.com/janyou/archive/2008/11/25/1340753.html http://www.dreamingwell.com/articles/archives/2008/05/understandingm.php 总结:由于之前Flash一直是在网页上使用,一般网页都是看完就关掉的,估计Adobe在内存回收这块也没有下太大的功夫, 现在AIR的出现使得内存管理也相当重要了,并且,AIR本身对内存的消耗就相当大,一个没有任何内容的初始创建的AIR程序,就得占掉10-20M+的内存…AIR还需改善.

##Modules

为什么要模块化;模块化提供了分离应用程序代码到不同的swf文件上以便减少下载时间和文件大小。 使用Modules的好处是:

  1. 主应用程序开始时不需马上下载modules。应用程序会根据需求载入和卸载modules。

  2. 由于每个modules独立于其他应用程序modules,当需要改变一个modules时,你只需要重编译这个modules而不是整个应用程序。模块化可创建模块化应用程序是提高Flex框架性能的重要方面,提供更多能力控制下载时间和文件大小,使用modules,你可以根据哪些可被独立载入,哪些可被其他程序使用而分离应用程序代码。

优点是合理分割了主Application,模块化开发。更小的SWF文件体积,配合RSL和延迟加载策略,大大减少用户等待时间。

缺点就是容易引起内存泄露。

##RSL

RSL(Runtime Shared Library),即运行时加载库。当前L主要有3个级别的RSL,一个是Standard RSL(即一个网站内共享),一个是Cross-domain RSL(跨域共享),最后一个也是最关键的是Framework RSL(Flex框架共享)。 功能说明 Flex Builder在默认情况下,编译的每个程序都是独立的。每个程序都包含了所需类的一个副本,例如:在多个程序中都用到了VBox这个控件,那么每个程序都要独立的拥有一个VBox类。由此造成了程序代码的重复,使得代码量增大很多。而RSL正是解决此问题的一种方法,它可以把共享代码提取出来,然后在相同域的程序之间进行共享。这些共享代码不会再编译进程序,而是放在单独的库中,供运行时加载。另外,RSL也可以在客户端进行缓存,因此不需要在每次使用程序时重复下载。

RSL(Runtime shared libraries)即动态链接库,在程序运行时由FlashPlayer动态加载。静态链接库是SWC文件,通过编译器的library-path和include-libraries 编译进应用程序。采用静态链接的应用程序SWF会产生比较大的文件以及更长的下载时间。使用RSL的应用程序载入时间短且文件比较小,而且提高了内存使用效率,只是 在开始需要花点时间下载RSL。RSL的强大体现在多个应用程序共享公共代码时,因为RSL只需要被下载一次,多个应用程序动态链接到相同的RSL,访问其中已经缓存在客 户端的资源。 使用RSL: (1).在项目文件夹中点右建,选择”properties”-“Flex Build Path”-“Library Path” (2).该选项卡上我们看到”FrameWork linkage”,默认是”Merged into cdoe”(FLEX4默认是RSL) (3).点开下拉,选择”runtime shared library(RSL)” (4).针对自定义的SWC,修改其link type为RSL,选择None,同时勾上Automatically extract swf to deployment path(自动将SWF提取到部署路径)。如果想对不同域的RSL共享,则选择Digests(摘要),同时指定其Policy file url(策略文件)。具体可参考FLEX SDK中的SWC文件处理方式。 (5).点击OK

##SWC

SWC 文件是类似 zip 的文件。静态链接库是SWC文件,通过编译器的library-path和include-libraries编译进应用程序。新建Flex Library Object或使用compc命令可以制作SWC。

##E4X E4X是在ECMA-357标准中定义的,并成为AS3的一部分。优点是提供更简明和可读性强的语法从XML中查找和提取数据。

##profile工具 可以很方便地观察对象的创建和销毁,帮助检查内存泄露问题。

##FlexUnit FlexUnit - Flex单元测试框架

##其他 1、flex生成出来的文件都是很大,请问你用什么办法进行缩小呢? (1)RSL (2)Module (3)外部加载资源

2、做一个flex项目,你认为成功的要素在哪呢? (1)数据和需求等传统软件项目的成功要素 (2)模块化开发,MVC框架 (3)swf文件减肥,运行效率,内存泄露问题,前台优化 (4)开源组件的使用

3、flex 前端的性能优化 (1)、避免容器的多级嵌套,减少相对尺寸、相对定位的使用。 (2)、尽量使用轻量级的容器 (3)、避免使用大体积的组件,比如DataGrid、AdvancedDataGrid (4)、处理数据时多用分页的方式 (5)、少使用setStyle (6)、使用延迟实例化加载子组件

4.Embed绑定图片有什么缺点? 答:直接编译到swf文件中,造成其体积过大。而且由于嵌入代码中,维护不便。

5、flex里调用JS措施? 答:直接在AS中利用ExternalInterface.call()来调用JS措施。如: import flash.external.ExternalInterface ; ExternalInterface.call(“JSFunction”); ExternalInterface.call(“JSFunctionWithParameters”,”myParameter”); var result:String=ExternalInterface.call(“JSFunctionWithReturn”); 6、用JavaScript调用ActionScript函数 答:利用ExternalInterface.addCallback在JavaScript里设置对Flex的回调措施并且在JavaScript里调用ActionScript措施。 AS: ExternalInterface.addCallback(“function1”,callback1); privatefunctioncallback1():void { Alert.show(“callback1executed”); } JS: container[swf].function1(); 6、FileReference browse(typeFilter:Array = null):Boolean//揭示一个文件博览对话框,让用户抉择要上载的文件。 cancel():void//废止正在对该 FileReference 对象厉行的任何上载或下载垄断。 download(request:URLRequest, defaultFileName:String = null):void//敞开对话框,以批准用户从长途服务器下载文件. upload(request:URLRequest, uploadDataFieldName:String = “Filedata”, testUpload:Boolean = false):void//开始将用户抉择的文件上载到长途服务器。

7、flash与flex是如何调停开发的? 答:这个问题能够这么来会意,万一是确乎必需用到FLEX SDK的利用,那我们就能够发生一个flex工程,翔实必需flash做UI的时候,输出成swc作为flex的skin,万一说并无须要flex sdk,只是为了编码得体而抉择flex的话,那我们凡是发生一个as工程,让flex作为flash的编码器。

8、请说下事件里的currentTarget 和 target的区别? 答:在事件流的过程中,目标阶段确定的目标对象由Event中的target属性来记录, 冒泡阶段移动的游标则由currentTarget来记录。事件对象冒泡过程中每往上移动一级,就会克隆出一个仅与前副本currentTarget不同的新副本。

9、warning: unable to bind to property ” on class ‘Object’ (class is not an IEventDispatcher) 在使用ItemRender时,经常会出现这种警告? 答:ArrayCollection的子元素是无法作为数据源绑定的。可以声明中间变量,在override set data时将ArrayCollection的子元素传入, 然后再将中间变量作为新的绑定源即可。

10、常用的几个切换数据的组件比如: TabNavigator等都有属性 creationPolicy 你知道这种策略的使用方式是什么嘛?以及优,缺点呢? 答:延迟实例化。优点是可以更快地加载组件,缺点是首次访问其他组件时,由于需要重新加载此组件,可能会有一定的延迟。

11、请试写一个自定义的验证组件 答:

package myCompenent
    {
        import mx.validators.Validator;//引用Validator
        import mx.validators.ValidationResult;//引用ValidationResult
        public class myValidators extends Validator
        {
            public function myValidators()//构造函数
            {
                super();
            }
            private var results:Array;//定义一个数组,用以存储错误
            //重写验证函数
            override protected function doValidation(value:Object):Array
            {
                var s:String = value as String;
                results = [];//清空数组
                results = super.doValidation(value);//先用继承类中的doValida tion方法验证
                if (results.length &gt; 0)//如果验证时有错,返回错误信息
                    return results;
                if(s.length&gt;6)//自定义验证,字符长度不超过6
                {
                    //记录出错信息
                    results.push(new ValidationResult(true,text,StringTooLong, “字符长度超过6了”));
                }
                return results;
            }
        }
    } 

在flex中监听鼠标右键事件,提示 TypeError Error 2007 参数type不能为空。

2013-03-11 Flash

在flex中监听鼠标右键事件 ,报错,提示 缺少参数、

TypeError: Error 2007: 参数 type 不能为空。

at flash.events::EventDispatcher/addEventListener()
at com.waylau.eagleos.components::DesktopExplorer/service_resultHandler()[D:\workspaceFB47\com.waylau.eagleos_0.9.5\src\com\waylau\eagleos\components\DesktopExplorer.mxml:59]
at com.waylau.eagleos.components::DesktopExplorer/__service_result()[D:\workspaceFB47\com.waylau.eagleos_0.9.5\src\com\waylau\eagleos\components\DesktopExplorer.mxml:214]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at HTTPOperation/http://www.adobe.com/2006/flex/mx/internal::dispatchRpcEvent()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\http\HTTPService.as:993]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::resultHandler()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:318]
at mx.rpc::Responder/result()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\Responder.as:56]
at mx.rpc::AsyncRequest/acknowledge()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:84]
at DirectHTTPMessageResponder/completeHandler()[E:\dev\4.y\frameworks\projects\rpc\src\mx\messaging\channels\DirectHTTPChannel.as:451]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

据悉,flash player 11.2版本以后支持鼠标右键,

所以开发的项目中运行时版本要相应设置,增加参数 -swf-version=15 以支持右键 ,即可


Flex/AS3/flash player支持屏蔽右键菜单,自定义菜单,并设置相应的菜单事件(示例,图解)

2013-03-04 Flash Flex

Flex/AS3/flash player支持屏蔽右键菜单,自定义菜单,并设置相应的菜单事件(示例,图解)

播放器 版本 11.2以后支持右键菜单屏蔽及自定义菜单 1.更新播放器 ,11.2 以上版本

http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_3.swc
http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_4.swc
http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_2.swc
http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_5.swc

2.编译器参数设置-swf-version=15(见图)

  1. 自定义 菜单,并设置相应的菜单事件 (Flex代码)
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
			   applicationComplete="init()">
	<fx:Script>
		<![CDATA[

			import mx.controls.Button;
			import mx.controls.Menu;
			import mx.events.MenuEvent;
			import mx.controls.Alert;

			private var menu:Menu = null;
			private var bt:Button = new Button();

			private function init():void {
				bt.label = "走你~";
				network.addElement(bt);
				network.addEventListener(MouseEvent.RIGHT_CLICK,handleRighClick);//监听右键
			}
			private function handleRighClick(e:MouseEvent):void {

				if(menu != null){
					menu.hide();
				}
				menu = Menu.createMenu(network, myMenuData, false);//myMenuData菜单数据源
				menu.labelField = "@label";//右键菜单的文字

				var point:Point = network.globalToLocal(new Point(e.stageX, e.stageY));
				menu.show(point.x, point.y);
				menu.addEventListener(MenuEvent.ITEM_CLICK,menuItemClickHandler);  //菜单事件
			}

			private function menuItemClickHandler(evt:MenuEvent):void{
				Alert.show([email protected])  //将事件名显示出来
			}
		]]>
	</fx:Script>
	<fx:Declarations>
		<fx:XML id="myMenuData">
			<root label="MenuItem 1" >
				<menuitem label="new" eventName="new" />
				<menuitem label="refreash" eventName="refreash" />
				<menuitem label="remove" eventName="remove" />
			</root>

		</fx:XML>
	</fx:Declarations>
	<s:Group id="network" width="100%" height="100%"  />
</s:Application>


可行性分析与需求分析

2013-02-27 Management Design

一、概念

可行性分析——可干否 需求分析——要干啥(避免需求蔓延) 二、可行性分析

柳传志“三不干”:没钱赚的事我们不干;有钱赚但投不起钱的事不干;有钱赚也投得起钱但没有可靠的人选,这样的事也不干。 可行性分析要素:经济、技术、社会环境、人 (1) 经济:成本——收益分析、短期——长远利益分析

(2) 技术:技术熟悉度、成熟度、可靠性、稳定性、技术成本、学习曲线

(3) 社会环境:市场、法律、道德

(4) 人——“人物,人才,人手,人渣。”最好的分工是让“人物”当领导,“人才”做第一线的开发人员,“人手”做行政人员,“人渣”负责行贿。

可行性分析报告(附录1) 三、需求分析

难点:客户说不清、需求老变更、理解有偏差 过程: 3.方式:

(1) 研究用户

(2) 调查问卷

(3) 原型完善

(4) 用户陈述

4.需求规格说明书(附录2)

附录1(可行性分析报告)

1.引言

1.1 编写目的

阐明编写可行性研究报告的目的,描述报告基本组成要素,指出读者对象。

1.2 项目背景

列出拟开发软件系统的名称,项目委托者、开发者和预期用户,说明该软件系统与其他系

统之间的关系等。

1.3 定义

列出报告中所使用的专门术语的定义和缩写词的原意。

1.4 参考资料

列出本文档需要引用的参考资料的来源。包括:已被批准的项目任务书、合同或上级机关

批文,与项目有关的已经公开发表的论文、著作,需要采用的标准或规范。

2.可行性研究的前提

2.1 基本要求

列出项目的各项基本要求,涉及功能、性能、数据输入、数据输出、数据处理流程、安全

保密要求、与其他系统的关系、完成期限等。

2.2 基本目标

涉及人力与设备费用的减少,工作环境的改善,工作效率的提高,处理速度、控制精度或

生产能力的提高,信息管理服务的改进,自动决策功能的改进等。

2.3 条件、假定和限制

涉及拟开发系统运行寿命的最小值,项目经费来源与限制,政策和法规方面的限制,硬件、

软件、开发环境和运行环境方面的条件与限制,可以利用的相关资源,拟开发系统要求投入使

用的最迟时间等。

3.对现有系统的分析

3.1 系统模型

可使用系统方框图、系统流程图说明现有系统的基本构造与基本处理流程。

3.2 工作负荷

列出现有系统所承担的工作与工作量。

3.3 费用支出

涉及现有系统运行过程中的人力、设备、空间、支持性服务和材料等各项支出。

3.4 局限性

指出现有系统存在的问题,并说明开发新系统或改造现有系统的必要性。

B.2 项目计划说明书209

4.对拟开发系统的分析

4.1 拟开发系统的体系结构

可使用系统方框图对拟开发系统的体系结构进行概要描述。

4.2 拟开发系统的工作模型

可使用系统流程图说明拟开发系统的基本处理流程。

4.3 拟开发系统的优越性

将拟开发系统与现有系统进行对比,并在诸如提高处理能力、减轻工作负荷、增强系统灵

活性和保证数据安全等方面,说明拟开发系统所具有的优越性。

4.4 拟开发系统可能带来的影响

涉及拟开发系统将对硬件设备、软件配置和用户操作等方面带来的影响。

5.对拟开发系统的可行性评价

5.1 技术可行性评价

说明拟开发系统在技术方面具备的可行性,例如,在当前技术允许的条件下,该系统的功

能目标能否达到;在规定的时间期限内,该系统的开发能否按期完工。

5.2 经济可行性评价

说明拟开发系统所需的开发费用和可以预期的经济收益,并由此进行成本效益分析。

5.3 社会因素的可行性评价

从法律法规、用户操作规程等方面进行可行性评价,例如项目合同中责任是否明确,拟开

发系统是否存在著作侵权,是否侵犯了国家、集体或他人的利益,拟开发系统是否充分考虑到


Cairngorm框架项目开发流程

2013-02-26 Cairngorm Flex

##Cairngorm框架的流程,由前往后 ,如下:

###Services.mxml

###VO ###model ###注册model

###event // 常量值简短,有利于编译效率 ###DL ###command

###AppControl

###view


软件工程概述

2013-02-20 Management

一、软件工程概述

软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。

最主要的目的是为了解决软件危机。

 

二、软件危机

表现:

1.软件开发成本、进度的估计很不准确

软件开发机构制定的项目计划跟实际情况有很大差距,使得开发经费一再突破。由于对工

作量和开发难度估计不足,进度计划无法按时完成,开发时间一再拖延,这种现象严重降低了软件开发机构的信誉。

2.软件产品常常与用户的要求不一致

在开发过程中,软件开发人员和用户之间缺乏信息交流。开发人员常常是在对用户要求只

有模糊了解的情况下就仓促上阵,匆忙着手编写程序。由于这些问题的存在,导致开发出来的软件不能满足用户的实际应用需要。

3.软件产品质量可靠性差

软件开发过程中,没有建立起确实有效的质量保证体系。一些软件项目为了赶进度或降低

软件开发成本,甚至不惜降低软件质量标准、偷工减料。

4.软件文档不完整、不一致

计算机软件不仅仅是程序,在软件开发过程中还应该产生出一系列的文档资料。实际上,

软件开发非常依赖这些文档资料。在软件开发过程中,软件开发机构的管理人员需要使用这些文档资料来管理软件项目;技术人员则需要利用文档资料进行信息交流;用户也需要通过这些文档资料来认识软件,对软件进行验收,熟悉软件的安装、操作等。但是,由于软件项目管理工作的欠缺,软件文档往往不完整,对软件的描述经常不一致,很难通过文档去跟踪软件开发过程中软件产品规格的变更。

5.软件产品可维护性差

软件中的错误非常难改正,软件很难适应新的硬件环境,很难根据用户的需要在原有软件

中增加一些新的功能。这样的软件是不便于重用的,以前开发的软件,一旦过时就不得不完全丢弃。

6.软件生产率低

软件生产率跟不上硬件的发展速度,不能适应计算机应用的迅速普及,以致现代计算机硬

件提供的巨大潜力不能被充分利用。

 

三、危机产生的原因

看点历史:

观察软件的发展,可以发现软件生产有三个发展时代,即程序设计时代、程序系统时代和

软件工程时代。

1.程序设计时代(20 世纪50 年代)

这个时期的程序大多是自用,程序的编写者往往也就是使用者,软件还没有形成为产品。

由于早期程序大多是为某个具体应用而专门编写的,程序任务单一,因此,对程序的设计也就仅仅体现在单个程序的算法上。早期程序还往往只能在某台专门的计算机上工作,很难将程序由一台设备移植到另一台设备。

 

2.程序系统时代(20 世纪60 年代)

这个时期的软件开发更多地依赖于个人创作。由于软件开发的主要内容仍然是程序编写,

软件开发的核心问题仍是技术问题;于是,用户的意图被忽视了,除了程序之外的其他文档、

技术标准、软件在今后运行过程中的维护等问题,也往往被忽视了。

软件已经开始成为产品,但软件的生产方式则是跟产品并不适宜的作坊创作方式。于是,

随着软件规模的不断扩大,软件危机现象在这个时期最终爆发出来。

 

3.软件工程时代(20 世纪70 年代起)

1968 年在联邦德国召开的计算机国际会议上,专门针对软件危机问题进行了讨论,在这次

会议上正式提出并使用了“软件工程”术语。于是,软件工程作为一门新兴的工程学科诞生了。

在软件开发上,自20 世纪70 年代以来的30 年里,结构化的工程方法获得了广泛应用,

并已成为了一种成熟的软件工程方法学;而自20 世纪90 年代起,基于面向对象的工程方法,也已被应用于软件开发之中。应该说,采用工程的原理、技术和方法实施软件产品开发,以适应软件产业化发展的需要,成为了这个时期诸多软件企业的追求目标。

 

 

真正的原因:

1.软件的不可见特性

软件不同于硬件,它是计算机系统中的逻辑部件,缺乏“可见性”。硬件错误往往可以通

过它的物理现象直接反映出来,例如,出现不正常的发热、噪音现象等;但软件错误没有这些直观表现,例如,软件中存在的程序行错误,就必须等到这行程序执行时才有可能被发现。因此,软件错误比起硬件错误来更难发现。软件的不可见特性也使得对软件项目的量化管理更难实施,对软件质量的量化评价更难操作。

2.软件系统规模庞大

软件成为产品以后已不同于早期程序,随着它的功能的增多,其规模、复杂程度越来越大。

例如,1968 年美国航空公司订票系统达到30 万条指令;IBM360OS 第16 版达到100 万条指令;1973 年美国阿波罗计划达到1 000 万条指令。这些庞大规模的软件系统,其复杂程度已超过了人所能接受的程度;但是,面对不断复杂的软件系统,其开发手段却仍然需要依靠开发人员的个人创造与手工操作。

3.软件生产工程化管理程度低

软件生产的工程化管理是软件作为产品所必须的,这意味着软件也需要像硬件一样,在软

件分析、设计完成之后,才能考虑软件的实现。应该说,工程化管理能够降低解决问题的代价。但是,许多软件的开发则往往是在分析、设计没有完成的情况下,就已经进入编码实现阶段。由于前期准备工作不充分,致使软件项目管理纷乱,严重影响软件项目成本、开发进度。

4.对用户需求关心程度不够

软件开发机构不熟悉用户业务领域。软件技术人员所关注的仅仅是计算机技术,它们不太

愿意和用户沟通,轻视对用户的需求调查,也缺乏有效的用户调查策略、手段。由于这些问题的存在,使得用户的需求意愿不能充分反映,或被错误理解。

实际上,软件是为用户开发的,只有用户才能真正了解他们自己的需要。由于没有对用户

做大量深入细致的调查研究,以致软件需求规格定义不准确,并最终使得完成后的软件不能适应用户的应用需要。

5.对软件维护重视程度不够

软件开发缺乏统一的规范。在软件产品开发过程中,开发者很少考虑到这个软件今后还需

要提供维护。但是,软件的使用周期漫长,软件错误具有隐蔽性,许多年之后软件仍可能需要改错。另外,软件的工作环境也可能会在几年后发生改变;用户也可能在软件运行几年以后,要求对它增加新的功能。这些都是属于软件维护问题。实际上,软件的可维护性是衡量软件质量的一项重要指标,软件可维护性程度高,软件就便于修正、改版和升级,由此可以使软件具有更长的使用寿命。

6.软件开发工具自动化程度低

尽管软件开发工具比30 年前已经有了很大的进步,但直到今天,软件开发仍然离不开工

程人员的个人创造与手工操作,软件生产仍不可能像硬件设备的生产那样,达到高度的自

动化。

 

四、探讨如何解决危机

  1. 软件工程的主要环节有:人员管理、项目管理、可行性与需求分析、系统设计、程序设计、测试、维护

 

 

  1. 常见的软件工程模型有:线性模型(瀑布模型),渐增式模型,螺旋模型,快速原型模型,增量模型,喷泉模型等

最早出现的软件工程模型是线性模型(又称瀑布模型)。

瀑布模型核心思想是按工序将问题化简,将功能的实现与设计分开,便于分工协作,即采用瀑布模型用结构化的分析与设计方法将逻辑实现与物理实现分开。将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。

002

优点

1)为项目提供了按阶段划分的检查点。

2)当前一阶段完成后,您只需要去关注后续阶段。

缺点

1)在项目各个阶段之间极少有反馈。

2)只有在项目生命周期的后期才能看到结果。

3)通过过多的强制完成日期和里程碑来跟踪各个项目阶段。

4)瀑布模型的突出缺点是不适应用户需求的变化.

 

线性模型太理想化,太单纯,已不再适合现代的软件开发模式,几乎被业界抛弃。但是复杂的“非线性”问题时,总是千方百计地将其分解或转化为一系列简单的线性问题。

 

 

螺旋模型:

基本做法是在“瀑布模型”的每一个开发阶段前引入一个非常严格的风险识别、风险分析和风险控制,它把软件项目分解成一个个小项目。每个小项目都标识一个或多个主要风险,直到所有的主要风险因素都被确定。

003

优点

1)设计上的灵活性,可以在项目的各个阶段进行变更。

2)以小的分段来构建大型系统,使成本计算变得简单容易。

3)客户始终参与每个阶段的开发,保证了项目不偏离正确方向以及项目的可控性。

4)随着项目推进,客户始终掌握项目的最新信息 , 从而他或她能够和管理层有效地交互。

5)客户认可这种公司内部的开发方式带来的良好的沟通和高质量的产品。

缺点

很难让用户确信这种演化方法的结果是可以控制的。建设周期长,而软件技术发展比较快,所以经常出现软件开发完毕后,和当前的技术水平有了较大的差距,无法满足当前用户需求。

螺旋模型的项目适用:

对于新近开发,需求不明确的情况下,适合用螺旋模型进行开发,便于风险控制和需求变更!

 

快速原型模型


Linux(Ubuntu)下设置golang环境变量

2013-01-31 Golang

1).源代码安装go语言

Go的工具链采用C语言编写,要构建它,你需要安装一个C编译器,本例采用gcc工具; 进入linux 终端,输入命令行

sudo apt-get install build-essential

Go使用Mercurial进行版本管理,首先你必须安装了Mercurial,对于 Ubuntu/Debian 系统先安装easy_install;

sudo apt-get install mercurial

出现Processing triggers for python-support…需先安装python环境 执行

sudo apt-get install python-setuptools python-dev

sudo easy_install mercurial

如果 还不行,那直接下载Mercurial安装

获取GO代码

hg clone -r release https://go.googlecode.com/hg/ $GOROOT

安装Go:

cd $GOROOT/src

./all.bash

如果 还不行,那直接下载编译好的代码安装 解压 go包放用户根目录下

sudo tar zxvf ~/Downloads/go1.0.3.linux-386.tar.gz -C /opt

2).设置环境变量,在/etc/profile文件同添加以下内容

sudo gedit /etc/profile

export GOROOT=$HOME/go
export GOBIN=$GOROOT/bin
export GOARCH=386
export GOOS=linux
export GOPATH=$HOME/workspacego
export PATH=.:$PATH:$GOBIN

GOARCH、GOOS为可选配置,交叉编译时有用 GOPATH设置工作空间,允许多个目录,当有多个目录时,用分隔符分隔,当有多个GOPATH时,默认会将go get的内容放在第一个目录下;

$GOPATH 目录约定有三个子目录:

src 存放源代码(比如:.go .c .h .s等)

pkg 编译后生成的文件(比如:.a)

bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中)

应用刚刚配置的环境变量:source /etc/profile

上面的配置是针对系统级别的,建议采用用户级别的配置如下:

如果用户根目录下不存在.bash_profile,则

cat > .bash_profile

export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=$HOME/workspacego

CTRL_D(这是按 CTRL - D两个键同时)

每次启动系统应用

. ./.bash_profile

官方建议把配置记录在用户在~/.bashrc或者 ~/.profile中,这样 登陆就可以使用go 而不用,每次登陆系统都要执行. ./.bash_profile

配置文件的区别,请参阅后面的附录

3).查看go是否是release版

hg identify

更新go到新版本

cd $GOROOT

hg pull

hg update release

./all.bash

4).浏览本地doc

在命令行执行

godoc -http=:8080

在浏览器地址输入:http://127.0.0.1:8080,即可进入doc界面

5).搭建基于浏览器的交互式Go编程指南-gotour

5.1).安装Go语言英文教程:

sudo go get code.google.com/p/go-tour/gotour

5.2).安装Go语言中文教程:

sudo go get bitbucket.org/mikespook/go-tour-zh/gotour

在命令行执行gotour,在浏览器地址输入:http://127.0.0.1:3999,即可进入教程的学习界面。

附录

参考:http://blog.csdn.net/wumingxing0228/article/details/6050175

环境变量是和Shell紧密相关的,用户登录系统后就启动了一个Shell。对于Linux来说一般是bash,但也可以重新设定或切换到其它的 Shell。对于UNIX,可能是CShelll。环境变量是通过Shell命令来设置的,设置好的环境变量又可以被所有当前用户所运行的程序所使用。对于bash这个Shell程序来说,可以通过变量名来访问相应的环境变量,通过export来设置环境变量。下面通过几个实例来说明。

1)etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. 注:在这里我们设定是为所有用户可使用的全局变量。

2)/etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.

3)~/.bashprofile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件. 注:~在LINUX下面是代表HOME这个变量的。 另外在不同的LINUX操作系统下,这个文件可能是不同的,可能是~/.bashprofile; ~/.bash_login或 ~/.profile其中的一种或几种,如果存在几种的话,那么执行的顺序便是:~/.bashprofile、 ~/.bashlogin、 ~/.profile。比如我用的是Ubuntu,我的用户文件夹下默认的就只有~/.profile文件。

4)~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被读取. (注:这个文件是 .开头的,所以在文件夹中被隐藏了) 那么我们如何添加自己定义的环境变量呢? 用记事本打开这个文件,然后在里面最后写上: xiaokang=kangkang 然后保存,这样每次打开一个新的terminal的时候,我们这个变量就生效了。记住,如果你已经打开一个terminal,然后你修改了这个文件,那么在这个terminal下是不会生效的。一般情况用户最好在这里进行修改,但是有时候会覆盖父级的变量,比如PATH是ROOT设定的,但是如果你在这个文件里面写了PATH=xx,那么将来所有的PATH都成了xx了,所以我们应该在这个文件中写为: PATH=$PATH:xx 这样就把原来的和你自己的一起加上了。而且注意在LINUX系统下用:分割表示并列,而不是windo的; 3和4都是在用户目录下的,他们唯一的不同是: .bash_profile只能在登录的时候启动一次。在我的Ubuntu里面这个3文件似乎没有。

5)~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件. 另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是/”父子/”关系.

~/.bash_profile 是交互式、login 方式进入 bash 运行的 ~/.bashrc 是交互式 non-login 方式进入 bash 运行的 通常二者设置大致相同,所以通常前者会调用后者。

好的,总结一下他们的执行方式: 当你登录并且登录shell是bash时,bash首先执行/etc/profile文件中的命令(如果该文件存在),然后它顺序寻找~ /.bashprofile,~/.bashlogin或~/.profile文件,并执行找到的第一个可读文件中的命令.当登录bash退出时,它 将执行~/.bashlogout文件中的命令. 当启动一个交互的bash时,它将执行~/.bashrc文件中的命令(如果该文件存在并且可读).当非交互地启动以运行一个shell脚本时,bash将查找bashenv环境变量,确定执行文件的名称.



Go For Java Programmers(面向Java开发者的GO编程)

2013-01-13 Golang Java

本文旨在帮助JAVA开发者迅速掌握 Go语言.

开始用一个很容易能被所有的Java程序员认出的例子来突出特色,然后对GO的框架给出了详细的的描述,最后用一个例子来说明GO结构中没有与 Java直接对应处。

##Hello stack (一个栈的例子) 为了吊起你的胃口,我们用一个麻雀虽小,五脏俱全和符合习惯的例子对应这个Stack.java 程序


// 包collection实现了生成栈.
package collection

// 零值栈是一个空栈,准备被使用.
type Stack struct {
    data []interface{}
}

// Push函数将x添加到栈顶.
func (s *Stack) Push(x interface{}) {
    s.data = append(s.data, x)
}

// Pop函数是将栈顶元素移除并返回.
// 在Pop函数执行在空栈时,会被一个运行时的error警示.
func (s *Stack) Pop() interface{} {
    i := len(s.data) - 1
    res := s.data[i]
    s.data[i] = nil  // 避免内存泄露
    s.data = s.data[:i]
    return res
}

// Size函数返回栈中元素的个数
func (s *Stack) Size() int {
    return len(s.data)
}

stack.go

  • 顶级声明出现之前,直接的评论是文档注释。他们是纯文字。.
  • 对于声明,你把名字写在类型后面.
  • struct 对应Java中的类, 但struct组成不是方法而只能是变量.
  • Tinterface{}类型对应Java的 Object. 在GO中它被所有的类型所实现,而不仅仅是引用类型.
  • 代码段 (s *Stack) 声明了一个方法,接收者 s 对应Java中的 this.
  • 操作符:=声明并初始化了一个变量. 它的类型可以从初始化表达式中推导出.

这里是一个的Hello world程序,演示了如何使用collection.Stack的抽象数据类型.


package collection_test

import (
    collection "."
    "fmt"
)

func Example() {
    var s collection.Stack
    s.Push("world")
    s.Push("hello, ")
    for s.Size() > 0 {
        fmt.Print(s.Pop())
    }
    fmt.Println()
    //输出: hello, world
}

example_test.go

##概念上的差异

  • Go的构造器没有类。Go 用 structs 和 interfaces来替代实例化方法,类的继承机制,动态方法查找.也可用于Java使用泛型接口
  • Go提供所有类型的指针的值,而不只是对象和数组。对于任何类型 T,有一个相应的指针类型*T表示指针指向类型 T的值。 offers pointers to values of all types, not just objects and arrays.
  • Go允许任何类型都有方法而没有装箱的限制 allows methods on any type; no boxing is required. 方法receiver,在Java中对应this可以是直接值或者是指针.
  • 数组在Go就是值. 当一个数组被当做函数的参数时,这个函数接收到的是数组的拷贝而不是它的指针. 然而在实践中,函数经常使用 slices作为参数; slices引用了基础数组.
  • 该语言提供了字符串,一个字符串行为就像一个字节片,但是是不可改变的。
  • 该语言中的哈希表被称作maps.
  • 该语言提供了独立运行的线程goroutines 和他们之间的通信渠道channels.
  • 某些类型(maps, slices, 和 channels)是按引用传递,而不是值。也就是说,传递一个map到函数并而不是拷贝map,如果函数修改了map,将被调用者看到变化。在Java术语来说,可以认为这是一个map的引用.
  • Go提供了两种访问级别对应Java的public和包的private.如果它的命名是大写字母开头就是最高级别public,反之就是包的private.
  • 作为替换Java中的异常机制, Go采用了类型 error值来表示事件,如文件结尾,和运行时的panics来表示运行时的错误,如数组越界等.
  • Go不支持隐式类型转换。混合使用不同类型的操作需要显式转换.
  • Go不支持函数重载。在同一范围内的函数和方法必须具有唯一的名称.
  • Go使用nil表示无效的指针,类似于Java使用null.

##句法 ###声明

声明是跟Java是相反的。你在类型后面再写名称,类型声明从左往右更容易读

Go 与Java相对应的

Go 与Java相对应的
var v1 int int v1;
var v2 *int Integer v2;
var v3 string String v3 = "";
var v4 [10]int int[] v4 = new int[10]; // v4 在Go中是一个值.
var v5 []int int[] v5;
var v6 *struct { a int } C v6; // Given: class C { int a; }
var v7 map[string]int HashMap<String,Integer> v7;
var v8 func(a int) int F v8; // Given: interface F { int f(int a); }

声明的一般形式是一个关键字后面跟着被声明对象的名字.这个关键字是const, type, var, 或者func. 您也可以使用一个关键字,后面的括号中跟着一系列声明.

var (
    n int
    x float64
)

当声明一个函数,你必须提供每个参数的名称,或者不提供任何参数的名称,你不能提供了一些而忽略了另外一些名字。您可以组合几个相同类型的名称:

func f(i, j, k int, s, t string)

一个变量可以在声明时初始化。当这样做时,指定的变量的类型是允许的,但不是必需的。当未指定类型,默认的是初始化表达式的类型.

var v9 = *v2 如果一个变量没有立即初始化,必须要制定类型。那样的情况下,它它会被隐式初始化该类型的零值zero value(0, nil, "", 等.). Go不存在未初始化的变量.

###短声明

在函数中,一个短的声明句法是 := 表示.

v10 := v1 这等效于

var v10 = v1

###函数类型

在Go中,函数都是一等公民。Go的函数类型表示一组所有具有相同的参数和返回类型的函数.

type binOp func(int, int) int

var op binOp
add := func(i, j int) int { return i + j }

op = add
n = op(100, 200)  // n = 100 + 200

###多重分配

GO允许多重分配。在右边的表达式会在评估后,再分配到任何的左操作数。

i, j = j, i  //交换i和j. 函数可以具有多个返回值,表示由括号中的列表。返回的值可以存储分配给一个变??量列表。

func f() (i int, pj *int) { ... }
v1, v2 = f()

###空白标识符

空白标识符提供了一种忽略多值表达式返回值的方式,用下划线字符表示: The blank identifier, represented by the underscore character, provides a way to ignore values returned by a multi-valued expression:

v1, _ = f()  // 忽略f()返回的第二个值.

###分号和格式

为了消除对分号和格式不必要的担忧,你可能会用gofmt程序来写GO风格的标准代码,虽然这种风格看起来很古怪,但熟悉了之后最终会像其他语言风格一样变得舒服

Go的代码在实际中很多出现分号。严格来说,Go所有的声明都用分号结束。但是Go毫无疑问会在每个非空白行的结尾插入一个分号,除非它还没有完. 这样做的后果是,在某些情况下,Go不允许断行。举例,你可能会像下面这样写:

func g()
{            //无效的;“{”应该是在前面那一行。
} 在g()后面会被插入一个分号,这样就使他像是一个函数声明而不是函数定义了类似的,你不能这样写:

if n == 0 {
}
else {       // 无效的; "else {" 应该是在前面那一行。
} 在} 后和else前面会插入一个分号,导致句法错误.

###条件语句

Go在条件语句中并不使用括号,像 if条件语句 , for 条件语句的表达式, switch 条件语句的值. 另一方面,它并不需要在 if或 for条件语句中加花括号

if a < b { f() }
if (a < b) { f() }           // 括号是不必要的.
if (a < b) f()               // 无效的
for i = 0; i < 10; i++ {}
for (i = 0; i < 10; i++) {}  // 无效的

此外, if和switch 接收一个可选的初始化的状态,那么惯用做法是建一个局部变量

if err := file.Chmod(0664); err != nil {
    log.Print(err)
    return err
}

###For 语句

Go没有while和do-while语句. 当for语句的条件比较单一时,他的作用就像是while语句. 完全省略条件则产生一个死循环。

for语句可能包含range遍历 strings, arrays, slices, maps, 或 channels。除了写成下面这样

for i := 0; i < len(a); i++ { ... } 去遍历a的元素,也可以写成

for i, v := range a { ... } 这里的i指索引, v代表的array, slice, 或者string的连续元素。对于字符串,i是一个字节的索引,v指向rune类型(rune类型是int32)的一个别名)。maps迭代产生键 - 值对,而channels只产生一个迭代值。

###Break和continue

像Java一样,GO许可break和continue指定一个标签,但标签上必须指的for, switch, 或者 select 语句.

###Switch 语句

在 switch 语句,case 标签默认情况下不通过,但你可以让他们 fallthrough语句结束的情况下通过了。

switch n {
case 0:  // empty case body
case 1:
    f()  // f is not called when n == 0.
} 但是一个case可以包含过个值

switch n {
case 0, 1:
    f()  // f is called if n == 0 || n == 1.
} case的值可以支持任何类型的相等比较操作符,如字符串或指针。一个丢失表达式的switch语句 等价于表达式为 true。

switch {
case n < 0:
    f1()
case n == 0:
    f2()
default:
    f3()
} ### ++ 和 -- 语句

++和–只能作为后缀操作符,和仅在语句中,而不是在表达式中。例如,你不可以写n = i++。

defer语句

defer语句调用一个函数的执行被推迟到函数返回那一刻。defer语句执行时,被递延的函数的参数被计算,并保存,以备将来使用

f, err := os.Open("filename")
defer f.Close()  // f will be closed when this function returns.

##Constants(常量) GO中的常数可能是untyped的。这适用于无类型的常量表达式的数字文本,和使用const声明的无类型的常量表达式。当它被用在需要一个带类型的值的背景下,一个无类型的常量的可以被转变成有类型的值。这样常量的使用相对自由,即使Go没有隐式类型转换

var a uint
f(a + 1)    // The untyped numeric constant 1 becomes typed as uint.
f(a + 1e3)  // 1e3 is also typed as uint. 语言对非类型化的数字常量不限制大小。限制仅适用于使用一个常量时,其中一种类型是必需的。

const huge = 1 << 100
var n int = huge >> 98 如果是不存在的变量声明的类型和相应的表达式的计算结果为一个非类型化的数字常数,这个常数是被转换为 rune, int, float64, 或者complex128 类型,取决于该值是否一个字符,整数,浮点,或复杂的常数。

c := '?'      // rune (alias for int32)
n := 1 + 2    // int
x := 2.7      // float64
z := 1 + 2i   // complex128 GO 不存在枚举类型。相反,你可以使用特殊的名字iota在单一的const声明中从而得到一系列累加值。当初始化表达式省略为一个 const,它重用了前面的表达式。

const (
    red = iota  // red == 0
    blue        // blue == 1
    green       // green == 2
)

Structs(结构体)

结构体对应于Java中的类,但一个结构的成员不能是方法,而是变量。结构体的指针是类似Java的的引用变量。与Java类不同的是,结构也可以被定义为直接值。在这两种情况下使用 .来访问结构体的成员。

type MyStruct struct {
    s string
    n int64
}

var x MyStruct      // x is initialized to MyStruct{"", 0}.
var px *MyStruct    // px is initialized to nil.
px = new(MyStruct)  // px points to the new struct MyStruct{"", 0}.

x.s = "Foo"
px.s = "Bar" 在Go中,方法可以与任何命名的类型关联,而不仅仅是与结构体。详情见方法和接口的讨论。

##Pointers(指针)

如果你有一个int或struct或者array需要分配对象的内容复制。 想达到Java的引用变量的效果,Go使用指针。对于任何类型e T,有一个相应的指针类型*T,表示指针类型 T的值

给指针变量分配存储空间,使用内置函数new,传入一个类型,并返回一个指针,指向分配的存储空间。分配的空间将被零初始化的类型。例如, new(int) 分配存储为一个新的int,初始化它的值为e 0,并返回它的地址,类型 *int。

Java代码T p = new T(),其中 T是一个两个int型实例变量a和b的类,对应于

type T struct { a, b int }
var p *T = new(T) 或者习惯性这样干

p := new(T) var v T代表声明,声明了一个变量包含一个值类型 T,这在Java中是没有的。也可使用复合方式创建并初始化值。

v := T{1, 2} 等同于

var v T
v.a = 1
v.b = 2 对于类型T的操作数x,地址运算符 &x提供值类型为*T的x的地址,

##Slices(切片) slice是概念上一个结构包含三个域:一个数组的指针、长度和容量。切片支持[]操作符来访问底层数组的元素。内置的len函数返回的切片长度。内置的的cap函数返回切片的能力。

给定一个数组,或另一个切片,通过a[i:j]来创建一个新的切片。这个新创建的切片指向a,从索引i开始,并结束索引j之前。它的长度是j - i。如果i 被省略,切片从0开始。如果j 被省略,切片在 len(a)结束。新切片跟 a一样指向相同的数组。即,改变后组成的新的切片的元素在a都能见到。新切片的容量就是简单的a减去i。数组的容量就是数组的长度。

var s []int
var a [10]int

s = a[:]  // short for s = a[0:len(a)] 如果你创建一个值类型为[100]byte(100个字节,也许是一个缓冲区的数组),你想不复制它,而将它传递给函数,那么函数的参数声明类型[]byte,并传入数组的切片。切片也可以用 make的函数创建(如下文所述)。

切片组合采用内置的append函数,Java的ArrayList提供相同的功能。

s0 := []int{1, 2}
s1 := append(s0, 3)      // append a single element
s2 := append(s1, 4, 5)   // append multiple elements
s3 := append(s2, s0...)  // append a slice 切片语法,也可以使用在字符串上。它返回一个新字符串,其值是原始的字符串的子串

##make函数 Map and channel values must be allocated using the built-in function make. For example, calling map和channel值必须使用内置的函数make。例如,调用

make(map[string]int) map[string]int返回一个新分配的值类型。相对于new, make 返回的是实际的对象,而不是一个地址。这是一致的事实,map和channel是引用类型。

对于map,make函数将容量作为一个可选的第二个参数的提示。对于channel,有一个可选的第二个参数来设置channel的缓冲能力,默认为0(无缓冲)。

make函数也可以用来分配一个切片。在这种情况下,它分配内存给基本数组并返回一个引用他的切片。该切片中的元素数是一个必需的参数。第二个可选的参数是切片的容量。

m := make([]int, 10, 20)  // Same as new([20]int)[:10]

##方法和接口 ###方法

方法看起来像一个普通的函数定义,但它有一个receiver(接收者)。receiver是类似Java实例方法中的this引用。

type MyType struct { i int }

func (p *MyType) Get() int {
    return p.i
}

var pm = new(MyType)
var n = pm.Get() 这声明了一个方法Get与MyType关联的。receiver被命名为p 在函数体内。

命名的类型来定义方法。如果您转换不同类型的值,新的值将有新的类型,而不是那些旧的类型。

你可以定义一个内置类型的方法,用新的命名类型声明。新的类型和内置的类型是不同的。

type MyInt int

func (p MyInt) Get() int {
    return int(p)  // The conversion is required.
}

func f(i int) {}
var v MyInt

v = v * v          // The operators of the underlying type still apply.
f(int(v))          // int(v) has no defined methods.
f(v)               // INVALID

###接口

Go接口类似于Java接口,但可被视为一个实现该接口提供任何类型的在Go接口命名的方法。明确的声明是不必要的。

接口像这样:

type MyInterface interface {
    Get() int
    Set(i int)
} 自从 MyType 已经有了Get 方法, 我们可以让 MyType满足接口通过添加

func (p *MyType) Set(i int) {
    p.i = i
} 现在任何只要将MyInterface当做参数就可以接收类型是*MyType的变量

func GetAndSet(x MyInterface) {}

func f1() {
    var p MyType
    GetAndSet(&p)
} 在Java术语,给MyType 定义 Set和Get 使MyType自动实现了MyInterface接口。这种类型型可满足多个接口。这是一种形式的鸭子类型。

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。” James Whitcomb Riley

###匿名域

匿名域可以用于实现很像一个Java子类的东西。

type MySubType struct {
    MyType
    j int
}

func (p *MySubType) Get() int {
    p.j++
    return p.MyType.Get()
}
MySubType有效实现的像是MyType的子类型.

func f2() {
    var p MySubType
    GetAndSet(&p)
} Set方法是继承自MyType的,因为关联了匿名域的方法的变为了封闭类型的方法。在这种情况下,因为 MySubType有一个匿名与域 MyType类型,所以为 MyTypee的方法也成为MySubType的方法。Get方法被重写,Set方法被继承。

这是与Java中的子类不完全相同。当一个匿名域的方法被调用时,它的 receiver就是这个匿名域,而不是周围的结构体。换句话说,匿名域上的方法的不会动态调度。当你想要实现相当于Java的动态方法查找,请使用接口。

func f3() {
    var v MyInterface

    v = new(MyType)
    v.Get()  // Call the Get method for *MyType.

    v = new(MySubType)
    v.Get()  // Call the Get method for *MySubType.
}

###类型断言

使用一个类型断言可以使具有一个接口类型的变量转换成具有不同的接口类型。这是在运行时动态执行。与Java不同,并不需要任何声明两个接口之间的关系。

type Printer interface {
    Print()
}

func f4(x MyInterface) {
    x.(Printer).Print()  // type assertion to Printer
} 转换为Printer 完全是动态的。只要x(x中存储的值的实际类型)的 动态类型 定义了一个Print方法。

##Errors(错误机制) Go的多值的返回可以很容易地沿着正常的返回值返回详细的错误消息。按照惯例,这样的error类型的消息,就像下面的简单的内置接口

type error interface {
    Error() string
} 例如,os.Open函数当它无法打开文件时返回一个非零error值。

func Open(name string) (file *File, err error) 以下代码使用 os.Open打开一个文件。如果 error发生,它调用 log.Fatal打印错误信息并停止。

f, err := os.Open("filename.ext")
if err != nil {
    log.Fatal(err)
}
// do something with the open *File f error的接口只需要一个 Error的方法,但具体的error的实现往往有额外的方法,允许调用者进行检查错误的详细信息

##Panic and recover(恐惧和恢复) panic(恐慌)是一个运行时错误,展开goroutine的堆栈,一路运行任何递延的功能,然后停止程序。恐慌与Java异常相似,但只适用于运行时的错误,如一个nil 指针或试图索引数组越界。 Go程序使用内置的error类型 (详见上文)为了表示如文件结束等事件。

可以使用内置的recover (恢复),重新获得控制权的恐慌的goroutine和恢复正常运行。呼叫recover停止展开,并返回传入的参数panic。因为只有运行的未展开代码,内部含有延迟函数,recover只在内递延的函数有效。如果的goroutine是没有恐慌,recover返回nil。

##Go的线程机制和管道 ###Goroutines(Go的线程机制)

Go允许用go开启一个新的执行线程–goroutine。它运行在不同的,新创建的的goroutine中。在一个程序中的所有goroutine共享相同的地址空间。

Goroutines是轻量级的,只占用比堆栈分配多一点的空间。堆栈开始小和成长的分配和释放堆(heap)的要求。内部goroutines像进行了复用多个操作系统线程的协程。您不必担心这些细节。

go list.Sort()  // Run list.Sort in parallel; don’t wait for it. Go处理文字的函数,可以作为结束,在处理go时很强大

func Publish(text string, delay time.Duration) {
    go func() {
        time.Sleep(delay)
        fmt.Println(text)
    }()  // Note the parentheses. We must call the function.
} 变量text和delay在周围函数和函数文字之间共享;只要它们都可以访问,它们就存在。

###Channels(管道)

管道通过指定的元素类型的值来提供两个goroutine同步执行和沟通的机制。 <- 操作符指定通道的方向,发送或接收。如无任何指示方向时,通道是双向的。

chan T          // can be used to send and receive values of type T
chan<- float64  // can only be used to send float64s
<-chan int      // can only be used to receive ints 管道是一个引用类型,用make分配。

ic := make(chan int)        // unbuffered channel of ints
wc := make(chan *Work, 10)  // buffered channel of pointers to Work

To receive a value on a channel, use it as a unary operator. 使用<- 作为一个二元操作符来在管道上发送值。当在管道上接收一个值时,把它作为一元运算符。

ic <- 3       // Send 3 on the channel.
work := <-wc  // Receive a pointer to Work from the channel. 如果管道是无缓冲,那么发送者阻塞,直到接收器接收到值。如果管道有一个缓冲区,发送者阻塞,直到该值已被复制到缓冲区。如果缓冲区已满,这意味着等待,直到一些接收器中检索到值。接收器被阻塞,直到有数据接收。

##并发 (示例) 最后我们用一个例子来说明如何散落的内容拼起来。这是一个服务器通过管道来接受的Work请求的例子。每个请求都在一个单独的goroutine运行。 Work 结构本身包含了一个管道,用于返回一个结果。

package server

import "log"

// New creates a new server that accepts Work requests
// through the req channel.
func New() (req chan<- *Work) {
    wc := make(chan *Work)
    go serve(wc)
    return wc
}

type Work struct {
    Op    func(int, int) int
    A, B  int
    Reply chan int  // Server sends result on this channel.
}

func serve(wc <-chan *Work) {
    for w := range wc {
        go safelyDo(w)
    }
}

func safelyDo(w *Work) {
    // Regain control of panicking goroutine to avoid
    // killing the other executing goroutines.
    defer func() {
        if err := recover(); err != nil {
            log.Println("work failed:", err)
        }
    }()
    do(w)
}

func do(w *Work) {
    w.Reply <- w.Op(w.A, w.B)
} [server.go](http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/server/server.go) 下面展示如何使用:

package server_test

import (
    server "."
    "fmt"
)

func main() {
    s := server.New()

    divideByZero := &server.Work{
        Op:    func(a, b int) int { return a / b },
        A:     100,
        B:     0,
        Reply: make(chan int),
    }
    s <- divideByZero

    add := &server.Work{
        Op:    func(a, b int) int { return a + b },
        A:     100,
        B:     200,
        Reply: make(chan int),
    }
    s <- add

    fmt.Println(<-add.Reply)
    // Output: 300
} [example_test.go](http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/server/example_test.go) 并发编程是一个大主题,JavaGo的方法是完全不同的。要想充分体验到并发编程的乐趣,看这篇[Share Memory by Communicating(《通过沟通共享内存》)](http://golang.org/doc/codewalk/sharemem/)

Stefan Nilsson

该文基于相似的文章 《面向C++的GO编程》

参考: http://www.nada.kth.se/~snilsson/goforjava_programmers


Flex 4.6 自定义Datagrid添加checkbox\图片等功能

2012-03-28 Flex

flex 4.6 中的 spark 的Datagrid相比于之前的 mx 有很大不同

实现自定义<s:itemRenderer>详见代码~

<s:DataGrid id="dg" left="14" right="10" top="35" bottom="9" dataProvider="{datagrid_data}">
<s:columns>
<s:ArrayList>
<s:GridColumn headerText="程序名称"
dataField="name">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:HGroup verticalAlign="middle">
<s:CheckBox id="cbx"/>
<s:BitmapImage width="24" height="24" source="{data.pic}"/>
<s:Label text="{data.name}"/>
</s:HGroup>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="date" headerText="更新时间"/>
<s:GridColumn dataField="version" headerText="版本号"/>
<s:GridColumn dataField="moduleUrl" headerText="moduleUrl"/>
<s:GridColumn />
</s:ArrayList>
</s:columns>
</s:DataGrid>

flex4 ColumnChart外包裹NavigatorContent进行TabNavigator分页出错,柱子移位

2012-03-28 Flex

之前单页面的ColumnChart显示图标正常。 后来用TabNavigator进行分2页,每个页面用NavigatorContent, 在NavigatorContent中 再添加ColumnChart 出现了柱子移位的现象。

在ColumnChart 外包裹一层BorderContainer ,问题解决。~

<mx:TabNavigator id="tabnavigator1" width="100%" height="100%" >
<s:NavigatorContent id="nc_Id_1" label="调峰报告"
icon="@Embed('assets/icon/list/48.png')" width="100%" height="100%">
<ElectroLoadShifting:Usefuldays width="100%" height="100%" id="usefuldays_id"/>
</s:NavigatorContent>

<s:NavigatorContent id="nc_Id_2" label="调峰执行"
icon="@Embed('assets/icon/list/48.png')" width="100%" height="100%" >

<s:HGroup width="100%" height="100%" paddingLeft="1" paddingRight="10"
verticalAlign="middle" includeIn="loadingState">
<s:BorderContainer width="100%" height="100%" borderVisible="false" >
<s:HGroup width="100%" height="100%" >
<s:Label id="unit_id" width="18" height="100%"
text="{'用电量︵'+_model.loadingShitServerModel.unit+'︶'}"
verticalAlign="middle"/>
<s:VGroup width="100%" height="100%">
<s:Label text="近30天用电量"/>
<mx:ColumnChart id="column" height="100%" color="0x323232" width="100%"
showDataTips="true" dataProvider="{_model.loadingShitServerModel.datas}"
dataTipRenderer="common.skin.ColumnChart_DatatipSkin" creationComplete="init()"
>
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="time"/>
</mx:horizontalAxis>

<mx:series>
<mx:ColumnSeries xField="time" yField="data" displayName="日用电量" id="columSeries_id" />
</mx:series>
</mx:ColumnChart>
</s:VGroup>

</s:HGroup>
</s:BorderContainer>

</s:HGroup>

<s:HGroup width="100%" height="100%" includeIn="coarseTurningState">
<ElectroLoadShifting:CoarseTurning id="coarseTurning_id" width="100%" height="100%"/>
</s:HGroup>
<s:HGroup width="100%" height="100%" includeIn="fineTurningState">
<ElectroLoadShifting:FineTurning id="fineTurning_id" width="100%" height="100%"/>
</s:HGroup>
<s:HGroup width="100%" height="100%" includeIn="powerSchemeState">
<ElectroLoadShifting:PowerScheme id="powerScheme_id" width="100%" height="100%"/>
</s:HGroup>

</s:NavigatorContent>

</mx:TabNavigator>

Way Lau

Software Engineer and Full Stack Developer, now work and live in Shenzhen, China. Detail

Donate

See the list of Donors.