﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-天堂的另一角-随笔分类-开源项目</title><link>http://www.cnitblog.com/addone/category/7483.html</link><description>天堂魷魚的原创技术博客。所謂兼容並包，無奇不有。</description><language>zh-cn</language><lastBuildDate>Sun, 26 Feb 2012 21:13:01 GMT</lastBuildDate><pubDate>Sun, 26 Feb 2012 21:13:01 GMT</pubDate><ttl>60</ttl><item><title>Enjoy: Mac下的JoyToKey</title><link>http://www.cnitblog.com/addone/archive/2012/02/26/77800.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Sun, 26 Feb 2012 13:56:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2012/02/26/77800.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/77800.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2012/02/26/77800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/77800.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/77800.html</trackback:ping><description><![CDATA[<p>不少人希望能用手柄来玩一些本身不支持手柄的游戏，在Windows下，他们有JoyToKey，可以用来把手柄的按钮映射为键盘按键事件，十分方便。</p><p>在Mac下，他们有<a href="http://www.carvware.com/gamepadcompanion.html" target="_blank">Gamepad Companion</a>。不仅支持键盘映射，还能把手柄映射到鼠标上，功能和界面都很不错。</p><p>问题是，那玩意儿是要钱的，而且相当地不便宜。所幸，我找到了这个：<a href="http://abstractable.net/enjoy/" target="_blank">Enjoy</a>。</p><p>界面很简单，不过操作也很简单。大体上，只要接上手柄，按下要设定的按钮，再按下对应的键盘按键，一个映射就建立起来了。</p><p>这个软件还支持把设置保存起来，这样玩游戏的时候只要切换成对应的设置就行了，还是相当方便的。我用来玩Mac下的&#8220;都市赛车6&#8221;，没有任何问题。</p><p>最大的好处是，Enjoy是免费的，还是开源的。唯一的问题是，界面目前只有英文。</p><p>由于1.0版在Lion下无法使用，我已经修正了该问题并反馈给作者，大家直接过去下载新版1.0.1就行了。因为是英文网页，我就不厚道地把<a href="http://abstractable.net/enjoy/enjoy.zip" target="_blank">下载链接</a>放上了，可以直接下载。为支持原作者，建议顺便过去看看，至少那边还有截图的说。</p><p>目前该软件处在冬眠状态，作为游戏爱好者的我对此深感痛心，尤其是在面对App Store上那个价格奇贵的GC时。我在考虑接手Enjoy的开发和汉化并且放到sf或者gg上，不过目前比较忙，还不敢动手。如果有希望参与这个项目的朋友，欢迎与我联系。直接给我发邮件或者留言都行。</p><p>当然，也许需要先给它起个更像样的名字。</p><img src ="http://www.cnitblog.com/addone/aggbug/77800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2012-02-26 21:56 <a href="http://www.cnitblog.com/addone/archive/2012/02/26/77800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的钟</title><link>http://www.cnitblog.com/addone/archive/2009/10/16/61971.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Fri, 16 Oct 2009 13:19:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2009/10/16/61971.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/61971.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2009/10/16/61971.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/61971.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/61971.html</trackback:ping><description><![CDATA[用PyQT4写的时钟，真的很简单。。。特性如下：<br>
<ol>
    <li>置顶显示，所有桌面显示；</li>
    <li>支持KClock皮肤，自带若干；</li>
    <li>鼠标滚轮调节透明度；</li>
    <li>背景图（未完成）。</li>
