Flex Event Flow

初识JSON

首先当然是介绍JSON是什么的缩写,JSON(JavaScript Object Notation)是js标准的一个子集,用来对交换的数据进行描述。说白了,就是可以用文本的形式对“对象”进行描述,也方便于网络传输和解析(不自觉的想到XML了)。

下面我们来看一个例子,这里就用JSON定义了一个对象

{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumbers": [
"212 555-1234",
"646 555-4567"
]
}

定义JSON对象的时候是用大括号包着的,由一对对key:value对组成。key是字符串,而value则可以是数组,对象,数字,字符串,布尔值,当然可以是null

在js中我们可以使用js自带的函数来解析json, var p = eval('(' + contact + ')');
现在p就是一个JS对象了。比如你可以通过p.firstName得到John

-------------------------------------------------------------------------------
我自己实践了一下,如果直接定义
var contact=
{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumbers": [
"212 555-1234",
"646 555-4567"
]
}

那么在JS中你是可以直接将contact看成对象的,就可以通过contact.firstName访问John
而使用eval的情况是当contact是字符串格式。

下面就是本人使用js写的,可以输入对应属性的名字,然后得到对应的值。如果其属性为对象那么就用点进行访问,比如address.city

属性名:

FLEX RSL

今天来公司想发布一些更新,Flex项目编译完成之后发现比原来的swf小了一大截,之前的swf文件1.2多,而现在的只有700多k,由于以前不是我发布的,所以我就没管直接换上了,发布完成后,发现自己的机器可以上,别人上的时候报RSL error的什么错误,仔细查看后终于发现了问题。
RSL(Runtime Shared Library)的简写,里面放的是Flex的一些基础共享库,在编译项目的时候可以在Flex Builder中设置是否将RSL打包到项目中,我检查了一下自己的设置,是FrameWork linkage, 所以不是打包在项目里,固然文件变小了。如果将RSL分离出来那么在输出的目录下将会多两个文件framework_3.1.0.2710.swz和framework_3.1.0.2710.swf(那一串数字是版本号),当你访问的时候过程是这样的,当你第一次访问应用的时候,flash player会优先将framework_3.1.0.2710.swz文件加载放到cache目录下,以后就不需再次加载了,如果这个动作失败了,就会加载framework_3.1.0.2710.swf,该文件只能下载到ie缓存..并不能达到RSL功能,只保证项目可正常运行.
出现RSL error的情况可能是一下两种情况
第一,使用低于9.0.115版本的Flash Player
第二,framework_3.1.0.2710.swz和framework_3.1.0.2710.swf未放到服务器的目录下。

我能访问的原因就是在我本地测试的时候已经将那swz放在了player的cache下了。

Flash中不同类型的坐标

在鼠标事件中经常碰到坐标这个概念,在Flash中有三种坐标的表示方式,大家也是经常容易混淆的。
下面是本人画的一个示意图:



第一种是本地坐标,本地坐标指定的像素位置随组件的左上角而变化。MouseEvent中可以由localX,localY获得

第二种是全局坐标,全局坐标指定的像素位置随舞台的左上角,即应用窗口的最外侧边缘而变化。,MouseEvent中可以由stageX,stageY获得

第三种是内容坐标,内容坐标指定的像素位置随组件内容的左上角而变化,并包括组件的所有内容区域,甚至包括当前剪切掉但必须能够通过滚动组件访问的任何区域。

DisplayObject中提供了本地坐标和全局坐标互相转换的方法,
Container中提供了内容坐标和本地坐标,全局坐标互相转换的方法。

Thinking In Seam

