Perfil de C.LittleC.LittleBlogListas Herramientas Ayuda

C.Little

生命和太阳一样不能被照亮,只能自明!
20 octubre

笑一笑十年少^_^(转自我一个哥们's mm的Qzone)

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

0、某领导耐心地对一犯错误的员工道∶『我跟你说,犯错误不可怕,怕的是你犯了错误以後就不再犯了!』
1、老师对一上课说话的学生吼道∶『××同学,你给我把嘴站起来!』
2、某犯了错误的员工小心翼翼地对领导解释道∶『头儿!我知道是我的错儿,可我真是故意的呀!』
3、小胖儿见炉子上的水开了,忙喊道∶『妈妈!快来呀,水著火啦!』
4、某姑娘对她的男友撒娇道∶『我饿了,咱们快去找洗手间吧!』
5、某君读诗∶『清晨,我打开窗子,只见那绿色的叶片上,挂满了晶莹的路灯┅┅』
6、丈夫对妻子气愤地喊道∶『告诉你,你已经把我逼得忍无可走了!』
7、某君急匆匆赶到车站售票口脱口说道∶『请给我来两张下午去广州的火车头!』
8、一个人骂另外一个人∶『我真想狠狠地往你脸上吐一泡狗屎!』
9、想起当年俺们宿舍一哥们抢别人的包子吃,边吃边说∶就这玩意儿,只配塞屁股。
10、想起小时候,小学老师骂一个学生∶『我一巴掌就把你踢出去了!』我们想笑不敢笑。
11、俺们几个中学同学有一次骑车出去,一个同学去踹另一个较胖同学的脚同时还想骂他两句,说道∶我伸出一只猪蹄,飞起一脚.....
12、我们宿舍一女孩拨弄著另一mm刘海∶瞧这乱的,狗爪子刨过似的。
13、宿舍某人喝别人的开水,烫得跳起来了,嘴里还叫∶****,这麽烫,猪都受不了啊┅┅
14、 有一次我和MM谈动情流泪被她发现了,她诧异的指著我的眼睛说∶怎麽了?我一脸无辜的答到∶眼睛掉进沙子里了。
15、高三时有一次和一个女同学(巨可爱)去书店买参考书,一边挑,一边聊,旁边的售货员得知我们是四中的学生後,对我们刮目相看、大加赞赏——心里那一个美!~~後来越聊越起劲,说起我们学校一个姓杨的团委老师,我脱口而出∶『那个杨委———』┅┅┅┅(声巨大)旁边售货员脸色都变了,我当时恨不得把手里拿的《黄冈》吃下去。再看我女同学脸都憋红了。
16、我在预科给学生上课,有一次我跟他们说关於考试的事情,让他们有选择的作题,因为时间不够用,结果不知怎的就把时间说成钱了。海一连说了好几遍,因为你们没有足够的钱,然後就听见下面哄堂大笑,那个糗阿。
17、还有一次,上学的时候,忘了让我们同学填什麽表格,我一时情急,又想说『表』,又想说『单子』,结果说成,『来,你添一下这个表子』,结果自己都寒得要命
18、我小学参加学习雷锋演讲比赛,由於紧张竟说『我要把无限的生命投入到有限的为人民服务之中去。』结果我屁奖都没拿到。

 
Soitif
19 octubre

King Of Yesterday

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
Album:King Of Yesterday
Title:King Of Yesterday (Radio Remix)
Can you still remember
How it seemed that we could live forever in a lovers dream?
And falling was the best part but now you know the things you cling to
Your heart can start to grow.
You, you're walking away.
I've been there now I know what to say... I'm the king of yesterday.
A silly little love song for myself.
It's all I ever do you know I shine the shell.
A pretty little picture, the face of you.
You were my setting sun and now you're every view.
You, you're walking away
I've been there now I know what to say...
I'm the king of yesterday.
Why don't, why don't, why don't you stay?
Why don't you stay? Why don't you stay? Why don't you stay?
Take a little time, throw it on the line.
Let me believe that you believe in me.
Baby turn around, look at what I found.
You are the one that I want.
Take a little time, throw it on the line.
Let me believe that you believe in me.
Baby turn around, look at what I found.
You were the one that I wanted.
And someday I'll be over on my own.
Believing all the legends of the loves I've known
And seeing you in summer the way we were when you were seventeen
You know I much preferred you walking away.
I've been here, now I know what to say
I'm the King of Yesterday.
Why don't, why don't, why don't you stay?
Why don't you stay? Why don't you stay with me? Stay.
Take a little time, throw it on the line.
Let me believe that you believe in me.
Baby turn around, look at what I found.
You are the one that I want.
Take a little time, throw it on the line.
Let me believe that you believe in me.
Baby turn around, look at what I found.
You were the one that I wanted.
You were the one that I wanted.
King of yesterday.
King of yesterday.

 
Soitif
15 octubre

That's my goal

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
    
英国单曲排行榜的新冠军歌曲
That's my goal 《那就是我的目标》演唱者是一位刚崭露头角的年轻人谢纳·沃德。谢纳·沃德的迅速窜红要归功于英国ITV电视台的一挡热播的娱乐节目《未知因素》(《THE X FACTOR》),这是一档歌唱比赛的真人秀,去年推出了第一届,斯蒂夫获得冠军后一炮走红,紧接着推出的个人专辑也大受欢迎。而今年,经过一轮轮的淘汰厮杀,来自英国曼彻斯特的谢纳·沃德与41岁的工人安迪·亚伯拉罕进入到最后的对决,两人分别演唱了为本届《未知因素》节目量身定做的最新单曲That's my goal 《那就是我的目标》,最终,21岁的shayne_ward谢纳夺冠,并获得了一份100万英镑的唱片合约。决赛当天观众的投票数量达到1080万,ITV电视台趁热打铁,第一时间推出了谢纳的最新单曲CDThat's my goal 《那就是我的目标》,仅仅上架4天就登上了单曲冠军宝座,销量在短短几天内达到了74万多张。“如果不是《The X Factor》,我想我会在服装店卖衣服打工度过我的圣诞新年。”2005年12月刚刚落下帷幕的英国ITV电视台歌唱比赛真人秀《The X Factor》本届冠军Shayne Ward近日在接受采访时说道。但事实是,因为有了《The X Factor》,Shayne的圣诞新年没有在打工卖衣服,取而代之的是在“卖”他的个人单曲CD——《That's My Goal》,而且是“大卖特卖”中。
You know where I've come from,
You know my story,
You know why I'm standing here...
Tonight,
Please don't go,
Don't be in a hurry,
I'm here to make it clear,
Make it right,
Well I know I've acted foolish,
But I promise you no more,
I've finally found that something
Worth reaching for,
I'm not here to say I'm sorry,
I'm not here to lie to you,
I'm here to say I'm ready,
That I've finally thought it through,
I'm not here to let you're love go,
I'm not giving up oh no,
I'm here to win your heart and soul,
That's my goal.
Please don't go,
You know that I need you,
And can't breath without you,
Live without you,
Be without you,
Well I know I've acted foolish,
But i promise you no more,
I'm not here to say I'm sorry,
I'm not here to lie to you,
I'm here to say I'm ready,
That I've finally thought it through,
I'm not here to let you're love go,
I'm not giving up oh no,
I'm here to win your heart and soul,
That's my goal.
Well i won't stop believing,
That we will be leaving together,
So when I say i love you,
I mean it forever and ever,
ever and ever....
I'm not here to say I'm sorry,
I'm not here to say I'm sorry,
I'm not here to lie to you,
I'm here to say I'm ready,
That I've finally thought it through,
I'm not here to let you're love go,
I'm not giving up oh no,
I'm here to win your heart and soul,
Yes I'm here to win your heart and soul,
Thats my goal....

 
Soitif

国际烟花大会,一个视觉大餐

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
     璀璨的烟花把杭州钱塘江上空照得一片辉煌。昨晚,10万发烟花在钱塘江上空绽放。

     这些照片都不是偶拍得,哈哈,相机没有那么好,水平没有那么好,而且站的位置也没有那么好。刚开始看的挺好的,可惜站的位置好象有点是下风向,后来烟雾越来越厚,慢慢的都看不出烟花了,有点可惜了。
     据说本次烟花大会施放烟花数目创出杭州举办烟花大会以来的又一个历史之最。其中,高空烟花2万发,与去年相比不仅数量增长,更有了质的飞跃。紧扣“人间天堂”、“五水共导”、“休闲之都”、“和谐杭州”四大主题,借助于电脑特技,构图奇特的交叉对射、层层递进的段射、节奏强劲的速射、波澜壮阔的齐射……各型烟花在近50分钟内尽情绽放,天空一次次点燃,江面一次次沸腾。而多角度交叉燃放,更是在宽阔的江面上空构筑起长达4000米,宽度500米,总面积200万平方米的烟花胜景,“此景只应天上有,人间哪得几回闻”,在从天而降的缤纷花雨中,现场观众如痴如醉。时近尾声,巨大的礼花在数百米高空尽情绽放,流光溢彩的夜空舒展着壮丽画卷……
     回来就比较悲惨,堵车堵了近3个小时,嗨,享受总是要付出代价的。。。
 

 
Soitif
 
27 agosto

PHP地开源CMS系统

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
PHP地开源CMS系统
开源的CMS
开源的CMS基本上是php的天下,选择时主要看
授权模式,不过很多人不关心这个
插件和模版的数量,开发社区是否活跃。有更多的人参与你才能源源不断地获得资源
中文的支持
系统需求,支持那些数据库,这会影响对空间的选择
扩展性,不过不是所有的人都有能力和兴趣自己做扩展
Mambo是一个老牌的opensource建站程序,获得过“最佳开源方案”,“年度最佳自由软件项目”等很多奖, 国外比较热门,但是在中国不够
热,中文支持比较弱,中文资源相对来说不够多。
Joomla 逐浪
http://www.joomla.org/
中文站点:
http://www.mambo.cn/
http://www.joomla.org.cn/
Mambo的分支,Mambo核心开发团队另起炉灶的产品。,2005年度最佳Linux开放源码系统奖
(八卦来自bbs.joomla.org.cn)
曼波开源核心开发团队致社区的公开信
致社区的公开信
--曼波开源核心开发团队
越来越多的人关注曼波开源项目,曼波商会 ( Mambo Foundation Inc *) 应运而生,它的初衷是为了更好的发展曼波。
我们,曼波核心开发团队,一致认为:
1、所谓开源项目,是致力于开发一个免费的和开放源码的软件的人们,组成一个团队而服务社会的行为。
2、开源项目体现协作精神,并享受协作过程带来的乐趣。它存储社区的信息反馈,提供好的管理,允许商业机构放心地投资于它的开发。
开源项目对任何人都敞开大门,欢迎那些能贡献价值和愿意在社区一起工作的人加入。
我们,曼波开发团队,认真关注曼波商会及其和社区的关系。我们坚信,曼波的未来,应该由使用者的需求以及开发者的能力所掌握。然而,
曼波商会却受Miro公司所控制,因此商会同社区之间的自由协作将变得不再现实。
1、曼波商会组建之初,并没有听取曼波核心开发团队们的意见。我们、社区成员,对曼波的管理和未来的发展方向,没有任何的发言权。由开
发团队组成的曼波筹委会和 Miro 公司的代表,联合组成曼波商会,并成立第一届理事会。但 Miro公司的CEO Peter Lamont完全将商会置于自
己的控制之下,在没有和开发团队的两名代表,Andrew Eddie和Brian Teeman商议的情况下,擅自任命了理事会成员。
2、尽管Lanmont先生向曼波筹委会许诺把Mambo的版权转移给商会,但Miro公司现在拒绝这么做。
我们将要做的是:在GNU规范下继续开发和改善这个获多项大奖的开源软件。我们希望Miro公司及曼波商会一路走好,很遗憾,我们不能够再和
他们继续合作。
我们听取了软件自由法律中心关于这次事件的建议,将很快就近期发展计划发布更多的信息。
2005年8月17日,曼波开发团队:
Andrew Eddie
Emir Sakic
Andy Miller
Rey Gigataras
Mitch Pirtle
Tim Broeker
Alex Kempkens
Arno Zijlstra
Jean-Marie Simonet
Levis Bisson
Andy Stewart
Peter Russell
Brad Baker
Brian Teeman
Michelle Bisson
Trijnie Wanders
Rey Gigataras
Shayne Bartlett
Nick Annies
Johan Janssens
The name Joomla! is a phonetic spelling for the Swahili word "Jumla", which means "all together" or "as a whole"
Swahili -- 斯瓦希里人,穆斯林民族中的主要一支,居住在东非从索马里到莫桑比克的沿海和岛屿上。斯瓦希里语作为坦桑尼亚官方语言的斯
瓦希里班图语,在东非或中东非被广泛地用作通用交际语言。
drupal
http://drupal.org/
Drupal模块功能一览
http://www.verydummy.com/drupal_demo/node/8
一些Drupal中文网站供参考
http://www.todaylog.com/node/44
PhpNuke
http://www.phpnuke.org/
中文站点:
http://www.postnuke.cn/
http://www.postnuke.ws/
老牌的CMS工具了,最早的php cms工具,用户很多,能找到很多phpnuke搭建的中文站点。最新的版本是7.9,功能很丰富,社区也很活跃。
postnuke
www.postnuke.com
中文站点:
http://www.postnuke.cn
phpnuke的分支,目标是在更少代码,更少的服务器负担,更多模版地情况下实现phpNuke的功能,Postnuke在显示上和php-nuke非常相似,但
是postnuke功能更多。
XOOPS
http://sourceforge.net/projects/xoops
http://www.xoops.org/
中文站点:
http://xoops.org.cn/
PostNuke的分支,最近很流行,插件很多,中文支持得也不错,模块组合的能力强大,wordpress,osCommerce, ipb等很多工具都可以整合成
为XOOPS的模块。
(www.xoops.org.cn/)
XOOPS - eXtensible Object Oriented Portal System, 面向对象的可扩展门户系统
XOOPS 框架稳定灵活,适应于web2.0 的各类功能的开发与集成,目前已经实现各类 RSS/ATOM 资源管理,集成 WordPress 等著名blog系统和
各类wiki管理系统,并实现与 Flickr, Delicious, Technorati 等社会资源的互动。
xaraya
http://www.xaraya.com/
中文站点:
http://zh.xaraya.com/
xaraya也是nuke系列发展起来的,基本摆脱了Nuke架构的束缚,架构上兼具 PostNuke/Drupal的优点,评价很高,模块开发潜力大,但是汉化
进展缓慢
更多的可以查看
www.opensourcecms.com
dotnetnuke用过一段时间,已经决定放弃继续使用了。

 
Soitif
08 agosto

msn spaces升级后头一帖

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
     很久没有来了,msn spaces升级成live spaces了,我的模版都变形了,害得我花了那么长时间,一个个代码的改。而且我那帅帅的flash media player显示不出来了,晕死,搞了半天不知道什么原因,看来哪天有空得去看看高手的设置了。不过好像那些歌还在,不知道那几首歌是否还是会自动循环。
     升级不知道出了什么新的功能,哪天观察观察!哪个哥们姐们知道了,告诉一声啊。只是功能,俺美工不行,界面都是抄的,哈哈,好功能还是可以学学的,呵呵

 
Soitif
16 julio

土豆哲学

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
     昨天跟一个朋友聊起技术人员,突然说到我们这些技术人员就是土豆,人土情商锈豆。我讲到了土豆也许只配爱上马铃薯,确实,土豆你永远只能是土豆,西瓜不会看上你的,不管你怎么付出,顶多只是看你新鲜瞅你几眼。因为你永远不是他们心目中的西瓜王子。像我们这样的人也许只能在命运的某个上帝安排时间,一不小心撞上另一个土豆,或者是在别人的介绍下认识另外一个土豆。不过我们这样的人也许也算是幸福的人,因为人的一生为了找寻爱的过程,每个人的人生都要找到四个人(前几天在一个Qzone上看到的),第一个是自己, 第二个是你最爱的人,第三个是最爱你的人,第四个是共度一生的人。我们怎么说也是找到了自己,并最终会和自己最爱的人共度一生,虽然也许我们并不是他们一生中最爱的。这样就是遇到一个想找共度一生的西瓜了。
     对于技术人来说,一切都是虚幻的,平时的生活最多的也是在虚幻中,任凭你怎么真心的付出西瓜是不会感动的。唯有认真地工作,打造自己的未来这才是真的,只有事业才会为你的付出所感动,感动的给你一份成功。
 
      一个还在努力中的土豆,等待另一个土豆or马铃薯,哈哈

 
Soitif
07 julio

如何解决ie浏览器收藏夹导入del.icio.us中文乱码问题!

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
     前几天遇到一个问题,把ie的收藏夹导出为bookmark.htm,然后再导入del.icio.us出现中文乱码的问题,后来发现这个是中文gb2312和utf-8之间的问题。后来想了个办法解决。先把DW的首选参数的新建文档的默认编码改成gb2312打开刚才从ie导出的bookmark.htm,此时看这些中文是不乱码的,把它复制下来,放在记事本或直接留在剪切板也可以,然后再把DW的首选参数的新建文档的默认编码改成utf-8,把刚才的那些文字复制进去,保存覆盖原来的bookmark.htm,然后再把它导入到del.icio.us,这样中文就不会乱麻了。
    哈哈,不知道对大家有没有用,要是已经知道了解决方法或者有更好的办法就当我没说,呵呵

 
Soitif
01 julio

不用就不要浪费,真是的。。。

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
     前一段时间一直在关注little.cc这个域名,对我来说这个域名蛮好的,做个人主页的域名,眼看着里面没有什么内容,到6月6号就到期了,那你不用就放出来吧,不知道那小子是谁,不用还给他续费,而且更气人的是whois.domaintools.com,前一段时间插出来他过期的时间一直是2006-06-06,害得我一直以为还有希望,最近在www.cc-china.cn上一查,人家早就续费了,郁闷!
Domain names can now be registered with many different competing registrars.
Go to http://registrar.verisign-grs.com/whois/ for detailed information.

Domain Name: LITTLE.CC
Registrar: TUCOWS INC.
Whois Server: whois.tucows.com
Referral URL: http://domainhelp.opensrs.net
Name Server: NS1.RENEWYOURNAME.NET
Name Server: NS2.RENEWYOURNAME.NET
Status: CLIENT-UPDATE-PROHIBITED
Status: CLIENT-XFER-PROHIBITED
Updated Date: 18-jun-2006
Creation Date: 06-jun-2004
Expiration Date: 06-jun-2007
 
纯属资源浪费啊!!

 
Soitif
21 mayo

用Eclipse RCP & ECF 实现 Google Talk客户端

▓ ▓返回主页▓ ▓ ▓ ▓给我写信▓ ▓ ▓ ▓编辑日志▓ ▓ ▓ ▓给我留言▓ ▓

  C.Little

 

 
大家用过Google Talk吗?它是Google推出的一个IM,通讯协议是我们熟悉的Jabber协议。我通过这篇文章给大家简单介绍一下如何利用ECF实现一个Google Talk客户端。源代码下载:http://www.blogjava.net/Files/reloadcn/Chat.rar

1.准备工作
先下载ECF:
www.eclipse.org/ecf


为了能够测试我们这个客户端是否能正常运行,我们还需要下载一个Goolge Talk客户端:www.google.com/talk

当然,我们想要登陆Google的服务器必须拥有一个GoogleMail帐号,由于现在GoogleMail帐号不是随便申请的,需要GoogleMail用户推荐才能申请,但也能通过一些网站进入GoogleMail申请页面,大家可以上网搜索一下,我在这里就不多说了。

googletalk.JPG


我们要建立一个Google Talk的客户端,需要了解一些ECF的知识。大家可以去Eclipse主站获得更多的信息。

2.建立一个RCP Mail  Example

我们先选择创建Plugin Project,取名为“Chat”,当到向导页的第二页的时候,注意在“Would you to create a rich client platform”选项选择“yes”,这样确保你创建的是一个RCP工程,见下图:

create rcp1.JPG



当到最后一页的时候,选择Mail Template:

create rcp2.JPG


完成向导后我们将会得到一个简单的RCP工程。

3.登陆的代码

1)连接前工作
ECF是一个基于Eclipse的通讯平台,它其中一部分实现了Jabber协议。ECF有一个ClientContainer概念,其实就相当于一个维护客户端的对象,它具有连接、断开连接服务的方法,并且能够添加一些通讯中的事件监听器。所以,我们创建Google Talk客户端首先就要拥有这么一个对象,而且它在整个程序生命周期中是唯一的。
让我们修改一下ChatPlugin中的代码:
首先,我们在这个类里增加一个私有变量clientContainer,并且给他加上Getter、Setter方法:

XMPPClientSOContainer clientContainer;
    
public
 XMPPClientSOContainer getClientContainer() {
        
return
 clientContainer;
    }

    
public void
 setClientContainer(XMPPClientSOContainer clientContainer) {
        
this.clientContainer =
 clientContainer;
    }

OK,试想一下,当我们在登陆Google服务器的时候才会去使用这个clientContainer去连接服务器,而且我们登陆的用户信息是需要保存下来的,以供后面的代码访问,所以这个clientContainer的生成方式应该是Lazy的,并且我们还需要建立一个我们登陆帐户的变量:

    private ID userID;

    
public
 ID getUserID() {
        
return
 userID;
    }

    
public void
 setUserID(ID userID) {
        
this.userID =
 userID;
    }

ECF中针对用户的信息是用ID来表示的,它是一个接口,ECF已经实现了一个XMPPID,正好是我们Jabber帐户需要的。

clientContainer有一个connect方法去登陆服务器,而且在连接后不再具有其他什么动作。读者会问:那什么时候通知我们连接成功呢?并且用户在服务器端的好友怎么获得呢?

clientContainer只负责连接,上述的那些事情都属于在连接服务器过程中或者连接后,服务器反馈给客户端的信息,这些信息需要我们给clientContainer设置监听器去捕获。

