jungleford's profileJungleford's Home MSN 总舵PhotosBlogListsMore Tools Help
    12/1/2007

    SmartCalendar relaunched

    最近家里有点闹心的事,没来更新。

    SC 0.1β在sourceforge上停了一年多了(参见2006年3月14日3月22日两贴),现在重新拾起来完全是因为做那个被cancel项目激励的,从这个项目上得到了pattern上的更进一步的认识,于是思考这些经验是否可以用来重构SC。要感谢水木Java版那些对开源保持热情的年轻的人们,zms、kabbesy、dev、cjmm……,因为他们牵头创建了这个水木自己的开源项目站点:SMTHJava

    目前差不多做成型的是一些基本widget,完全GUI-independent,以及它们的Swing和SWT实现,这些基础widget是用来拼时钟/日历这些高级widget的积木块。想法就是类似IoC那样运行时注册,发现,并启用具体采用哪一套GUI Adapter实现方案(Swing or SWT)。简单介绍几个基本概念:

    ● Iterator(遍历器)

    这是在0.1β里就用到的概念。我们观察一个acceptable的日历组件应该有这么一个特征:可按输入(按钮或输入)转到指定月/年上,尤其是相邻的前/后一个月/年。这个行为往往可以适用到很多组件上,譬如通常用到的table“翻页”行为,譬如VB流行的年代常用的DAO/ADO组件。所以我这里抽象出一种行为叫Iterator,“可遍历”,当然它是一个interface,它包含这么几个最常用的方法:

    moveXXX():如moveFirst/moveLast/movePrevious/moveNext,即这个数据结构是“可游动”的,而且是“可线形游动”的(movePrevious/moveNext,而moveFirst/moveLast是两个特殊的游动方式)。

    getXXX():如getFirst/getLast/getPrevious/getNext,我们知道设计栈(Stack)这种数据结构的时候为方便起见会加上一个peek()方法,意思是让你得到栈顶元素而不将其弹出栈(瞟一眼但不去动它),这里也是类似的意思,得到某个位置上的元素而不移动游标。

    getCurrentItem()/setCurrentItem():顾名思义,得到当前游标上的元素或移动游标到某个元素。这是一种非线性遍历方式。

    isRollback()/setRollback():这个名字不知道是不是起得合适,我的本意是这个遍历器是不是“可循环”的,即到达头或尾再往下遍历是不是可以跳到尾或头开始,如果是循环队列的话需要做模运算确定index。

    我们看到“遍历器”实际上是一个增强型的队列(循环或非循环),在java.util包中你也能找到Iterator这个接口,但它是单向线性遍历的,只有next()方法。在这个接口上我写了几个基础遍历器,用于封装对整数的遍历,对List(线性列表)的遍历,对日历的遍历,这几个是GUI无关的组件;在GUI中有继承扩展了几种,如对文本框(尤其是格式化文本框)的遍历,对combo box的遍历。

    ● IterableWidget(可遍历组件)

    Iterator是个什么东东呢?简单的说它就是一个helper,可以用来告诉UI应该怎么做,如果要扯到MVC的话,Iterator就是一个controller,UI是view,Iterator要遍历的东西(比如comobox的item list)就是model了。我定义IterableWidget是这么一个玩意,它将一种UI和一个Iterator绑定在一块,这就成了一种稍微高级一点的GUI组件。我们能够想到的有哪些“可遍历组件”呢?上面说了,显示整数的文本框,combo box,spinner,我要做的calendar界面,可翻页的table,DAO/ADO组件等等。

    ● IterateAction

    IterableWidget仅仅是“可遍历”,要激发它动作需要通过另一个组件(譬如按钮),我定义了一个IterateActionButton的组件用于把一个按钮和它要激发的遍历操作的若干个IterableWidget绑定在一起,这个按钮去激发IterableWidget的helper(即Iterator)进行遍历操作。

    ● Adapter

    这里需要对泛型、Adapter模式和IoC稍微有点了解了。我的目的是想达到GUI-independent,对比Swing和SWT,你会发现它们差得十万八千里,除了Object这个爪哇人都知道的根对象,两者竟然没有交集,那你怎么来搞GUI无关性?怎么抽取共同行为?于是乎,泛型就来了吧?把一个具体的GUI对象适配成我这套GUI library当中的对象,具体要用的时候(比如布局,这个GUI-independent做不了)再getAdaptee()还原成具体的GUI对象(Swing或SWT或其它什么玩意)。不管怎么样,地球人总有一套必不可少的公共组件:按钮、标签、文本框、容器、对话框、窗口……,再高级一点就表格、树……,更高级一点就像我们要做的这个日历等等。widget越基础,行为就越容易抽象。

    ● 一点puzzle

    写的时候往往是反复重构,解耦程度越高,重构的代价就越低,这也符合agile的办事风格。我比较为难的是权衡保留泛型参数的规模上,如果你内部属性的类型要做到“精确”,势必要有较多的泛型参数来约束,这个好处是减少类型检查的hard code,但泛型参数的增加会随着类库的继承和复用层次的增长而增长,这是很讨厌的一件事,因为你会发现为了创建一个对象需要指定N多个你并不关心的这个对象内部属性的具体类型。所以,我妥协了,人是容易妥协的动物,我对一个widget通常只用一个泛型参数(如果它需要用泛型的话),这个参数就是指代它需要适配的那个GUI组件的类型;所有接口,目前只有IAdapter使用了泛型,因为我们需要得到adaptee,其它接口只定义行为;widget内部如果用到composite的widget的话,都用这个widget的接口类型。

    以上大概通过代码更好理解一些,代码我放单位的机器上了,过两天传上来。

     

    重新启动的SmartCalendar项目主页在这里,主页快照:

     

    smartcalendar (活跃度12)

    可扩展的时钟/日历组件库.

    详细介绍

    一个可扩展的时钟/日历组件,来源于我在2006年3月在sourceforge上开的项目SmartCalendar 0.1β版。原始创意来源于对JDK没有提供日历选择框组件的不满,因为JFileChooser和JColorChooser两种Dialog都实现了。此类例子在网上多得是,于是考虑做成一个可扩展的API库,可以提供给其他人员进行二次开发。0.1β版提供了 数字时钟/模拟时钟/月历/年历 高级Swing组件,以及 月历/年历 的日期选择框组件,总的来说这一版的代码耦合度还是密了些,供二次开发的伸缩度不够理想。另外,SWT从3.3开始提供DateTime Widget,所以单纯的日历组件意义已经不大。

    本项目(0.2版)希望达到如下目标:

    • GUI independency:即对GUI实现进行抽象和适配,提供一个更统一的Adapter,以适应不同的GUI库;提供SmartCalendar所依赖的几个基础Widget
    • 充实上述四种组件
    • 至少提供Swing和SWT两种具体实现
    • 提供日程表组件
    • 中国农历系统(ChineseLunarCalendar,视情况而定,是否有一个全面的算法?)

    长期目标:

    • 0.2版仅follow SUN JDK的Calendar API,考虑到Joda-Time项目已加入JSR,未来也应给予支持
    • 逐渐扩充为一个GUI独立的RCP抽象组件库(GUI-independent Widget Library)

    更长远的目标:

    • 考虑分离出一个"微内核",或者说"极小内核"的JVM,甚至小于J2ME(是否可能仅仅是native的?),仅提供虚拟机运转的最基本服务,其它的API都可以抽象化,以适配不同厂商的具体实现,这个项目就是希望定义出这些"微内核"以外的"扩展API"的行为。

    文档

    [编写文档]

    Unable to render {include} Couldn't find a page to include called: smartcalendar_doc

    源代码

    源代码浏览可以访问fisheye
    匿名用户检出最新代码 svn co http://smthjava.org/repo/smartcalendar/trunk/ trunk
    开发人员检出最新代码 svn co https://smthjava.org/repo/smartcalendar/trunk/ trunk --username 用户名

    最新5条更新

     FishEye on repo/smartcalendar (rss_2.0)
    (Recent changes to the "repo" repository under directory /smartcalendar)

    root: init project smartcalendar

    RoadMap

    分布图

    Unreleased
    0.1 ( 28/十一月/07 | 发行报告 )

    进度: 
    没有问题.

    早期版本,延续自sourceforge上开的项目SmartCalendar 0.1β版

    没有问题.

    问题跟踪

    缺陷报告和新功能需求可以通过jira来提交

     SMTHJAVA (1 issues)

    T
    Key
    Summary
    Assignee
    Reporter
    Pr
    Status
    Res
    Created
    Updated
    Due

    New Feature
    CAL-1
    实现农历万年历
    jungleford@smth
    kabbesy@smth
    Major
    OpenOpen
    未解决
    Nov 30, 2007
    Nov 30, 2007

    团队

    创建人:
    jungleford@smth
    开发人员
    jungleford@smth
    kabbesy@smth
    License:
    LGPL

    Comments (1)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    cai kabbesywrote:
    本来说看看二战模型的pp来着...
    Jan. 21

    Trackbacks

    The trackback URL for this entry is:
    http://jungleford.spaces.live.com/blog/cns!E733CCEEE4BE0FB2!2015.trak
    Weblogs that reference this entry
    • None