马越,Redhat 中国社区总架构师,作为Seam框架先行者马越,积极推动中国开源技术的发展。
今天他给我们讲解了Seam。
如今Java在企业应用领域里大行其道,于是诞生了太多太多的框架,Struts,Spring,Hibernate,GWT,JSF...当面对这么多框架的时候,我们如何选择,选择之后又如何将其在服务器中跑起来,这些都需要花费人力。
马越提及在欧美国家,JSF非常的流行,最近Seam的下载量更是非常的高,而中国则主要还是Struts,Spring,Hibernate居多。
首先JSF是SUN提出的JavaEE页面的规范, 有着大量的Widget组件,基于事件驱动。
提及EJB大家都可能感到退却,EJB3之前,EJB确实是非常的繁琐,写一个EJB需要大量的辅助类的配合,然而EJB3出来之后,使用Java5的Annotation特性使得EJB和POJO并无差异,只是增加一些Annotation而已。
然而JSF的生命周期和EJB的生命周期不同,这使得将两者结合起来非常的困难,然而Seam的出现改变了这一现象。Seam其实不能说它是一个框架,而是一个有状态的应用栈,通过它可以方便将其他的框架的整合在起来。
在Seam中一个核心的概念就是Context,在以前的Web应用中,我们可以设计到request/response Context ,Session Context,Application Context,然而这样的设计能够很好的满足如今复杂多变的企业应用吗,显然是不够的,比如我们在网页上做一个调查问卷,可能问卷的内容不止一页,这是我们就需要一种比Request Context长而比Session Context短的生命周期的Context,这样可以横跨几个request且不会放在Seesion中占用系统资源,所以Coversation Contest 应运而生。还有一个问题,一个业务流程启动后可能需要不止一个人员的参与,所以这时需要一个比Seesion Context更广的Context,于是Seam提出了Business process context.其实这些概念都是一些简单的概念。
其实Seam中是直接将Data Object暴露在页面上的。而我们现有的系统却都避免了这种情况。

如何在自己的Blogger上显示最新文章

首先介绍一个概念:GData,GDtata是Google Data API的简称,提供一套简单的协议来读写web上的数据,GData 使用两种基于xml的聚合格式,Atom和RSS,Google更倾向于前者。Atom有一个Atom Publishing Protocol(APP)协议,使得用户可以以HTTP请求的形式来操作网络中的资源,比如一个HTTP的GET方法可以获得特定的资源信息,PUT方法可以对某个资源进行更新。而且GData使用Atom标准的扩展机制来支持查询。GData使得可以让你将各处的信息集中到一起进行显示。

现在基本上一些Google的服务都支持GData。
废话少说,我们来看看Blogger上GData的使用,
首先如果你访问http://www.lostincode.cn/feeds/posts/default 这将是文章的XML标准输出,
但是如果写成http://www.lostincode.cn/feeds/posts/default?alt=json-in-script 则结果就会不一样,alt=json-in-script告诉google将结果以json的形式输出,这里如果你加上回调函数对json进行一定的处理就可以使用友好的html将内容解析出来,加回调函数只需要在后面加&callback=回调函数名字

下面就贴出本人的完整代码,效果就见右侧的最新文章,
大家注意 var link=post.link[4].href;这句代码,Link[]其实是一个文章单元中所有链接的数组,下标从0开始,第四个正好为文章的链接。
还有就是compareentry函数是用来比较时间用的。
----------------------------------------------------------------------
<div id="new">
加载中...
</div>

<script>
function compareentry(a,b){
order= Date.parse(a.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2})T([0-9:]*)([.0-9]*)(.)(.*)$/,
'$1/$2/$3 $4 GMT')) - Date.parse(b.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2})T([0-9:]*)([.0-9]*)(.)(.*)$/,
'$1/$2/$3 $4 GMT'));
return 0-order;

}
function handlePosts(json) {

var temp = '<ul id="Feed001_feedItemListDisplay">';
var postshow=10;
var sortentry=json.feed.entry.sort(compareentry);
for (var i=0, post; post = sortentry[i]; i++) {
if(i>=postshow) break;
var title=post.title.$t;
var link=post.link[4].href;
var authorname=post.author[0].name.$t;
var timestamp=post.published.$t.substr(0,10);
temp += '<li><span class="item-title"><a href="'+link+'">'+ title +'</a>('+timestamp+')'+'</span></li>';
}
temp+="</ul>";
document.getElementById("new").innerHTML = temp;
}
</script>

<script src="http://www.lostincode.cn/feeds/posts/default?alt=json-in-script&callback=handlePosts"
type="text/javascript"
></script>