其中有一个监听器名为ISharedObjectContainerListener,这个监听器能够捕获一些在连接过程和断开连接过程中的事件,比如SharedObjectConnectedEvent (连接成功事件)、SharedObjectDisconnectedEvent (断开连接成功事件),如果我们需要在客户端连接上服务器后做点什么,那这个监听器是必须的。

clientContainer.addListener(
                  
new
 ISharedObjectContainerListener() {
                   
public void
 handleEvent(IContainerEvent evt) 
                       
if (evt instanceof
 ISharedObjectContainerConnectedEvent) {
                                 // 连接服务器成功后做点什么呢?
                        }
                       
if (evt instanceof
 ISharedObjectContainerDisconnectedEvent) {
                                 // 断开服务器成功后做点什么呢?
                        
}
                   }

                   }, 
null);

2)开始连接服务器

我们看看clientContainer有一个connect方法。

这个方法需要有两个参数:用户的ID、连接上下文

用户ID我们刚才已经说过了,它是ECF提出的一个概念,我们可以通过IDFactory生成它:

userID = IDFactory.getDefault().makeID(
                                        clientContainer.getConnectNamespace(),
                                        getUserName());

大家发现了吗,上面代码中的makeID方法需要两个参数,一个参数我们可以从clientContainer获得,它是连接名字空间,我的理解是某种协议。第二个是用户名,这个参数在我们这里是Google Talk的帐号,也就是GMail帐号,但是目前我们还没有办法从外部获得,这我会在下面的内容中提到,到时候就可以将这个程序串起来,大家现在可以把它看作已经具备某些值。