</ol>
效果看截图。<br><img alt="" src="http://www.cnitblog.com/images/cnitblog_com/addone/AClock0-2.png" width="235" height="224"><br><br>目前放出的只是一个早期测试版本，只实现了部分比较简单的功能。开发动机主要是Linux下常见的桌面时钟不能方便的置顶和调节透明度。下一版会争取实现Mac下的SimpleFloatingClock的类似功能，即完全使用单个png文件定制皮肤。<br>代码和可执行程序都放在压缩包中。Mint 7 下测试通过。<br><a target="_blank" href="http://www.cnitblog.com/Files/addone/AClock.zip">点此下载</a><br><br>使用方法：<br>运行run即可执行；<br>换肤在右键菜单里选skin，注意不要选以jpg结尾的，那个是bug（汗。。。）；<br>右键菜单退出；<br>在钟面上用鼠标滚轮可以调节透明度。<br><br> <img src ="http://www.cnitblog.com/addone/aggbug/61971.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2009-10-16 21:19 <a href="http://www.cnitblog.com/addone/archive/2009/10/16/61971.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BOINC项目Enigma介绍</title><link>http://www.cnitblog.com/addone/archive/2009/08/29/61070.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Sat, 29 Aug 2009 00:40:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2009/08/29/61070.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/61070.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2009/08/29/61070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/61070.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/61070.html</trackback:ping><description><![CDATA[近日在Mac下重新上了<a target="_blank" href="http://boinc.berkeley.edu/">BOINC</a>，不过目的不再是SETI，而是跟课程相关的一个相当有意思的项目：Enigma。<br><br>所谓的Enigma，指的是二战时期德军的一种加密解密技术，即恩尼格玛密码机。详细介绍请参考维基百科（如被封请自行学习穿墙技术）：<br><a target="_blank" href="http://en.wikipedia.org/wiki/Enigma_machine">http://en.wikipedia.org/wiki/Enigma_machine</a><br><a target="_blank" href="http://zh.wikipedia.org/wiki/%E6%81%A9%E5%B0%BC%E6%A0%BC%E7%8E%9B%E5%AF%86%E7%A0%81%E6%9C%BA">http://zh.wikipedia.org/wiki/恩尼格玛密码机</a><br><br><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/a/ae/Enigma.jpg"><br>（图片来源：<a target="_blank" href="http://en.wikipedia.org/wiki/File:Enigma.jpg">维基媒体</a>，看不到请翻墙）<br><br>这个密码机实在是加密解密史上的传奇之作，它由德国工程师Arthur Scherbius（亚瑟&#183;谢尔比乌斯）于1918年发明，并于1920年正式投入商业应用。它的强大之处在于，即使你知道它的结构和工作原理，而且能够截获到一些明文和密文，甚至能够得到一台样机（正如波兰早期的工作那样），你仍然无法破解已被加密的信息！其中构思之诡异精巧简直到达了匪夷所思的地步，这绝对是天才的作品！<br><br>然而，世界上没有打不开的锁，Enigma最终还是被破解了，而破解的过程也同样堪称解密史上的巅峰之作，其中涌现出许多闪闪发光的天才人物，包括后来计算机架构的奠基人Alan Turing（阿兰&#183;图灵），他是英国破解小组的核心成员。他研制出来的解密机Bombe（图灵炸弹），极大的提高了解密的效率，详细介绍请参考：<a target="_blank" href="http://en.wikipedia.org/wiki/Bombe">http://en.wikipedia.org/wiki/Bombe</a>。<br><br>Enigma被成功破解的事实，在后来被评价为：为盟军在西欧战场的胜利提前了整整两年。然而，事情到这里并没有结束。的确，到了今天，人们已经非常了解Enigma的加密解密原理，也已经可以很轻松通过软件或硬件方式来模拟它，但并不是所有的Enigma密文都已经被破解了。直到21世纪，仍然有3份截获于二战时期的德军电报无法破解。这三份电报均由Enigma M4（即4转子Enigma机）进行加密，于1942年在北大西洋被盟军截获，并由Ralph Erskine（拉尔夫&#183;厄尔斯金）提交给Cryptologia杂志社。于是，2006年，一小群人发起了一个名为&#8220;<a target="_blank" href="http://www.bytereef.org/m4_project.html">M4</a>&#8221;的项目，企图依靠分布式计算的威力，强行破解这三份&#8220;解密史上的耻辱&#8221;。中文版地址是：<a target="_blank" href="http://www.equn.com/m4/m4_project.html">http://www.equn.com/m4/m4_project.html</a>。<br><br>因为仅有密文，M4采取了暴力破解+爬山优化算法。一开始的进展还算顺利，2006年2月，也就是项目正式开始的一个月之后，第一份电报被破解。而不到一个月之后，第二份电报也告破。两份电报的内容均已被核实，M4项目组的成员在档案馆的德军潜艇U263及U264的日志中查到了相应的文本。第一份电报是一份发自U264的遇敌报告，而第二份则是发自U263的动向报告。破解结果可以在他们网站上查到：<br><a target="_blank" href="http://www.bytereef.org/m4-project-first-break.html">http://www.bytereef.org/m4-project-first-break.html</a><br><a target="_blank" href="http://www.bytereef.org/m4-project-second-break.html">http://www.bytereef.org/m4-project-second-break.html</a><br><br>看起来形势还不错。但事实证明，他们的估计太过于乐观了。2007年，M4加入BOINC项目，命名为Enigma@Home。而直到今天，总计算量已经耗费了超过2233年以上的CPU时间（相对于AMD速龙Athlon 1400处理器），来自大半个世纪前的第3份电报的内容仍然是一个谜。<br><br>这是一场传奇般的&#8220;没有硝烟的战争&#8221;。值得一提的是，其中出现的许多天才人物都在年纪轻轻的时候就已经崭露头角，如Enigma的设计者亚瑟，不到25岁就获得了德国汉诺威技术学院的工程学博士学位；为Enigma破解奠定基础的&#8220;波兰三杰&#8221;，在成功地大量破译Enigma信息时，年龄最大的也只有30岁左右；英国的Enigma破解专家图灵，于26岁获得英国普林斯顿大学博士学位，同年提出Enigma的解密机&#8220;炸弹&#8221;的构想。而当他初次提出现代计算机的架构——图灵机时，图灵只有24岁，还只是一名在校大学生。<br><br>提到这些，我真正想要说明的是，这些大学生们在那个时代起到的作用之巨大。然而今天，让我们回顾中国遍地的大学和大学生们、教授们、院士们，假如同样的时代来临，他们之中有多少人能够发挥像样的作用呢？战争不只是拼肉盾，发展不只是靠口号，人生也不只是狂赚钱。可惜，在整个社会都越发浮躁的今天，&#8220;科学技术是第一生产力&#8221;的言犹在耳，奈何国家的教育经费支出仍然没有达到GDP的2%（日本、以色列等国均在30%以上）。<br><br>废话说完了，谢谢阅读。想参加&#8220;M4&#8221;的，请打开你的BOINC，添加项目Enigma@Home：<br><a target="_blank" href="http://www.enigmaathome.net/">http://www.enigmaathome.net/</a><br><br><br> <img src ="http://www.cnitblog.com/addone/aggbug/61070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2009-08-29 08:40 <a href="http://www.cnitblog.com/addone/archive/2009/08/29/61070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPSM: 用Java做的PSP存檔管理器</title><link>http://www.cnitblog.com/addone/archive/2009/04/14/56361.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Tue, 14 Apr 2009 10:58:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2009/04/14/56361.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/56361.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2009/04/14/56361.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/56361.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/56361.html</trackback:ping><description><![CDATA[<span style="color: red; font-weight: bold;">當前版本：1.1</span><br style="color: red; font-weight: bold;"><span style="color: red; font-weight: bold;">發佈日期：2009-10-27</span><br><br>在Mac下的PSP工具並不多，也感覺不是太方便，於是打算用Java做一個跨平台的存檔管理軟件。目前功能包括查看存檔信息和PSP存檔備份等。當前版本暫時沒有中文版，僅供測試使用。包含中文的國際版和比較完整的功能將會在1.2版提供，屆時也會將源代碼按GPL協議發布。<br><br>平台要求是Java 1.5以上即可。目前在Mac OSX 10.5 Intel和Windows XP上測試通過。兼容3.71 M33及5.00 M33。<br><br><img src="http://lh3.ggpht.com/_70JovzHBzDc/SubzXdKzKQI/AAAAAAAAAE8/xdFpXFRYYCI/%5BUNSET%5D.png?imgmax=800" style="max-width: 500px;"><br><br>
<h3><span style="font-weight: bold;">下載地址</span></h3>
Version 1.1 (build 27 Oct, 2009)<br><a href="http://www.cnitblog.com/Files/addone/jpsm-1.1.zip" target="_blank">平台無關壓縮檔</a><br><a href="http://www.cnitblog.com/Files/addone/jpsm_1_1.dmg.zip" target="_blank">Mac OS X 專用壓縮檔(dmg.zip)</a><br><br>如果有任何問題，請按照頁面右邊的聯系方式聯絡我。<br><br>
<h3>鏈接</h3>
PSP的SFO文檔處理方法參考以下文檔（英文）：<br><a href="http://hitmen.c02.at/files/yapspd/psp_doc/" target="_blank">yet another PlayStationPortable Documentation</a><br><br>原始發布頁（我的新站，英文）：<br><a target="_blank" href="http://addlone.blogspot.com/2009/04/jpsm-java-psp-savedata-manager.html">http://addlone.blogspot.com/2009/04/jpsm-java-psp-savedata-manager.html</a><br><br><br>   <img src ="http://www.cnitblog.com/addone/aggbug/56361.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2009-04-14 18:58 <a href="http://www.cnitblog.com/addone/archive/2009/04/14/56361.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>获取歌曲封面的Amarok脚本 - AGetCover</title><link>http://www.cnitblog.com/addone/archive/2008/01/22/39200.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Tue, 22 Jan 2008 13:40:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2008/01/22/39200.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/39200.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2008/01/22/39200.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/39200.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/39200.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: AGetCover是Amarok的一个通用脚本，主要针对Amarok自身的封面功能的缺点开发。<br><br>&nbsp;&nbsp;<a href='http://www.cnitblog.com/addone/archive/2008/01/22/39200.html'>阅读全文</a><img src ="http://www.cnitblog.com/addone/aggbug/39200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2008-01-22 21:40 <a href="http://www.cnitblog.com/addone/archive/2008/01/22/39200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>要高效还是要易用？——谈GUI与CLI</title><link>http://www.cnitblog.com/addone/archive/2008/01/08/38581.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Mon, 07 Jan 2008 17:24:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2008/01/08/38581.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/38581.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2008/01/08/38581.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/38581.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/38581.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 自Linux渐渐风行起来，有关图形界面（GUI，Graphical User Interface）和命令行界面（CLI，Command Line Interface）之争就一直闹个不停。看了众多评论之后，总有些郁闷之意想要发泄一下，虽然觉得有混水摸鱼的嫌疑，却还是不吐不快。&nbsp;&nbsp;<a href='http://www.cnitblog.com/addone/archive/2008/01/08/38581.html'>阅读全文</a><img src ="http://www.cnitblog.com/addone/aggbug/38581.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2008-01-08 01:24 <a href="http://www.cnitblog.com/addone/archive/2008/01/08/38581.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一种新的软件设计开发方法——谈UCL技术</title><link>http://www.cnitblog.com/addone/archive/2006/11/09/19006.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Thu, 09 Nov 2006 06:53:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2006/11/09/19006.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/19006.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2006/11/09/19006.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/19006.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/19006.html</trackback:ping><description><![CDATA[最近一段时间来，我都在忙于做一件&#8220;异想天开&#8221;的事情——寻找传说中的&#8220;银弹&#8221;。呵呵，听起来确实有些搞笑，但是我想我的确发现了什么。<br><hr size="2" width="100%">
<h2>引言</h2>
自Brooks预言&#8220;没有银弹&#8221;的数十年来，软件设计开发的理论和技术都有了相当大的改进，但也正如Brooks所言：没有银弹。<br>现在，我们拥有面向对象编程、UML建模、CMMI过程改进等各种理论和技术，然而所有这些充其量只能算得上铜质子弹，答案依然：没有银弹。<br><br>
<h2>通用构件库（UCL）的基本构想</h2>
我所设计的是一个叫做&#8220;通用构件库（Universal Components Library）&#8221;的框架，设计灵感源自可视化构件库VCL、MVC三层架构以及Linux下一个基于Alsa的声音合成软件，而其理论基础则是分层数据流图。<br>这个框架贯穿整个软件的设计和开发过程，试图让设计和开发连成一气。虽然并非基于面向对象设计与编程，但也不排斥面向对象编程技术。除了大幅度提高代码重用性之外，这个框架也有助于提高软件的可维护性。在基于UCL的设计和开发过程中，还可以综合运用XP开发过程及CMMI过程以进一步改善整个过程。<br><br>UCL的目标和当初VB、Delphi的目标一样，让软件开发变得就像搭积木那么简单。使用类似VCL、MFC的东西的确可以提高开发效率，但无法从根本上实现这个目标。其原因可以归结为几点：<br>
<ol>
    <li>把&#8220;搭积木&#8221;理解为对整个系统进行可视化开发，而非对系统的各个模块进行分层搭建；</li>
    <li>扩充性不足，自定义组件没有能获得和自带组件同等的地位，以至于不得不重复发明各种轮子；</li>
    <li>独立于设计过程，无法将代码和设计进行对照。</li>