JBoss Application Server Architecture

听了一天的关于Jboss的课,讲课的老师是程勇,貌似是中国开源界的某个XX人物,从JBoss的发展开始讲起,给我印象最深的是JBoss的微内核的架构,其微内核是基于JMX(Java Management Extensions),然后诸如JMS,EJB容器等一系列的服务将以Mbean的形式可以被集成到一起,这样整个系统并非常的便于管理,后来也讲了JBoss5的近况,JBoss5历时3年时间,重写其内核,完全采用POJO进行架构。还谈及一个概念就是Open Service Gateway initiative(OSGi),这个最成功的案例当然是Eclipse了。

Cairngorm简介

Cairngorm[ˈkɛənɡɔ:m]其解释为烟晶宝石,当然我这里不是为你介绍这种宝石,我这里所讲的是一种开源框架。
Cairngorm是由Adobe开发团队设计,适用于开发大型的RIA应用,这里的RIA指的是基于AS的应用。
其实这个框架是一个基于事件处理的MVC框架,可以将原先分散在各个MXML或AS文件中的事件进行集中管理,这样会使得代码很整洁,也便于代码的重用。

下面就简单讲一下基本的流程,
首先在需要派发事件的地方将事件进行分发,
然后由前台控制器捕获到事件,调用相应的命令进行执行,
命令中的execute方法进行相关的处理,处理的结果会在onResult中编写,若有异常信息则放在onFault中进行处理。

The First Quarter In Alibaba

学校里的欢声笑语似乎就在昨日的记忆中,那些校园的小路,在脑海中依然是那么清晰。但细数起来,已过一个季度,从那炎热的夏季,茂盛的梧桐,到现在凉爽的初秋,飘香的金桂,在这个无穷的宇宙中,在这个蓝色的星球上,一个季度也许只是那么一瞬间,但对于人,可能是一个生命的降临,一个生命的逝去,亦或是一个人生的转变。
至今在那本小本子上依然有着“阿里巴巴”的四个字,这个小本子记录着毕业前期找工作的一些历程,一路走来,坎坎坷坷,但总算得到一个理想的结果。
今年春天的时候,第一次来到杭州,依然记得那烂漫的桃花,平静的湖水,感觉杭州真的很美,也是第一次走进阿里巴巴,走进那充满激情的橙色。
短短的时间里,要熟悉这边的开发环境,开发流程,虽然有导师带着,但是大家都很忙,说实话当时心里不是很有底,但既然来了,就硬着头皮看代码,学着使用SVN,还记得做第一个小需求时的激动,还记得第一次发布时的紧张,但这些都过来了,对系统也了解得越来越多,我们几个志同道合的同事开始在一起吃饭,一起谈论着自己工作的事情,我们保持着应有的低调。
我在工作的时候,总是多问自己几个为什么,找到根本的东西,然后将其从我们的系统中抽象剥离出来形成独立的知识点,所以工作对我而言也是一个加强学习的过程,只是从以前的课本学习到实践中学习。渐渐的也认识到系统的弱点的地方,有时候甚至对那繁琐的流程感到厌烦,当然我深深的知道流程对于一个庞大的系统来说是多么重要,任何事物的存在都有其原因,也有其利弊,我们需要的是使其利大于弊,并达到最优,当然有好多问题是历史遗留问题,鉴于人力物力或当下的性价比来看没有做的价值,但是确实给后期维护开发带来很大的重复性劳动,就比如系统的技术性文档和业务文档,人的记忆毕竟是有限的,而系统是庞大的,如果没有一个完善的最新的文档来对系统的技术个业务进行描述,那么有一些细节之处便会成为盲区,成为bug孕育的土壤。
从心底讲,我觉得阿里巴巴很久之前没有把技术搞得很完善,往往许多项目都是赶着时间进行的,代码质量有所欠缺,当然近年开始大力发展技术,这对阿里巴巴来讲是很明智的。
不管怎么讲,阿里巴巴是个伟大的公司,人性化的公司,在这里让我感觉到了温暖和工作的激情。工作几个月以来感觉自己进步很多,又学会了一种新的语言,懂得了搜索引擎的原理,这些我都感到很有价值,当然自己还有一些地方不够好,比如有时候不够主动,做事总是担心别人忙,害怕麻烦别人。在今后的日子里我一定克服自己的不足,好好工作和学习,使自己在最短的时间里学到最多的知识,为以后成为一名优秀的架构师而努力。