好,我们已经有了ID,现在看看什么如何创建上下文。连接上下文其实很简单,我们可以这样理解:就是在我们连接的时候,clientContainer会向客户端所取一些相关的信息,比如nikename,password,这样理解起来就不麻烦了,而且在我们的这个Google Talk客户端中,它也只会向我们索取password和username,来看看我们代码就更清楚了:

clientContainer.connect(userID, new IConnectContext() {

           
public
 CallbackHandler getCallbackHandler() {
 
              return new
 CallbackHandler() {    
                     
public void handle( Callback[] callbacks)throws
 IOException,
                                                        UnsupportedCallbackException {
                             
if (callbacks == null) return
;
                               
for (int i = 0; i < callbacks.length; i++
) {
                                     
if (callbacks[i] instanceof
 NameCallback) {
                                      NameCallback ncb 
=
 (NameCallback) callbacks[i];
                                      ncb.setName(getUserName());
                                      } 
else 

                              if
 (callbacks[i] instanceof ObjectCallback) {
                                 ObjectCallback ocb 
=
 (ObjectCallback) callbacks[i];
                                  ocb.setObject(password);
                                 }
                                                        }
                                                    }

                                                };
                                            }

                                        });

到目前为止,我们已经完成了连接这个环节,我们将这些代码都封装到ChatPlugin的login方法中,到时候通过外部的操作好调用。