</ol>
UCL是一个抽象的库，只是一个框架而已，作用是把以VCL、MFC之类的具体组件组织起来，从而真正具备&#8220;搭建&#8221;的能力。由于本身就是个完全开放的框架，因此任何组件都是平等的，大家可以随心所欲地创建各种各样的专用UCL库。UCL框架使用UCL图作为设计和代码的中间媒介，数据流图可以直接转换为UCL图，代码可以由UCL图直接生成或&#8220;搭建&#8221;。<br>由于UCL组件和代码一一对应，因此UCL图是依赖于具体库的，例如使用VCL搭建的系统和使用MFC搭建的系统，即使其功能一致，UCL图也有可能不同。也就是说，想要应用UCL技术，就必须拥有要使用的具体库所对应的UCL库，例如UCL_VCL、UCL_MFC、UCL_Swing、UCL_QT等等，这也是为了实现真正的&#8220;搭建&#8221;所付出的代价。<br><br>UCL图是UCL设计思想的核心，其灵感来源于Linux下的一个声音合成软件。该软件提供了许多种类的声音处理模块，这些模块的外部接口都很简单，大都只有输入、输出接口而已。但是只需要将各种模块用音频流连接起来，理论上却可以合成出任意的声音。面向对象技术中的问题之一就是类的接口太多且没有标准，不便于掌握。如果可以每个组件只有几个接口，并且组件的分类比较科学，那么掌握起来就简单多了。<br>除了连接关系之外，为了适应自顶向下的分层设计的需要，UCL图还支持&#8220;组合&#8221;的关系。一个组件可以由一个或多个内部组件组合而成，嵌套层次不限。这样，一个复杂系统就可能最终分解为一系列仅具有一个输入接口和一个输出接口的简单组件。<br>UCL图除了能够充当设计和开发的中间媒介之外，还有另一个重要的作用。在分解为一系列UCL组件之后，整个系统的规模和工作量就可以快捷并准确地估计出来。<br><br>可见，UCL技术的优点在于：<br>
<ol>
    <li>使得软件的规模和工作量在前期设计就可以比较准确地估计；</li>
    <li>使得设计和开发过程一气呵成；</li>
    <li>提倡面向组件开发，在不增加代码复杂性的前提下，大大提高了可重用性；</li>
    <li>使得软件更易于维护。</li>
    <li>以下将分别讨论这些问题。</li>