Flex中Tree的dragDropHandler方法详解

首先通过isDefaultPrevented来判断事件是否调用过preventDefault来取消默认的事件,当然不是所有事件都可以取消,
hideDropFeedback(event);在拖拽的过程中有一个小黑线来指示当前放置的位置,调用这个函数,当drop后将黑线隐藏掉,
接下来重要的就是数据的处理了,如何获得数据了,event.dragSource.hasFormat("treeItems")是用来判断dragSource中时候有名字为treeItems的数据,取数据的话就是用dataForFormat,其类型是一个Array类型的。
如果是内部拖动的话,就要判断一下,以防止将自己拖进自己的子节点中。
判断的方法是取得目标的所有父节点,然后与被拖拽的节点进行比较,若拖动的节点为目标位置的父节点的话就直接返回

Web编程第一步之实例

接下来结合一个具体的例子讲解一下Web编程的过程。
例子是这样的,有一个网页上面有个输入框可以由用户输入自己的名字XXX,提交后返回一个“Hello,XXX”的页面。
使用工具:Netbeans
1.首先得保证你安装了JDK,netbeans可以从这个网址下载http://zh-cn.netbeans.org/,下载页面有很多不同的版本可供下载:

2.安装好Netbeans后,开心新建一个项目。

然后输入项目的名称,我这里是“Hello”,点下一步后,选择一个服务器,这里选择Netbeans自带的Tomcat6

由于本例子只是使用了Servlet还未使用任何其他的框架,故框架那里无需勾选。
3.下面开始写点代码了,
首先右击项目新建一个Servlet,修改Servlet的类名后,点下一步,输入Servlet名称和URL映射名,这里的信息其实最终会在web.xml里生成,这部分内容下次在详细讲解。
建好了之后,我们在index.jsp中增加一些内容,

这里form的action对应刚刚那个Servlet的URL映射名,表面这个form提交之后由相应的这个Servlet进行处理。
这时我们在回到那个Servlet里在processRequest这个函数里增加一些代码,用来获取form提交过来的name和打印相应的信息返回给客户端。
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String name = request.getParameter("name").toString();
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet NewServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello ," + name + "</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}


写好之后我们就可以运行我们的程序了。

右击项目点运行,就会自动跳出浏览器。

输入名字点击确认,


在下一讲里将介绍其中的原理。

Web编程第一步之引子

每个从事Web编程的人总是有那么一次痛苦的经历,对于Web编程的理解和参悟。
人的一生中总是有这样或那样的门槛,当你跨过了,在回首看的时候,你会觉得原来就是那么一回事,未知的世界总是充满恐惧和新奇,关键在于你的选择。
而Web编程中你所使用的技术也是蛮多的,首先你得熟练一种Web编程的语言,比如Java,PHP,Python,还有就是了解javaScrit,CSS,

在这里我将为大家揭开Web编程的神秘面纱,让大家看看,其实Web编程也就是那么一回事。

其实我们大家经常所说的Web编程就是指编写动态的网页,在过去的一些时代人们使用各种脚本语言进行编写,后来逐渐使用ASP,PHP,Java等语言进行编写。

我先说一下静态网页,静态网页就是网页上的内容是固定不变的,每个网页有固定的网址,每一次请求得到的结果都是一样的。
而动态网页呢,则可以接受客户端传递的参数显示不同的内容。

下面简单的讲一下客户端和服务器端
1.浏览器
我们使用浏览器浏览网页其底层在网络上传输的当然还是IP包,应用层协议是HTTP协议,这些都有浏览器封装好了,所以我们不必担心socket编程的细节,只需要输入网址然后又DNS服务器解析出ip地址,然后发送请求和接受响应,一切就这么简单。
2.服务器
服务器的作用就是根据你的请求,返回相应的响应,比如一个请求一个动态页面的时候,服务器会根据请求的参数或提交的表单,然后根据一定的“模板”,动态的“拼出”一个临时的网页返回给客户端。