4.开始登陆

我们利用SWT Dialog建立一个简单的登陆对话框:

LoginDialog.JPG


这个类需要有几个属性:用户帐号、用户密码、对话框返回值。

当我们点击了Login后,对话框关闭,并将文本中的值赋给帐号和密码这两个属性,返回值设为SWT.OK;如果是Cancel的话那我们就直接关闭对话框,返回值设置为SWT.CANCEL。

我们再到Mail RCP中提供的MessagePopupAction类中修改它的run方法:

 public void run() {
        
if(ChatPlugin.getDefault().getClientContainer() != null
) {
            MessageDialog.openInformation(window.getShell(),
"Info","已经登陆了,请先注销再重新登陆"
);
            
return
;
        }
        LoginDialog dialog 
= new
 LoginDialog(window.getShell(),SWT.NONE);
        dialog.open();
        
if(dialog.getDialogResult() ==
 SWT.OK){
            ChatPlugin.getDefault().setPassword(dialog.getPassword());
            ChatPlugin.getDefault().setUserName(dialog.getUser());
            ChatPlugin.getDefault().login();
        }
    }

代码逻辑很清楚。当我们点击这个按钮的时候,就会弹出登陆的对话框,然后我们输入信息后就可以正常登陆了。

注意后面的代码,我们将ChatPlugin中的用户名和密码先设置好后再调用登陆方法。如果登陆失败的话会在ChatPlugin的login方法中捕获到连接失败的异常。