</ol>
<br>
<h2>UCL解决的问题：前期设计</h2>
软件的前期设计，从来不是个简单的问题。我们在获得需求说明书之后，就需要将其转变为设计蓝图。过去的数据流、事务流、控制流分析方法更适用于模块内部的分析，而对于一个庞大的系统，则往往需要使用UML进行建模。<br>无论如何，建模过程总是繁杂的，而且最糟糕的是，和传统的工程设计不同，这种繁杂的软件设计往往跟最终的软件产品根本就是天壤之别。我们最后拥有的是一大堆跟最终代码几乎完全没关系的模型以及一大堆几乎丝毫看不出设计思想的代码。因此，对于一个稍微复杂的项目，我们对其规模和工作量都是难以准确估计的。<br>即使我们使用昂贵的工具来试图同步设计和产品代码，经常也只是徒劳而已，过高的设计成本和维护成本使得这种投资毫无意义。更多的公司选择了手工作坊式的开发方式，只是在开发过程中借助XP或CMMI来扳回一点面子。在项目完成后，再根据最终产品进行建模——当然，这已经不再是设计了，只能算是&#8220;文档化&#8221;罢了。<br><br>基于UCL的设计过程，并不是面向对象的设计过程，而是基于传统的分层数据流图，也就是说，整个设计过程是自顶向下的。本来，数据流图对于系统的架构描述并不清晰。但是，分层数据流图使得这样的架构描述至少可以达到&#8220;将就能用&#8221;的程度。更重要的是，由于最底层的数据流图和UCL图可以方便地对照，由UCL图作为设计和产品代码的中间媒介，从而将设计过程和开发过程连成一气。<br>实现UCL组件和数据流处理的一一对应，更重要的意义在于使得系统的规模和工作量将变得更直观、更准确，也更易于统计，而不像过去一样只能依靠项目负责人的经验判断。<br>而在购买或自行填充了UCL库之后，通过实现UCL组件和代码的一一对应，不仅可以实现建模和实现的互相参照，开发成本也可以大大降低。<br><br>以下是一个简单系统的功能需求说明、分层数据流图以及一个对应的UCL图，仅供参考：<br><br>
<h2>UCL解决的问题：重用</h2>
重用，是件说起来容易做起来难的事情。利用面向对象技术，设计一个可重用构件的工作量大约是&#8220;一次性&#8221;构件的2~3倍。<br>这里的问题是通用性和专用构件的矛盾。人们在得到一个专用构件之后，在将其重用的过程中往往需要针对特定需求进行修改。不断的重用导致不断的修改，并催生了使这个构件日趋通用化的需求，最终专用构件变成了通用构件。但构件的通用性带来了高昂的维护成本，最终人们对其失去了兴趣，又开始重新开发专用构件。如是循环。<br>高昂的重用成本带来了昂贵的可重用构件，也就导致更多的人决定自行开发各种形态各异的轮子，最终这些轮子又陷入了成本高昂的重用泥沼中。<br><br>UCL组件和传统的构件很不相同，其特点如下：<br>
<ol>
    <li>关系简单，只有简单的&#8220;连接&#8221;和&#8220;组合&#8221;两种关系；</li>
    <li>接口简单，只具备&#8220;输入&#8221;、&#8220;输出&#8221;等几个简单的接口；</li>
    <li>处理简单，通常只执行很简单的处理，保证了低廉的开发成本和良好的可维护性，同时保证了可重用性。</li>