计划

我接下来会学习memcached的源码,以及Google相关的技术,当然语言涉及c,python,但是工作中使用的还是Java和Ationscript 3,所以这些内容也会涉及,还有就是校园招聘临近,还会写一些在招聘中的注意点特别是与技术相关的。

翻译 ActionScript 3: Dynamic Classes

原文地址

在java里,如果你从一个特定的类创建了一个对象,那么你只能使用这个类定义了的属性和方法,举例:
class Person {
public String name;
}
你只能对其name属性进行操作:
Person p = new Person();
p.name = “Joe”;
System.out.println(p.name);

ActionScript称这种类为封闭的,和这种类相对的另外一种类叫做:动态类,允许以编程的方式在运行时给类增加新的属性和行为只需要动态的将神奇的关键字加到类的定义里。
dynamic class Person {
var name:String;
}
现在我们往类型为Person的对象里动态的增加属性age和函数printMe:
Person p= new Person();
p.name=”Joe”;
p.age=25;
p.printMe = function () {
trace (p.name, p.age);
}
p.printMe(); // Joe 25
但是你也不是完全的自由,你只能动态的增加公共的属性和方法,当然,天下没有免费的午餐,静态类在内存的使用上显得更高效一点,这是因为它不需要建立Hash表来存储在在编译时未知的属性和函数。

Blogspot SEO(Search Engine Optimization)

1.Google的Googlebot在抓取页面的时候,页面标题Title是一个非常重要的参数,Title在搜索结果中是为结果条目的标题,但是在blogspot中默认的文章标题与网站标题位置是颠倒的,每一篇文章页面的title都是以博客的标题为前缀的,这样对搜索引擎来讲不是很友好,你的文章的关键字就得不到突出,也会影响到你的搜索排名情况,那怎么解决呢?
在后台修改模板的HTML代码,将
<title><data:blog.pageTitle/></title>

修改为:
<b:if cond='data:blog.pageType == "index"'>
<title><data:blog.title/></title>
<b:else/>
<title><data:blog.pageName/> - <data:blog.title/></title>
</b:if>


2.还有就是blogspot的网页地址生成规则的把握,Blogger发表中文文章标题的时候永久链接的格式为:yourname.blogspot.com/年/月/blog-post_文章ID.hmtl,如果我们需要将关键字出现在文章永久链接里面的话,比如我想发布一篇《你好美女》的文章,可以在发布文章的时候先用英文标题:hello beauty,等文章发表成功之后再将英文标题修改为中文标题:你好美女,这样,最后文章的标题就是:yourname.blogspot.com/2008/09/hello-beauty.html。

Google 网站管理员中心 简介

Google 网站管理员中心 是提供给网站管理员使用的,它可以帮助您回答有关抓取和编制索引的问题,向您介绍改善和提高网站流量的产品和服务,从而增进与访问者之间的联系。
我就试着使用了一下,首先可以将自己的网站添加到网站列表中,这样你就可以查看你的网站在google索引中的情况了。
然后你就可以为你的网站添加sitemap和对你网站进行验证。
由于blogspot无法自己上传sitemap,所以一开始觉得没有办法,后来上网搜索了一下,可以使用blogger自带的atom.xml或rss.xml来当作sitemap文件,
地址是:你的网站地址/atom.xml
目前验证有两种方式,一是上传指定文件名的静态html文档,二是加入指定的meta,这里选取了第二种方式,

验证的目的是为了确认你是该网站的管理员,验证后你就可以查看你网站的一些信息了。
比如你网站是否被索引到,你所提交的sitemap是不是被索引了之类的。

Flex数组解惑

前几天对如下的数组初始化方式一直感到疑惑,不明其原理,今天终于豁然开朗。
private var students:Array = new Array({name:"luke",age:22},{name:"jane",age:18});
或者 var students:Array =[{name:"luke",age:22},{name:"jane",age:18}];