5.获得我的好友们

怎么去获得我的好友呢?

刚才已经在前面提到了一点:clientContainer只负责去连接,而那些网络的事件需要我们去增加监听器捕获。获得好友也是一样的,我简单说一下。

clientContainer可以通过getAdapter去获得一个IPresenceContainer类型对象,这个对象可以增加监听获得好友信息的监听器,不仅如此,它还可以获得消息发送对象和消息的监听对象,这我会在后面介绍。
我们要想获得好友信息,就应该通过clientContainer获得IPresenceContainer对象,然后给它增加一个能够获得好友事件的监听器。

问题在这里,我们应该在什么时候去获得这个对象呢?那这个监听器接口是不是需要一些现有类去实现呢?

先说第一个问题:我们什么时候去获得这个对象,并为它增加监听器

一般情况下,我们在登陆成功以前的时候是不会去捕获我们的好友列表的消息的,而且也捕获不到,服务器在没有验证我们的客户端时,是不会发过来的,所以我们需要在登陆成功后去获得这个对象,并为它增加一个监听去。而这个对象也是需要作为一个私有变量存放起来,供其他类去访问。所以我们需要在第3节中提到了监听登陆成功的方法中写这段代码,由于篇幅问题,我不在这里给出代码片段,读者可以去看源代码。