</ol>
通过两种简单的关系，我们就可以将各种简单的UCL组件&#8220;搭建&#8221;成具备复杂功能的复合组件，最终搭建成整个系统。也就是说，尽管UCL的设计过程是自顶向下的，但开发过程却是自底向上的，这就在保持低成本的同时兼顾了通用性，从而得以解决传统面向对象开发方法中的通用和专用的矛盾。<br><br>在具体的开发过程中，我们在得到UCL图之后，首先是实现图中的各个组件。这些组件的代码和组件一一对应，存放在代码库中，日后再次使用该组件时无需再次编写，由于组件的规模很小，可重用性就比传统的构件要高得多。<br>在所有的底层组件都有代码实现之后，借助专用的CASE工具，输入UCL图并连接代码库，即可直接生成完整的系统。<br><br>当然，以上是一个理想化的过程。其主要的一些应用问题如下（当然还有别的）：<br>
<h4>如何输入UCL图？</h4>
我的目标是设计出一个类似那个声音合成软件的画图软件，这样就能以可视化的方式来拖拉各种组件并创建连接。但是作为一种简单的替代方案，我也设计出了一种脚本语言，用文本的方式来表达UCL图中所包含的所有元素。以下是一个脚本示例：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">cnitblog</span><span style="color: #000000;">.</span><span style="color: #000000;">addone</span><span style="color: #000000;">.</span><span style="color: #000000;">AID3Tagger</span><span style="color: #000000;">.</span><span style="color: #000000;">Mp3FileListEditor<br><br>AddFileButton</span><span style="color: #000000;">:</span><span style="color: #000000;">JButton</span><span style="color: #000000;">,</span><span style="color: #000000;">title</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">添加文件</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">proc</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">OpenFileDialog</span><span style="color: #000000;">.</span><span style="color: #000000;">show;<br>OpenFileDialog</span><span style="color: #000000;">:</span><span style="color: #000000;">JFilteredFileChooser</span><span style="color: #000000;">,</span><span style="color: #000000;">multiSelection</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">true</span><span style="color: #000000;">"</span><span style="color: #000000;">/</span><span style="color: #000000;">filterString</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">.mp3|MP3音乐文件</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">show</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Mp3FileList</span><span style="color: #000000;">.</span><span style="color: #000000;">add(fileList</span><span style="color: #000000;">:</span><span style="color: #008080;">File</span><span style="color: #000000;">[]);<br><br>AddDirButton</span><span style="color: #000000;">:</span><span style="color: #000000;">JButton</span><span style="color: #000000;">,</span><span style="color: #000000;">title</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">添加文件夹</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">proc</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">OpenDirDialog</span><span style="color: #000000;">.</span><span style="color: #000000;">show;<br>OpenDirDialog</span><span style="color: #000000;">:</span><span style="color: #000000;">JFileChooser</span><span style="color: #000000;">,</span><span style="color: #000000;">selectionMode</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">directories</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">show</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">GetFilesInDirRecursively</span><span style="color: #000000;">.</span><span style="color: #000000;">proc(</span><span style="color: #008080;">dir</span><span style="color: #000000;">:</span><span style="color: #008080;">File</span><span style="color: #000000;">);<br>GetFilesInDirRecursively</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&gt;,</span><span style="color: #000000;">filterString</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">.mp3</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">proc</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Mp3FileList</span><span style="color: #000000;">.</span><span style="color: #000000;">add(fileList</span><span style="color: #000000;">:</span><span style="color: #008080;">File</span><span style="color: #000000;">[]);<br><br>RemoveFileButton</span><span style="color: #000000;">:</span><span style="color: #000000;">JButton</span><span style="color: #000000;">,</span><span style="color: #000000;">title</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">移除文件</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">proc</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">FileListBox</span><span style="color: #000000;">.</span><span style="color: #000000;">remove;<br>SourceEncodingBox</span><span style="color: #000000;">:</span><span style="color: #000000;">JComboBox</span><span style="color: #000000;">,</span><span style="color: #000000;">editable</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">false</span><span style="color: #000000;">"</span><span style="color: #000000;">/</span><span style="color: #000000;">data</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">GBK|UTF-8|UTF-16-BE|UTF-16-LE</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br></span><span style="color: #000000;">proc</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">FileListBox</span><span style="color: #000000;">.</span><span style="color: #000000;">changeEncoding(encoding</span><span style="color: #000000;">:</span><span style="color: #0000ff;">String</span><span style="color: #000000;">);</span></div>
<br>
<h4>如何&#8220;真正地&#8221;实现UCL图到具体代码的转换？</h4>
这种转换的问题在于，对于UCL组件的属性应该如何转换？我目前的想法是，使用一个映射文件，将UCL组件和具体组件的属性映射关系保存在其中，例如：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">version</span><span style="color: #000000;">=</span><span style="color: #000000;">0.1</span><span style="color: #000000;"><br>type</span><span style="color: #000000;">=</span><span style="color: #000000;">java.swing<br><br>JButton.title</span><span style="color: #000000;">=</span><span style="color: #000000;">setText(String)<br>JFileChooser.multiSelection</span><span style="color: #000000;">=</span><span style="color: #000000;">setMultiSelectionEnabled(boolean)<br>JFileChooser.filterString</span><span style="color: #000000;">=</span><span style="color: #000000;">setFileFilter(Custom.FileFilter)<br>JFileChooser.selectionMode</span><span style="color: #000000;">=</span><span style="color: #000000;">setFileSelectionMode(Custom.FileSelectionMode)<br><br>_converter_.FileSelectionMode.source</span><span style="color: #000000;">=</span><span style="color: #000000;">String<br>_converter_.FileSelectionMode.target</span><span style="color: #000000;">=</span><span style="color: #000000;">int<br>_converter_.FileSelectionMode.rule</span><span style="color: #000000;">=</span><span style="color: #000000;">files|</span><span style="color: #000000;">0</span><span style="color: #000000;">|directories|</span><span style="color: #000000;">1</span><span style="color: #000000;">|files_and_directories|</span><span style="color: #000000;">2</span></div>
<br>另外一个可供考虑的方法是，开发UCL组件来专门对属性进行处理。这样即可在目前的UCL框架中实现，无需增加新的特性。<br><br>
<h4>如何使用UCL设计GUI界面？</h4>
不得不承认，这将是个很棘手的问题。对于java、.net来说，情况要好些，因为界面也是使用代码来构建的。但对于VB之类来说，由于界面是采用专用格式来保存，情况就麻烦得多了。而且，即使是java和.net，没有可视化的界面设计，也将是没有吸引力的解决方案。<br>我目前的想法有两个：一个是将具体的GUI组件包装为UCL组件，不过这样一来有可能会加大界面设计的工作量；一个是干脆完全将GUI部分从UCL中剔除出去，即这一部分使用传统的开发方法，但应该保证GUI组件和UCL组件能够彼此调用。<br><br>
<h2>UCL解决的问题：维护</h2>
在传统的软件开发项目中，维护成本所占的比例是很大的。这里主要指的是由需求变更、BUG修改等引起的软件修改和更新工作。对于小的修补工作来说，每次修改的成本并不高，但是在多次修改之后，原有的代码往往就变得面目全非了。这时，如果再面对一个较大的需求变更，往往我们情愿重新开发，而不愿意再继续维护这个系统。<br>造成这种问题的原因有很多，一方面是因为无法从代码中看出设计，不得不求助于文档，这对于一些缺乏文档的项目来说是致命的；另一方面是，在修改之后没有及时地同步文档和模型，这种情况在发生若干次之后，这个项目离寿终正寝也不远了。<br><br>如前所述，UCL图是设计和实现之间的一座桥梁，对于解决这类维护问题应该是很有效的。修改工作和开发时一样，都只需对图进行操作，所有的设计都可一目了然。这种方式，有利于提高维护效率和降低维护成本。<br><br>
<h2>总结和思考</h2>
由以上讨论可以看到，由于平滑连接了设计过程和实现过程，UCL技术具有许多独特的优点。作为一种全新的技术，UCL不仅仅是一个组件库的理论，更代表着全新的设计思想和开发方式。作为一个抽象的组件库，UCL更不是VCL、MFC等的替代品，而是这些具体库的包装者和使用者。<br>由这些理论可见，如果UCL技术能被证明可用于实际的商业开发中，目前的整个设计和开发方式都将发生巨大的改变。不过，由于理论是全新的，而且对开发语言具有依赖性，基于UCL的设计和开发过程更需要有一系列的CASE软件支持，这可能会带来一系列的问题，但更有可能形成一个巨大的商机。<br><br>不过很遗憾，尽管我已经在一些小软件中成功的应用了相关理论，但目前，各种应用问题还远没有得到完全解决。例如，问题1中所说的可视化设计器和脚本解析器，还都没有实现。而问题2、3的解决方法还需要进行深入讨论。这一切，都需要耗费大量的时间和精力。<br>好在，即使不能完全实现由UCL图向代码的转换，这个理论至少也能帮助我们在设计前期就对一个项目的规模和工作量进行更为准确的统计。<br><br>限于个人的时间、金钱和精力，我不得不暂时放弃UCL的相关思考。把东西扔在这里，只希望机缘巧合，居然能起抛砖引玉之效，那也不枉我连日的冥思苦想了。 <img src ="http://www.cnitblog.com/addone/aggbug/19006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2006-11-09 14:53 <a href="http://www.cnitblog.com/addone/archive/2006/11/09/19006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最近开始ArgoUML的简体中文翻译工作</title><link>http://www.cnitblog.com/addone/archive/2006/09/09/16573.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Sat, 09 Sep 2006 03:39:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2006/09/09/16573.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/16573.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2006/09/09/16573.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/16573.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/16573.html</trackback:ping><description><![CDATA[我现在已经是ArgoUML的简体中文本地化项目的开发人员啦～<br>ArgoUML是一个十分优秀的用Java写成的开源的UML建模工具，支持UML 1.4中所有的标准UML图。我在Linux下一般就是用这个。<br><br><img src="http://argouml.tigris.org/images/welcome_screenshot_0_16_1.gif"><br><br>ArgoUML的功能相当不错，画图也十分简便，可惜一直没有中文版，直到0.22版才终于出现了一个十分不完整的繁体中文版。我的目标是在0.23.2之前基本完成简体中文的翻译工作。<br>由于ArgoUML的本地化文件使用的是iso-8859-1编码，因此中文字符只能以unicode的代码写入文件。为了提高效率，我用PyQT写了一个十分简单的工具，用来将utf8格式的字符串转为unicode代码。<br><br><img src="http://www.cnitblog.com/images/cnitblog_com/addone/unicode2ascii.png" alt="unicode2ascii.png" width="608" border="0" height="477"><br><br>有兴趣的朋友可以去访问一下ArgoUML的简体中文本地化项目的网址，在那里可以订阅邮件列表。<br><br><br>
<h3>链接</h3>
<a target="_blank" class="" title="" href="http://argouml.tigris.org/">ArgoUML主页</a><br><a target="_blank" class="" title="" href="http://argouml-i18n-zh.tigris.org/">ArgoUML中文本地化项目（ArgoUML-i18n-zh）主页</a><br><a target="_blank" class="" title="" href="http://argouml-zh-cn.tigris.org/">ArgoUML简体中文本地化项目（ArgoUML-zh-CN）主页</a><br> <img src ="http://www.cnitblog.com/addone/aggbug/16573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2006-09-09 11:39 <a href="http://www.cnitblog.com/addone/archive/2006/09/09/16573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我做的一个Java日历组件</title><link>http://www.cnitblog.com/addone/archive/2006/04/01/8457.html</link><dc:creator>Addone</dc:creator><author>Addone</author><pubDate>Fri, 31 Mar 2006 18:39:00 GMT</pubDate><guid>http://www.cnitblog.com/addone/archive/2006/04/01/8457.html</guid><wfw:comment>http://www.cnitblog.com/addone/comments/8457.html</wfw:comment><comments>http://www.cnitblog.com/addone/archive/2006/04/01/8457.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnitblog.com/addone/comments/commentRss/8457.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/addone/services/trackbacks/8457.html</trackback:ping><description><![CDATA[最近用java做一个很简单的桌面应用，居然发现连一个好用的日历组件/控件都找不到，郁闷&#8230;&#8230;<br>于是自己做了一个简单的，现在放出来共享吧！<br>呃&#8230;&#8230;其实这个也不完全是自己做的，修改自一个网上下回来的日历组件（似乎是多年前开发的了），不过原版不是很好用，我进行了重构和增强，估计已经很难看出跟原版的关系了&#8230;&#8230;<br><br>这个组件以jar的形式发布，源代码也在里面。直接运行即可看到演示效果。<br>由于使用了枚举（enum），所以需要java5.0才能编译运行。<br>大家可以随便使用、修改，不过最好把修改后的源码发回来给我，谢谢啦！<br><br>以下运行截图均运行于Kubuntu Linux 5.10+JRE 5.0系统中。<br>直接运行效果：<br><img src="http://www.cnitblog.com/images/cnitblog_com/addone/2300/r_jcalendar1.png" alt="r_jcalendar1.png" width="400" height="172" border="0"><br><br>实例效果（使用了第三方laf）：<br><img src="http://www.cnitblog.com/images/cnitblog_com/addone/2300/r_jcalendar2.png" alt="r_jcalendar2.png" width="400" height="200" border="0"><br><br><strong><font size="5"><a target="" class="" title="Java日历组件下载 build 20060401" href="http://www.cnitblog.com/Files/addone/aj_calendar_20060401.zip">点击这里下载</a></font></strong><br><br>
<h3>基本功能</h3>
可以选择日期，直接选择当天；<br>支持在改变日期时以及选择日期后的简单事件处理。<br>
<h3>编程接口</h3>
组件使用Eclipse3.1.1+JDK5.0开发并测试通过。<br>所有类放在包：addone.publics.gui.calendar中：<br>
<ul>
    <li>WeekDay类：操作周日的Enum</li>
    <li>CalendarColors类：定义了日历的外观颜色常数<br></li>
    <li>CellSelectionListener类：选中表格单元格后的侦听器</li>
    <li>CellChangeListener类：表格单元格改变后的侦听器</li>
    <li>CalendarSelectionListener类：在日历中选中日期后的侦听器</li>
    <li>CellChangeListener类：日历日期改变后的侦听器</li>
    <li>CalendarTable类：日历表格，封装了表格操作方法，继承自JTable</li>
    <li>CalendarPanel类：日历面板，封装了大部分的组件操作方法，继承自JPanel</li>