这里数组中的{name:"luke",age:22}和{name:"jane",age:18}其实都是一个Object对象,也就是这个数组中的每一个成员都是一个Object对象。

Associative arrays (关联数组)

关联数组有时候也称为"哈希"或"映射",由key和value组成。
关联数组是key和value的无序集合。

在ActionScript3中引入了名为"字典"的高级关联数组。
字典是 flash.utils 包中 Dictionary 类的实例,使用的键可以为任意数据类型,
但通常为 Object 类的实例。即字典的key不局限于 String 类型的值。

关联数组的key分类有以下2种。

1.key为字符串
在 as3中有两种创建关联数组的方法。

a.使用 Object 构造函数
Object 类的实例在功能上等同于关联数组。

如:
var luke:Object = {name:"Luke", age:22};
trace(luke["name"], luke["age"]);
// 输出:luke 22
//其实这些key和value的对在对象中是其属性和属性值

如在声明数组时不需要初始化,则以[] 或者 .的方式 添加值。
如:
var luke:Object = new Object();
luke["name"] = "Luke";
luke.age = "22";

b.用 Array 构造函数,如果将关联数组声明为 Array 类型,则将无法使用对象文本初始化该数组。

var luke:Array = new Array();
monitorInfo["type"] = "Flat Panel";
monitorInfo["resolution"] = "1600 x 1200";
trace(monitorInfo["type"], monitorInfo["resolution"]);
// 输出: Flat Panel 1600 x 1200

用 Array 构造函数创建关联数组没有什么优势。即使使用 Array 构造函数或 Array 数据类型,
也不能将 Array 类的 Array.length 属性或任何方法用于关联数组。
最好将 Array 构造函数用于创建索引数组。

即不赞成用array做字典以及哈希组织数据。

2.key为对象
用 Dictionary 类创建使用对象而非字符串作为键的关联数组。

如,考虑这样一个应用程序,它可根据 Sprite 对象与特定容器的关联确定 Sprite 对象的位置。
可以使用 Dictionary 对象,将每个 Sprite 对象映射到一个容器。

如下例子:

import flash.display.Sprite;
import flash.utils.Dictionary;

var groupMap:Dictionary = new Dictionary();

// 作为键名的对象
var spr1:Sprite = new Sprite();
var spr2:Sprite = new Sprite();
var spr3:Sprite = new Sprite();

// 用作值的对象
var groupA:Object = new Object();
var groupB:Object = new Object();

// 在字典中创建新的键-值对。
groupMap[spr1] = groupA;
groupMap[spr2] = groupB;
groupMap[spr3] = groupB;

if (groupMap[spr1] == groupA)
{
trace("spr1 is in groupA");
}
if (groupMap[spr2] == groupB)
{
trace("spr2 is in groupB");
}
if (groupMap[spr3] == groupB)
{
trace("spr3 is in groupB");
}

设计模式之Strategy

Strategy中文名叫做策略,计谋,一听就知道是为实现某一需求而所使用的方法,相对于编程中的对象也就是对象所表现出来的行为。
Strategy模式主要用来将算法实现从类中分离出 来,并封装在一个单独的类中。更简单的说,对象与其行为(behaviour)这本来紧密联系的两部分被解耦,分别放在了两个不同的类中。这使得对同一个 行为,可以方便的在任何时候切换不同的实现算法。而通过对策略的封装,为其提供统一的接口,也可以很容易的引入新的策略。

想起这种设计模式主要是因为最近在使用as3实现panel的几种常见布局,由于布局的算法和容器本身是分离的,使用了策略的设计模式。