看看第二个问题:谁需要实现这个监听器?

我们常见的IM中,都是有一个列表控件保存我们当前的用户信息的,所以我们在获得好友列表后就需要往某些Viewer中增加一些内容,来表示这是我们的好友列表。

我在这个客户端中,采用了一个View作为显示好友列表的控件,该View名为SimpleView,这个View具有一个TableViewer。该类的具体生成方法我不在多说,大家可以看看源代码,我只说一下这个View如何去实现监听获得好友信息的事件的。

我们让它实现IPresenceListener接口,并修改handleSetRosterEntry方法

public void handleSetRosterEntry(IRosterEntry entry) {
        
final IRosterEntry e1 =
 entry;
        Display.getDefault().asyncExec(
new
 Runnable() {
            
public void
 run() {
                
if(e1.getInterestType() ==
InterestType.BOTH){
                roseters.add(e1);
                
if(viewer.getInput() !=
 roseters) viewer.setInput(roseters);
                viewer.refresh();
                }
            }
        });
    }

这个方法就是截获获得好友信息的接口函数,entry表示的是从服务器获得的一些和客户端好友有关的信息,每当获得一个,判断一下这个好友是否都在双方的好友名单中,如果不是那就不要增加它;反之,我们就会把这个entry放到一个名位roseters的List对象中,然后刷新viewer。这里的viewer是刚才我们提到的TableViewer,做过SWT/JFace的读者一定知道,这个类需要我们去为它添加两个接口实现,一个是ContentProvider接口,一个是LabelProvier接口,这两个接口代码读者可以看看我的源码,这里就不写了。如果您对SWT/JFace不熟悉的话也没关系,这方面的资料很多。
看看我们登陆后获得好友列表是什么样的:

firend.JPG



6.监听消息

有了刚才增加好友的经验,我们现在就很容易解决这个问题。
同样,监听消息还是由IPresenceContainer对象增加的监听器来截获的。
而我让我们工程中一个名为View的类实现了这个监听器,并且实现这个接口的方法如下:

    public void handleMessage(ID fromID, ID toID, Type type, String subject, String messageBody) {
        
final ID id =
 fromID;
        
if(type ==
 Type.CHAT){
        
final String message =
 messageBody;
        Display.getDefault().asyncExec(
new
 Runnable(){
            
public void
 run(){
                
try
 {
                    
if(id.toURI().compareTo(chaterID.toURI()) ==0
){
                        
                        String s 
=
 chaterID.toURI().getUserInfo().toString();
                        s 
+= " say: " + message +"\n"
;
                        
                        showText.append(s);
                        View.
this
.getSite().getWorkbenchWindow()
                        .getWorkbench().getActiveWorkbenchWindow()
                        .getActivePage().activate(
                   (IViewPart)ChatPlugin.getDefault().getMessageDialogForID(chaterID));
                    }
                } 
catch
 (URISyntaxException e) {
                    
// TODO Auto-generated catch block

                    e.printStackTrace();
                }
            }
        });}
        
    }

可能读者这会看上面的代码会一头雾水。我解释一下:
变量chaterID是一个ID类型的,它其实是从刚才我们好友列表中,双击某一项时生成这个View对象的时候传进来的,让我们看看SimpleView 中的双击action的代码:

doubleClickAction = new Action() {
            
public void
 run() {
                ISelection selection 
=
 viewer.getSelection();
                IRosterEntry entry 
=
 (IRosterEntry) ((StructuredSelection) selection)
                        .getFirstElement();
                View chatView 
=
 (View) ChatPlugin.getDefault()
                        .getMessageDialogForID(entry.getUserID());
                
if (chatView != null
) {
                    SampleView.
this
.getSite().getWorkbenchWindow()
                            .getWorkbench().getActiveWorkbenchWindow()
                            .getActivePage().activate(chatView);
                }
            }
        };

可以看出来,当我们双击某个好友的时候,就会从entry中得到他的ID,然后生成一个View,并将ID给View,所以View的chaterID就时这么来的。

接着上面的解释:
showText变量其实是一个StyleText对象,他专门负责显示聊天信息,而下面那一长段代码读者大可不必理会,那是为了使一个好友对应一个View而做的一些工作,大概了解即可,也可以去看源代码获得更多的信息。

7.发送消息

让我们看看View类中的一段代码:

messageText.addKeyListener(new KeyListener(){

            
public void
 keyPressed(KeyEvent e) {
                
            }

            
public void
 keyReleased(KeyEvent e) {
                
if(e.character == '\r'
){
                    sendMessage(messageText.getText());
                    messageText.setText(
""
);
                }
            }
            
        });

不难看出这段代码的意思:当遇到输入字符为回车的时候,就调用sendMessage方法:

public void sendMessage(String message) {
        
if(this.getChaterID() == nullreturn
;
        String s 
= "你说:"
;
        s
+=
 message;
        
        ChatPlugin.getDefault().getPresenceContainer().getMessageSender()
                .sendMessage(ChatPlugin.getDefault().getUserID(),chaterID, 
nullnull
, message);
        
        showText.append(s 
+ "\n"
);
    }

sendMessage方法是从ChatPlugin中获得IPresenceContainer的messagesender去发送消息的,发送消息的函数第一个参数是发送者的ID,第二个是接收者的ID(chaterID已经在上面讲过了获取的来源),最后一个是发送的消息,中间两个参数一个消息类型和标题,他们可以为空。

8.结束语
通过我们上面所说的如何去登陆、获得好友列表、接收消息和发送消息,我们已经能够简单地创建一个Google Talk的客户端了,但是还有很多功能没有实现,比如添加好友、监听好友状态改变等等,这些都需要大家去增加。就讲到这里,我们下次再见。

talkrcp.JPG


 
Soitif
 

蓝色忧伤

Ocupación
Ubicación
努力不一定会成功,但是不努力一定不会成功!