</ul>
基本用法（CalendarPanel类）：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">CalendarPanel()：构造一个以星期天为每周的第一天的日历<br>CalendarPanel(WeekDay)：构造一个以WeekDay为每周的第一天的日历<br>WeekDay&nbsp;getStartWeekDay()：返回当前日历每周的第一天<br>Calendar&nbsp;getCalendar()：返回组件内部当前的Calendar对象<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setCalendar(Calendar&nbsp;calendar)：重新设置组件内部的calendar对象，并刷新日历<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setToday()：日历跳转到当前日期，同时刷新日历<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setCalendarChangeListener(CalendarChangeListener&nbsp;listener)：设置日历日期改变时的侦听器，当改变年份或月份时，以及选中日期但尚未跳转时触发<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setCalendarSelectionListener(CalendarSelectionListener&nbsp;listener)：设置日历日期选中时的侦听器，当直接在日历中选中日期并跳转后，或者直接回到今天时触发</span></div>
<br>如果需要改变日历的外观颜色，直接修改CalendarColors类中的颜色常数即可。<br><br>
<h3>简单示例</h3>
<br>以下代码创建了一个Frame，其中放置了一个日历组件，日历设置为以星期一为每周的第一天。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CalendarFrame&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;JFrame&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;CalendarPanel&nbsp;myCalendar;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CalendarFrame()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initCalendar();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initFrame();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pack();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;initCalendar()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myCalendar&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CalendarPanel(WeekDay.MONDAY);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myCalendar.setCalendarSelectionListener(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CalendarSelectionListener()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;calendarSelected(Calendar&nbsp;currentCalendar)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(currentCalendar.get(Calendar.YEAR)</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">-</span><span style="color: #000000;">"</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">(currentCalendar.get(Calendar.MONTH)</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">)</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">-</span><span style="color: #000000;">"</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">currentCalendar.get(Calendar.DATE));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myCalendar.setCalendarChangeListener(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CalendarChangeListener()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;calendarChanged()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">Changing<img src="http://www.cnitblog.com/Images/dot.gif"></span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(myCalendar);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;initFrame()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setTitle(</span><span style="color: #000000;">"</span><span style="color: #000000;">日历</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setSize(</span><span style="color: #000000;">400</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">172</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setResizable(</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</span></div>
<br> <img src ="http://www.cnitblog.com/addone/aggbug/8457.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/addone/" target="_blank">Addone</a> 2006-04-01 02:39 <a href="http://www.cnitblog.com/addone/archive/2006/04/01/8457.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>