为了方便我用GNU的java实现的Layout给大家介绍一下,具体代码可以使用
来进行搜索相关的类。
AWT的LayoutManager,是 Strategy模式的一个例子。对于GUI而言,每个组件(Component)在容器中(Container)的排放是需要遵循一定的算法的。通常的方法是使用绝对坐标,就像VB,Delphi之类的工具所作的那样,记录每个组件在容器中的位置。这当然会带来一些问题,比如在窗体缩放的时候,就需要手工编码改变组件的大小和位置,以使得原来的比例得以保存。而在AWT中,引入了布局管理器(LayoutManager)的概念,使得布局的方法大大丰富,编码过程也变得简单。
一个容器,比如Applet,Panel等,仅仅记录其包含的组件,而布局管理器中封装了对容器中组件进行布局的算法,具体地说,就是指明容器中组件的位置和尺寸的大小。通过布局管理器,你只需要确定想放置的组件间的相对位置即可,这一方面简化编码,另一方面也有助于实现软件的平台无关性。
每一个容器均有一个布局管理器,当容器需要布置它的组件时,它调用布局管理器的方法布置容器内的组件。LayoutManager2继承于LayoutManager,提供更为细致的布局功能,它可以让布局管理器为组件加上约束条件已确定组件如何被布置。例如,为了确定组件被摆放在边框内的位置,BorderLayout在它的组件上加上方向指示。
特别的,通过实现LayoutManager或者LayoutManager2接口,可以很容易实现自定义的布局策略。
回到模式的话题上来,如果有几个很相似的类,其区别仅仅是在个别行为上的动作不同,这时候就可以考虑使用Strategy模式。这样,通过策略组合,将原来的多个类精简为一个带有多个策略的类。这很符合OO设计的原则:找到变化的部分,并将其封装起来!Strategy模式同样的为子类继承提供了一个好的替代方案,当使用继承机制的时候,行为的改变是静态的,你指能够改变一次--而策略是动态的,可以在任何时候,切换任何次数。更为重要的是,策略对象可以在不同的环境中被不同的对象所共享。以布局管理器为例,虽然每一个容器只有一个布局管理器,但是一个布局管理器可以为多个容器工作。
Strategy模式也有一些缺点,比如,应用程序必须知道所有的策略对象,并从中选者其一。而且在策略对象被使用的时候,它和Context对象之间通常是紧耦合的,Context对象必须为策略对象提供与具体算法相关的数据或者其它的东西,而这些数据的传递可能并不能够风装载抽象地策略类中,因为并不是所有的算法都会需要这些数据的。另外,因为策略对象通常由应用程序所创建,Context对象并不能够控制Strategy的生命期,而在概念上,这个策略应该从属于Context对象,其生命期不应该超出 Context的范围对象。
通常的,Strategy很容易和Bridge模式相混淆。确实,他们有着很相近的结构,但是,他们却是为解决不同的问题而设计的。Strategy模式注重于算法的封装,而Bridge模式注重于分离抽象和实现,为一个抽象体系提供不同的实现。

Tomcat 远程调试

window:tomcat/bin/startup.bat
linux:tomcat/bin/startup.sh
文件中加入:
SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
其中8000为调试的端口号

Java自定义Annotation

Annotation注解(也称Meta Data元数据)为我们在代码中添加信息提供一个形式化的方法,是我们在后面的某个时刻方便的使用这些数据。
JavaSE5中自带了一些Annotation,可以分为两类,
标准注解,目前Java自带的有三个@Override,@Deprecated,@Suppress Warning
元注解
元注解是用来注解其他Annotation的,用的比较多的有两个
@Target 表示该注解可以用于什么地方。其取值的类型为java.lang.annotation.ElementType枚举类型
@Retention 表示需要在什么级别保存该注解,取值为RetentionPolicy枚举类型


整个Annotation的使用过程可以分成三块,Annotation的定义,Annotation的使用,和Annotation的处理器。
1.首先我们可以看一下如何定义一个Annotation
package com.luke.hello;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//用于域的声明
@Target(ElementType.FIELD)
//VM在运行期间也会保存annotation的信息,所以可以使用反射机制来读取之
@Retention(RetentionPolicy.RUNTIME)
public @interface Hello {
public String echo() default("Hello,I am a field!");
}


2.我们将这个刚刚定义的Annotation拿来使用
package com.luke.test;
import com.luke.hello.Hello;
public class Book {
@Hello(echo
="Hello,I am the name of the book!")
public String name;
}

3.写一个处理器类来对Annotatin进行处理,这里要使用到Java的反射机制了呢
package com.luke;

import java.lang.reflect.Field;
import com.luke.hello.Hello;
import com.luke.test.Book;

public class BookFileldTracker {
public static void trackBook(Class<?> cl){
for(Field f:cl.getDeclaredFields()){
Hello h
= f.getAnnotation(Hello.class);
if(h!=null)
{
System.out.println(h.echo());
}
}
}
public static void main(String[] args){
trackBook(Book.
class);
}
}

foucusOut事件

focusOut事件是指焦点离开某控件时触发的事件,这个比较简单,只是举个比较简单的例子:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initEvent()">
<mx:Script>
<![CDATA[
public function initEvent():void
{
panelWidth.addEventListener(FocusEvent.FOCUS_OUT,focusOut);
this.addEventListener(MouseEvent.CLICK,mouseClick);
}
public function focusOut(event:FocusEvent):void
{
panel.width = parseInt(panelWidth.text,10);
}
public function mouseClick(event:MouseEvent):void
{
panelWidth.focusManager.deactivate();
}
]]>

</mx:Script>
<mx:Panel id="panel">
</mx:Panel>
<mx:Label text="宽" />
<mx:TextInput id="panelWidth"/>
</mx:Application>


此例子中涉及了Application 表单的 creationComplete 事件,这个一般用来对事件的注册进行初始化。
还有就是deactivate可以使控件失去焦点。(focusManager还需学习)

Flex反射机制

这里用到一个类flash.utils.getDefinitionByName,其作用是返回由name参数指定的类的对象引用,然后我们就可以根据这个类的类引用实例化该类。
不过有个缺陷, 使用getDefinitionByName方法获得的类必须是在发布的时候被编译到swf文中的,否则就会报错:"ReferenceError: Error #1065: 变量 <类的名字> 未定义。"
且即使你import了某个类,是没有用的,需要定义一个这个类的引用才可以解决问题。

Flex之DataGrid

最近一直在使用ActionScript3进行编码,也学到了不少的新的知识,虽然觉得Flex3现在还不是很成熟,但我相信,Flex4出来后应该还是有不错的前景的。

在Flex中,控件既可以使用mxml的标记来描述,也可以写在ActionScript的代码里,但是归根结底,mxml最终还是被编译成as代码的,写成mxml只是为了编程的方便而已。

今天我就来谈一谈DataGrid这个控件吧。

DataGrid 控件提供以下功能:
1.列可以具有不同宽度或同一固定宽度
2.用户可以在运行时调整其尺寸的列
3.用户可以在运行时对其重新排序的列
4.可选择自定义列标题
5.对任意列使用自定义项目渲染器以显示除文本之外的数据的功能
6.支持通过单击列对数据进行排序

一个DataGrid控件既可以使用mxml标签的形式书写,也可以使用as3的代码写出来。

如下面所示,是使用mxml标签来进行描述的,其中medals是个XML类型的对象。
<mx:DataGrid id="dg" dataProvider="{medals.children()}">
<mx:columns>
<mx:DataGridColumn dataField="@name" headerText="国家"/>
<mx:DataGridColumn dataField="@gold" headerText="金牌"/>
<mx:DataGridColumn dataField="@silver" headerText="银牌"/>
<mx:DataGridColumn dataField="@copper" headerText="铜牌"/>
<mx:DataGridColumn dataField="@total" headerText="总计"/>
</mx:columns>
</mx:DataGrid>


如果使用as3的代码怎么写呢,首先得写在一个函数里。
public function genDataGrid():void
{
var dg:DataGrid = new DataGrid();
dg.dataProvider = medals.children();
var countryColumn:DataGridColumn = new DataGridColumn();
countryColumn.dataField = "@name";
countryColumn.headerText = "国家";
var goldColumn:DataGridColumn = new DataGridColumn();
goldColumn.dataField="@gold";
goldColumn.headerText = "金牌";
dg.columns = dg.columns.slice(0,0).concat(countryColumn).concat(goldColumn);
panel.addChild(dg);
}