订阅 漓筝轩 的RSS 
  2008年5月5日
报表工具的演示录像发布

http://jeasonzhao.uubox.net/browse.u/Public/

1、报表的基本操作 和 2、参数配置s.rar (2403K)

解压缩后两个文件
1、报表的基本操作.avi (71M)
2、参数配置 (50M)

3、列操作和图操作.rar (6557K)

解压缩之后一个文件

3、列操作和图操作.avi(213M)

有兴趣的可以下载看看,全功能演示

更多的信息 参看 http://www.loveayang.com.cn/category/ERIS.aspx (也不是很多啦)

posted @ 2008-05-05 12:36 Jeason 阅读(441) | 评论 (0)编辑
  2007年12月12日

实现功能:

  1. 在Table上实现行的拖动。支持预览
  2. 忽略THEAD/TFoot的行

支持的两个函数

if(window.scrollTop==null)

{

    window.scrollTop=function()

    {

        return window.document.body.scrollTop || window.document.documentElement.scrollTop;

    }

}

if(null==window.scrollLeft)

{

    window.scrollLeft=function()

    {

        return window.document.body.scrollLeft || window.document.documentElement.scrollLeft;

    }

}

主要功能函数

if(null==window.XTable)

{

    window.XTable={};

    window.XTable.DragDrop={};

    window.XTable.DragDrop.tempRow=null;

    window.XTable.DragDrop.isProcessing=false;

    window.XTable.DragDrop.bgColorInitRow=null;

    window.XTable.DragDrop.bgColorOverRow=null;

    window.XTable.DragDrop.rowOver=null;

    window.XTable.DragDrop.divStyle="color:white;"+

        "background-color:#6E7B8B;"+

        "position:absolute;"+

        "z-index:9000;"+

        "border:solid 2px #68228B;"+

        "width:300px;"+

        "padding:2px;";

    window.XTable.DragDrop.tdStyle="color:#98FB98;"+

        "white-space:nowrap;"+

        "border:solid 1px #6C7B8B;"+

        "padding-left:5px;"+

        "padding-right:3px;";

    window.XTable.DragDrop.overColor="#708090";

    window.XTable.DragDrop.maskColor="#CDBA96";

    window.XTable.rowDragDropMouseDown=function(tr)

    {

        if(null==tr||tr.parentElement==null||tr.parentElement.tagName!="TBODY")

        {

            return;

        }

        window.XTable.DragDrop.bgColorInitRow=tr.style.backgroundColor;

        tr.style.backgroundColor=window.XTable.DragDrop.maskColor;

        if(null==window.XTable.DragDrop.tempRow)

        {

            window.XTable.DragDrop.tempRow=document.createElement("<div style='"+window.XTable.DragDrop.divStyle+"'>");

            document.body.appendChild(window.XTable.DragDrop.tempRow);            

            window.XTable.DragDrop.tempRow.appendChild(document.createTextNode("拖动到目标行的上面,本行将自动放在目标行前面"));

        }    

        while(window.XTable.DragDrop.tempRow.children &&window.XTable.DragDrop.tempRow.children.length>1)

        {

            window.XTable.DragDrop.tempRow.removeChild(window.XTable.DragDrop.tempRow.children[1]);

        }

        window.XTable.DragDrop.tempRow.style.display="block";

        window.XTable.DragDrop.tempRow.style.top=event.clientY+scrollTop();

        window.XTable.DragDrop.tempRow.style.left=event.clientX+scrollLeft()+10;

        $A(tr.children).each(function(td,idx)

        {

            var ntd=document.createElement("<span style='"+window.XTable.DragDrop.tdStyle+"'>");

            ntd.appendChild(document.createTextNode(td.innerText));

            window.XTable.DragDrop.tempRow.appendChild(ntd)

        });

        window.XTable.DragDrop.isProcessing=true;

        tr.setCapture();

    }

    window.XTable.rowDragDropMouseMove=function(tr)

    {

        if(null!=window.XTable.DragDrop.rowOver)

        {

            window.XTable.DragDrop.rowOver.style.backgroundColor=window.XTable.DragDrop.bgColorOverRow;

            window.XTable.DragDrop.rowOver=null;

        }

        if(false==window.XTable.DragDrop.isProcessing)

        {

            return false;

        }

        window.XTable.DragDrop.tempRow.style.top=event.clientY+scrollTop();

        window.XTable.DragDrop.tempRow.style.left=event.clientX+scrollLeft()+10;

        var target=document.elementFromPoint(event.x,event.y);

        while( null != target && target.tagName!="TR" )

        {

            target = target.parentElement;

        }

        if(!target||null==target.parentElement||target.parentElement.tagName!="TBODY")

        {

            return;

        }

        window.XTable.DragDrop.bgColorOverRow=target.style.backgroundColor;

        window.XTable.DragDrop.rowOver=target;

        target.style.backgroundColor=window.XTable.DragDrop.overColor;

    }

    window.XTable.rowDragDropMouseUp=function(tr)

    {

        tr.releaseCapture();

        tr.style.backgroundColor=window.XTable.DragDrop.bgColorInitRow;

        if(null!=window.XTable.DragDrop.rowOver)

        {

            window.XTable.DragDrop.rowOver.style.backgroundColor=window.XTable.DragDrop.bgColorOverRow;

            window.XTable.DragDrop.rowOver=null;

        }

        if(null!=window.XTable.DragDrop.tempRow)

        {

            window.XTable.DragDrop.tempRow.style.display="none";

        }

        if(!window.XTable.DragDrop.isProcessing)

        {

            return false;

        }

        window.XTable.DragDrop.isProcessing=false;

        var target=document.elementFromPoint(event.x,event.y);

        while( null != target && target.tagName!="TR" )

        {

            target = target.parentElement;

        }

        if(!target||null==target.parentElement||target.parentElement.tagName!="TBODY")

        {

            return;

        }

        target.insertAdjacentElement("BeforeBegin",tr);

    }

    window.XTable.makeDragDrop=function(tablename)

    {

        var table=$(tablename);

        if(null==table)

        {

            return;

        }

        if(!table.tBodies||table.tBodies.length<1)

        {

            return;

        }

        $A(table.tBodies[0].rows).each(function(tr,n)

        {

            (function(tr)

            {

                tr.onmousedown=function()

                {

                    window.XTable.rowDragDropMouseDown(tr);

                }

                tr.onmousemove=function()

                {

                    window.XTable.rowDragDropMouseMove(tr);

                }

                tr.onmouseup=function()

                {

                    window.XTable.rowDragDropMouseUp(tr);

                }

            }

            )(tr);

        });

    }

}

测试的脚本如下

<div style="width:200px;float:left">AAA</div>

<div style="">

    <TABLE WIDTH="800" BORDER="1" ID="AAAAAA" >

    <THead>

         <TR><TD>Header0</TD><TD>Header1</TD><TD>Header2</TD></TR>

    </THead>

    <tbody>

     <TR style="background-color:"><TD>ROW_0</TD><TD>ROW_0_CELL_1</TD><TD>ROW_0_CELL2_1</TD></TR>

     <TR style="background-color:black;color:white"><TD>ROW_1</TD><TD>ROW_1_CELL_2</TD><TD>ROW_1_CELL2_2</TD></TR>

     <TR style="background-color:white"><TD>ROW_2</TD><TD>ROW_2_CELL_3</TD><TD>ROW_2_CELL2_3</TD></TR>

     <TR style="background-color:menu"><TD>ROW_3</TD><TD>ROW_3_CELL_4</TD><TD>ROW_3_CELL2_4</TD></TR>

     <TR style="background-color:yellow"><TD>ROW_4</TD><TD>ROW_4_CELL_5</TD><TD>ROW_4_CELL2_5</TD></TR>

     <TR style="background-color:green"><TD>ROW_5</TD><TD>ROW_5_CELL_6</TD><TD>ROW_5_CELL2_6</TD></TR>

     <TR style="background-color:blue"><TD>ROW_6</TD><TD>ROW_6_CELL_7</TD><TD>ROW_6_CELL2_7</TD></TR>

     <TR style="background-color:red"><TD>ROW_7</TD><TD>ROW_7_CELL_8</TD><TD>ROW_7_CELL2_8</TD></TR>

    </tbody>

    <TFOOT>

         <TR><TD>Footer</TD><TD>Footer</TD><TD>Footer</TD></TR>

    </TFOOT>

    </TABLE>

</div>

<script type="text/javascript" defer>

    window.XTable.makeDragDrop("AAAAAA");

</script>


posted @ 2007-12-12 18:02 Jeason 阅读(333) | 评论 (0)编辑

更多的沈胜衣的文章,请访问此处

前面的几次报表系统交流,不管是不是我做的,效果都不是很好,当时只看到了表象,觉得是别人的原因,现在想起来,应该是自己的偏置所导致这种情况,我无意以什么手段或者方式来说服人,但是我会正确的表达我的想法,正是这种过于理想化的想法促使了今天的结果。

在我参加其他厂商的培训的时候,我大多数时候都是在本子上乱画,我觉得在这个时候我真正关心的不是讲台上的仁兄正在讲的,我只要知道关键字就可以了,而更多的信息我可能来源于网络,也可能求助于书籍,但是肯定不是课堂填鸭式的教学,也不会式面对面的交流。我注重在整个过程中的个人体验,而不是结果。我去参加培训,可能式迫不得已,更多的时候,可能是找个地方休息休息自己的脑袋。

如果我能够把以上的思维推及到自己的PPT讲座中,那么我还可能有最开始的偏激的想法么?

很像是一种高傲蒙蔽了眼睛。我从事了四年的经营分析的开发,从最低层的数据建模到ETL到最终的OLAP展现我都参与过,在这个期间,我自己编写代码实现了一个ETL抽取系统和一个简单的统计报表系统,在这个时候,数据仓库的概念已经深深植根于我这个不太大的脑袋中,所以就产生了很多技术人员所犯的错误:间歇性的技术视觉无视!

我很多时候都TM语重心长的告诉兄弟们,任何事情存在必然有他的道理。为什么夏桀都成武王所说的那么不堪了,武王伐纣还是花了那么大的工夫?为什么CELL组件如此难用,还是有用那么多的MM在网络、杂志上打广告?不错,正是因为这种盲试,所以导致我没有仔细的思考问题。同样没有花功夫去思考报表系统的适应性的问题。

在离开上一家公司的时候,老领导担心我对现在经营分析系统甩手不管了,我很恳切的说,那经营分析系统对我而言,就像一个孩子,不管他存在多大的缺点,他还是我的孩子,我倾注了那么多功夫在这个系统之上,我不会坐视他的消亡。

这个报表系统正是脱胎于经营分析系统的报表系统,在这个时候我不会放弃,所以我将新的CodeName命名未ERIS.

回到最初的标题,在交流中我们的确还存在很大的问题,忽视了受众 本身的问题,或者说是当受众是技术人员的时候,我们的考虑不是很足够。在讲PPT的时候,我过分的关注了PPT的内容,忘记了关注受众的接受程度,其实归根结底,就是技术基础的问题。

如果受众是客户,我可能会慎重很多,对PPT的材料准备,布局等等考虑的更多,但是对方是自己部门和其他兄弟部门的开发人员的时候就不太注意这个问题了,我的确是忘记了演说者的第一要素:你要当你在任何时候都可以以正确的方式说出你想说的正确的事情。

温博格老先生拿这事情开了一个玩笑,说这个就是交流的输出过度,输出过度是指在老式的磁带机上,如果输出的字节的速度大于打点设备的速度就会出现字符丢失或者重叠,从而导致信息的曲解甚至误解。同时,温博格老先生举的那个学生的例子,和我面对的情况非常相似,汗!

posted @ 2007-12-12 10:33 Jeason 阅读(107) | 评论 (0)编辑
  2007年11月20日
 如果你要做IT,首先你要确定你的目标是什么,我的建议是,千万不要当程序员,因为中国这个环境之下,没有人当程序员是个什么东西。
 程序员是挣不到钱的,不管你是自己做程序来卖还是帮公司做程序,你最终还是一个搬砖头的,就是一民工,没有人会当民工是工程师,所以,如果有人为你冠以“软件工程师”的头衔你还沾沾自喜的话,恭喜你,你还没有看到这个行业背后的黑暗,保持一份纯洁对于我这种老家伙来说已经变成一种奢侈了。先说说自己做私活吧,一个简单的Web站点,在你那里可能能够卖到5K、1W甚至2W,但是也就这样顶天了,你还能卖到多少?而且没有后续的合同保障,所有的维护啊程序变更都是你自己的事情,但是同样的项目,在公对公的卖,价格至少翻5倍,如果加上硬件,那就不得了了,最近我的一个朋友公司还卖出去一套自己开发的国产OA,价值300w,购置的是 PCServer单机+JBOSS,呵呵,有些不可思议?事实就是这样,你觉得你占了便宜,实际上你可能花费了更多的精力和时间,你可以计算计算这笔钱自己拿的是否值得。对于帮公司就更不用说了,公司会计算软件成本,基本是开发人员开发费用(基础设施成本+工资+住行费用)+市场费用(招待费+市场住行费用+灰色费用)+运维成本(运维部门的支出)+硬件成本+税收成本,我不是搞会计的,对于这些术语可能不准确;好的,项目总投资额-软件成本就应该是公司的收益了,现在可以进行收益分配了,我们可以看到,在收益分配处,无一例外的是公司本部收益比例>市场收益比例>研发收益比例>运维收益比例。公司占用比例无可厚非,俗话说的老板占大头,没错,就是这样,你就Shut UP了;市场占收益比例也好像合理,没有市场就没有项目,大家都得喝西北风;研发,呵呵,当然得有了。首先出的问题可能就是运维收益了,一般的理解,运维部门作为公司的内部部门,不能直接参与项目收益分摊,的确也是没有直接参与,但是变相的就厉害了,我以前的某个公司是如此计算运维成本的,一个项目中配备网络管理员1个+财务人员1个+项目综合秘书1个+综合事务管理1个共计四个人,这四个人的成本是按照工资+日常开销、补助+加班费计算,其参与周期为整个项目周期,好像也没有啥问题,问题就在于这些人都是兼用在多个项目中的,你说是不是成本就转换成收益了;同样的情况也发生在其他的组成员中,例如测试、市场和商务,所以对于成本的计算,也就如此,没有办法,成本转换成收益,的确不错,公司领导恨恨的说在兄弟们身上砸了多少多少,都是虚的,实际拿中等程序员的工资×整个项目的参与人员数量×项目周期基本就是实际的可见成本,至于交通费住宿费加班费补助费都可以在前面计算公式中折合。这下你知道你为公司作出不朽的贡献了吧,你一个人养着那么多人,哈哈,笑话。
 最可怜的是,在这种制度下,程序员的工资涨的速度块却幅度不大,我最初的公司共对程序员定了6格级别,初一初二初三中一中二中三,刚入门的是初一,1000,然后每级涨幅100,即使到了中三你也还一个小PP,去看看PM的工资,他们涨的机会小多了,呵呵,可是基数不一样啊。
 如果你要想学东西,也不应该选择当程序员,其根本的症结在于,程序员还是那个整个建筑工地里的民工,你会发现你自己在不断的搬砖头,什么设计模式啊、面向对象之类的,和民工搬砖头使用手还是箩筐还是用竹子编的专用工具没什么区别——都是为了更好的搬砖头。你会发现,你没有时间来看你买的书,来学习你所感兴趣的新东西,因为你老在搬砖头啊。公司会给一定的承诺,忙完这个项目大家可以休息休息了,呵呵,你要相信这个就有些天真了,程序员都休息了,公司不就歇菜了。在你搬砖头的时候,市场商务可是没有闲着,还在那边不遗余力的刨坑,等着你这个民工跳下去。
 有的年轻人在找工作的时候会问培训机会,一般公司都人模狗样的说有很多培训机会,呵呵,你又相信这个东西的话,恭喜你,你还继续保持着天真。培训分成两类,收费的和免费的,免费的要时间,收费的要时间又要钱。时间不就是请假了,好像和公司培训没有关系了,对了,说的就是收费的。技术人员和运维部门的口味可不一样,在程序员眼中Borland曾经是旗手,而在他们眼中这家公司只是昨日黄花,所以首先在技术培训的选择上面就存在分歧,你不可能听到Martin Fowler的演讲,倒是可能会看到张亚勤的一个人的秀。所以,培训,对于程序员来说,更像一个逃避工作的机会。再看看参加的人员,一个不成文的规约,越贵的培训参与的人的层次越高,作为金字塔的最底层的同学,你参加微软TechED的机会和你去华星看加勒比海盗的首映场的概率一样——一般的主张是,钱要花在刀刃上,程序员好像是刀把子,是在手里面用的,不是在外面用的。说起这个,想起2003年参加的那次TechED,我因为要辞职,公司给了这么一张门票给我,会上看到的学生居多,公司去的程序员少,其他大多数是穿西服的要么精干要么大腹便便的仁兄。参会期间,程序员和学生都很饥渴,都在忙着选择课程(课程时间有冲突),而穿西服的却在打电话、和展商唠嗑,那次给我的刺激非常大,如果再给我门票,我也不会参加这种大型的技术推广会,因为我怕受刺激。
 还没说完呢。刚才提到,在金字塔中,程序员属于最底层,也就是说是个人基本都可能会踩你一脚,技术岗位和其他的岗位不太一样的是可替代性强,具有讽刺意义的是其他岗位的不可替代性正是因为这些岗位对技术的不敏感,具体是什么就心照不宣啦,哈哈。而程序员应该是整个行业里面最可爱的人,有啥说啥,保持一个正气凌然的样子(建议Party接收所有的程序员作为正式Party员,坚决能做到又HONG又ZHUAN的就程序员啦,哈哈),这样可是不好,但是换个角度想,技术是诚实的,不是诚实的人怎么可能学好技术?(可能比较费解,自己琢磨吧)刚才说到某些岗位的技术不敏感性,可能你上楼去帮某人看看人家的Excel如何进行行汇总行锁定,你心里在笑“这丫也忒笨了吧”,呵呵,有可能对方做的整好就是你的考勤表、工资表。
 程序员在公司的不如意不是在于个人发展或者技术层面的不足,对于这两点,的确是辞职的不二法门,但是实际很多时候程序员的稳定性是很强的,因为没有什么心计所以还是单纯。程序员的不如意很多时候是由于制度约束或者不公平导致的,人嘛,心里都有一杆秤。我初到某公司的时候,因为位置匮乏,就坐在领导的办公间,某君横入,指手画脚,大言炎炎,我怯怯的问“君何人?”,此君答曰“全公司就我一个姓汤的,你去查吧”,寒,我查了一下,运维综合的头头,果然盛气凌人,ORZ了。某次会议,客户十几个人,市场配合一人、技术一人陪着去风景区,横里杀出一个综合的人也要去陪客户;如此两件事在我心里留下了不小的阴影,也是导致我对这家公司产生成见的第一药引,也成为离开公司的第一成因。
 刚才提到,程序员的稳定性强,原因很简单,程序员工作的目标是学习,而非其他,在这个层面上,程序员可能或多或少的有种心思,就是运维综合只是服务部门,我不评论这个想法是否正确,但是有一点可以说道,一个机器的运转需要不同的部件,各个部件最终服务的对象是整体,而不是服务于个体,正如军队之于国家机器,所以在这个层面上,产生冲突是在所难免。这也导致一个有意思的情况,程序员对程序员服气,对于技术不咋地的也不咋地服气,要纠正这个很难,这就显得程序员在全公司范围内显得很屌技术越强好像就越屌。对于其他的金字塔下层的人员来说就有些意思了,身处在一个技术公司,技术不敏感导致危机感较强,对程序员这些屌人就更加敏感,呵呵问题不就出来了。对技术强悍的又像我这样的屌人(我的技术不强,虚荣心让我很屌,哈哈),说一句多的坏话,你的直系领导能够包容你,知道你是个“才”,了解你的德性,但是其他的人却只能看到你屌,看不到你的才,这点需要注意。
 才说了,搬砖头没有时间倒腾技术,那么发展线路呢?一句话,如果你现在身在一线,你会有很长时间在一线。程序员、高级程序员、设计工程师、分析工程师,都是程序员,你的发展线路是 什么?技术好了,可能会让你啃硬骨头,或者好些可以让你带Team,让你从编写一个项目的代码转换到编写更多项目的代码。从Team Leader到经理的转变不是一个职位的问题,而是一个角色转换的问题,绝大多数情况,公司会相信空投,即便这个空降部队的家伙前面还是某个公司的Team Leader。倒不是说要转换就得跳槽,关键是思维的转换需要时间,编写代码占用了那么多时间,你还有多少时间给你自己用?我就纳闷了,一个MBA学完就能搞好管理?一行代码都不会就能建模,扯了,大多数人都抱有这样的思想,但是也无可奈何,有的事情该服气要服气。所以,要转换角色就赶紧,否则就来不及了。
 给那些想编而优则商务的兄弟泼点冷水吧,你不会有太多的机会真正处理商务或者市场的事情,大部分时候说让你到现场锻炼,因为你是程序员,更多的时候你其实是换了一个地方换了一个爷爷来编程而已,而且,比在公司的还不如。如果你想籍此建立你的人脉关系,那就更扯蛋了,首先,你谈的都是技术问题,你有机会在大领导面前露脸,但是没机会表达自己的“优秀",更多的时候你是在和业务人员打交到;其次,对方领导不可能太能记住你,比起你所作的PPT而言,你的脸容易忘记多了;第三,和对方“真正接触”的机会少,嘛时候能现出人的本性?人说最好的交情有一个就是"一起打过炮",嘿嘿,俗了不是,那时你不在,不是商务在就是市场在;第四,你的领导也记不住你,你又不直接汇报,领导可能能在某个场合恍然曰“此君能人也,某项目得赖君大力支持得以验收,赞!”,一杯酒的交情,呵呵;最后,你还真没有那么多时间去揣摩人的心思,你更多的心思还在你的立国之本——技术上,小农经济的思想何时转换了,何时就是你出息了。
 程序员是一个比较脆弱的角色,为啥这样说啊,程序员心理防线低啊,我本将心照明月,明月何曾照沟渠,呵呵。对技术的敏感是对的,但是这个敏感性好像无处不在,一句很受伤就可以概括,没辙啊,难不成学oerlord里面的,指挥小红小黄小蓝揍他丫的?哈哈,YY吧。
 最后说点正面的,如果你真的还要当程序员或者你没办法只能当程序员(就像我一样),首先要明确,工作只是你生活的一个部分,不是全部,实话说,从04年以后,我投入实际工作的时间最多到60%,已经没有那种百分百投入的激情了;其次你要明白在整个集体中,你个人的能力不可忽视也不可视之过高,项目的生死存亡和你本身没有太多的关系,本分则以,矫枉过正亏身体;再次,如果要靠写程序当程序员挣钱,就要忍得,公司除了程序员这群单纯的家伙还有不单纯的家伙,要被人挖坑自己哭还来不及呢;最后,如果你执意要当程序员,你要明白,程序员是一场苦修,你最好把它当成你的乐趣,否则你会烦死。
 我是出不去了,不管我在什么样的位置,这些年根深蒂固的思想左右了我很久了,现在我就像修苦禅一样当一个不是很称职的程序员,对我来说,程序员是完成我自我修养的一个过程。我没有后悔选择这个职业,因为那是一个必然,只是奉劝那些热血青年,不要过多的相信这个行业的光辉,99年我在厂里,一月400大洋,2000年我当程序员,一月1.7K,差距很大,而现在,我原先的厂里我那些哥们姐们官也当了,工资也到5K了,所以路有很多条,选一条别后悔的路——就是那条你选了就别后悔的路。人TM一辈子真正的就只有30年供你支配,完成你自己吧。
 
更多的正版沈胜衣
posted @ 2007-11-20 11:32 Jeason 阅读(358) | 评论 (5)编辑
  2007年11月14日

在实际开发中,我们遇到一种情况,需要将表格的底部放一个分页的标签,这样使得布局如下

实际表格主体包含两部分内容,数据和分页信息,分页信息最好总是停靠在表格主体的底部,我们以前使用的是表格的Valign实现,但是存在不少的问题,现在我们使用CSS+Expression实现以下功能
1、表格主体的位置可以在水平和垂直的任何位置
2、表格主体的高度自动扩展到页面的底部
3、分页信息停靠在表格主体的底部

现在的缺陷
1、页的margin、padding属性会导致定位不正确
2、需要自处理表格行数,免得将分页信息覆盖
3、页面如果包含在主体以后的东西需要自己计算啦

闲话少说,帖代码

<script>
if(null==window.$)
{
  window.$=function() 
  {
    var elements = new Array();
    for (var i = 0; i < arguments.length; i++) 
    {
      var element = arguments[i];
      if (typeof element == 
'string')
        element = document.getElementById(element);
      if (arguments.length == 1)
        return element;
      elements.push(element);
    }
    return elements;
  }
}
function controlOffsetLeft(itemName) 
{
  var item=$(itemName);
  var totalOffset = 0;
  do 
  {
    try
    {
      totalOffset += item.offsetLeft;
      item = item.offsetParent;
    }
    catch(ee)
    {
    }
  } 
  while (item != null);
  return totalOffset;
}
function controlOffsetTop(itemName) 
{
  var item=$(itemName);
  var totalOffset = 0;
  do 
  {
    try
    {
      totalOffset += item.offsetTop;
      item = item.offsetParent;
    }
    catch(ee)
    {
    }
  } while (item != null);
  return totalOffset;
}
function scrollTop()
{
  return window.document.body.scrollTop || window.document.documentElement.scrollTop;
}
function scrollLeft()
{
  return window.document.body.scrollLeft || window.document.documentElement.scrollLeft;
}
function windowWidth()
{
  var de = document.documentElement;
  return window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
}
function windowHeight()
{
  var de = document.documentElement;
  return window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;  
}
</script>

<style>
  #Content
  {
    position:relative;
    height:expression(windowHeight()-controlOffsetTop(this)-16/*设置Margin的值,默认的情况下Body的Margin为上下为8px*/);    
    border:solid 1px blue;
    clear:right;
  }
  #PageInfo
  {
    position:absolute;
    border:solid 2px menu;
    width:100%;
    bottom:0;
    left:0;
    background-color:ghostwhite;
    text-align:right;
  }
</style>
AA<br/>  
BB<br/>  
CC<br/>  
CC<br/>  
CC<br/>  
CC<br/>  
CC<br/>  
CC<br/>  
<div>
<div style="width:100px;float:left;background-color:#FFFFCC;">
  传统的东东,这里的高度是自适应的高度,呵呵,如果需要实现底部对齐,有些费劲
</div>
<div id="content">
  
  <table style="width:100%" border="1">
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
    <tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
  </table>
  要注意这里表格的行数啊,否则一不小心就会覆盖下面的分页显示的东西,慎重啊慎重
  <div id="PageInfo">
  分页显示<br/>
  后面的东东
  </div>
</div>
<em>这行你肯定需要滚屏才看得到!!!这行导致出现滚动条!</em>
</div
我的BLOG搬家到自己的站点
站点链接
RSS
posted @ 2007-11-14 19:21 Jeason 阅读(924) | 评论 (4)编辑
我的BLOG搬家到自己的站点
站点链接
RSS
  先帖样子
    
使用层或者其他技术所实现的JS菜单不能解决的问题就是这些菜单不能跨帧,也就是说在Frame之间的时候无可奈何,所幸的是IE5+提供了createPopup这个函数,可以提供窗口的创建,使用createPopup需要注意以下几个问题:
1、函数没有任何参数
2、CreatePopup函数返回的值是新窗口的句柄,这个窗口和普通的窗口一样,所有该有的东西都有。
3、新窗口的parent属性可以对父级窗口(调用createPopup函数的窗口进行访问)
4、一个窗口只能创建一个popup窗口,新调用createPopup将会吧以前的窗口关闭。
5、新窗口的内容初始的时候是空的,没有任何内容,使用document.write和document.body.innerHTML设置值
6、窗口显示的时候调用popwindow.show函数,调用契约为 show(left,top, width, height, document.body);最后一个参数指明位置属性相对的对象
7、窗口隐藏直接调用hide函数。
8、在父级窗口中点击鼠标将会自动将popwindow隐藏。
9、销毁父亲窗口不一定销毁其创建的popwindow,前提是保存窗口句柄的对象是否被销毁。
10、使用alt-tab转换窗口的时候,有时这些新窗口会悬浮在桌面顶层,不会随IE窗口转到后台而隐藏(IE6、IE7都是)
11、新窗口的对象不能使用父窗口的CSS风格,需要手工复写
12、新窗口中的链接(Anchors)需要注意点击之后链接显示的窗口是当前的窗口,一般无效。
13、新窗口中的JavaScript出现错误的时候并不会在当前的IE状态栏中提示!
14、新窗口的CSS风格不支持expression,晕!
15、显示窗口的时候(调用show函数)必须指定窗口的位置和大小,尤其是大小,新窗口可不能自动进行缩放!

实现跨帧菜单首先确定显示方式,每一级的菜单都是显示在一个Popwindow中,如前所述,在一个窗口中只能有一个popwindow,如图显示二级菜单就无法显示了,如何解决这个问题呢?
刚才我们提到,popwindow对象本身就是一个完整的窗口对象,要解决这个问题的最直接的办法就是,下级菜单的生成有父亲菜单所在的窗口(不管是主窗口还是popwindow)调用createPopup生成,这样,各级菜单都可以拥有自己的popwindow,而且可以自动的在同级菜单中进行切换,具体的脚本如下

var ele=control==null?event.srcElement:$(control);
/*...*/
var popw=ele.document.parentWindow.window.createPopup();
/*...*/

层次结构可以构造菜单的基本样式,刚才提到,popwindow不支持CSS风格,也就是说需要手工将CSS风格写到popwindow中,写CSS风格可以使用document.write方式或者直接构造styleSheet对象然后插入rule的方式(注意,直接使用document.body.innerHTML写的style标签好像没有生效),我采用前者,主要原因是,我在主窗口中配置菜单的显示风格,而后将这些显示css风格的文本信息直接保存下来,然后对每个新窗口进行写操作,这样就可以保持每级菜单的CSS风格完全一致。
读取主窗口CSS的代码如下

FrameMenuConfig.CssText="";
    for(var n=0;FrameMenuConfig.CssPrefix!=null && FrameMenuConfig.CssPrefix.length>0 && n<document.styleSheets.length;n++)
    {
      var sts=document.styleSheets[n];
      for(var x=0;x<sts.rules.length;x++)
      {
        var rr=sts.rules[x];
        if(rr.selectorText.indexOf(FrameMenuConfig.CssPrefix)>=0)
        {
          FrameMenuConfig.CssText+=rr.selectorText+"{"+rr.style.cssText+"}";
        }
      }
    }

这里使用的是匹配FrameMenuConfig.CssPrefix的CSS风格才写入到新的窗口中。

然后涉及到菜单的数据结构的定义,这个定义比较简单,就不扯了,用膝盖也能想出来。我这边处理的时候为了防止函数被重复定义,使用了简单的类静态函数的方式进行定义。

到现在为止,我们可以画出一层一层的菜单,在每层的菜单项上挂接onmouseover处理函数就可以自动弹出下级菜单,一切看起来已经完成了。

呵呵,好像还有点东西,菜单的链接有问题,如何解决在新窗口中的Anchor链接指向的页面在我们指定的框架中显示?首先还是要强调,每个popupwindow都是一个window对象,使用parent可以取得上级的对象,我的处理方法是在主窗口中定义了一个goto(url,target)的函数,这个函数负责在主窗口中将URL正确的进行跳转,带出来的问题是,怎么让popwindw正确的调用这个函数,第一层菜单使用parent.goto,第二层菜单使用parent.parent.goto,第三层使用.....Embarassed

最后一个就是解决alt-tab的问题,这个问题说起来也简单,当alt-tab处理的时候隐藏IE窗口会触发document.onfocusout事件,在这个事件中对所有的popwindow 进行关闭即可,实际测试的时候,却发现如果不对IE窗口的内容进行点击操作(鼠标划过不算),不会使得document取得焦点,也就无法触发onfocusout事件,简单的做法是生成菜单之后调用一下document.focus()函数,这个函数可能会将焦点移动,所以不是很好,但是找不到解决的办法了 

没啥藏着掖着的,源代码下载test.rar (7.97 kb)

以下是测试代码,包含鼠标悬停、自动创建和右键菜单,详细请参考压缩包中的东西


<style type="text/css">
  #fm_MainContainer
  {
    width:100%;
    height:20px;
    border:solid menu 1px;
    background-color:ghostwhite;
    padding:3px;
    font-size:10pt;
    color:menu;
  }
  #fm_MainContainer a
  {
    padding-left:15px;
    padding-right:15px;
    border-left:solid 2px #104E8B;
    border-right:solid 1px #104E8B;
    text-decoration=none;
    color:blue;
    font-size:10pt;
    font-weight:bold;
    background-color:;
  }
  #fm_MainContainer a:hover
  {
    text-decoration=underline;
    color:red;
    background-color:yellow;
  }
  #fm_Container
  {
    background-color:#E8E8E8;
    height:19px;    
    cursor:hand;
    width:150;
    padding-right:3px;
    border-bottom:solid 1px menu;
    border-left:solid 5px #B0C4DE;    
  }
  #fm_Container a
  {
    padding-left:15px;
    padding-right:15px;
    font-size:10pt;
    text-decoration=none;
    color:blue;
    font-weight:normal;    
  }
  #fm_Container a:hover
  {
    text-decoration=underline;
    color:red;
    background: url(goto.png) no-repeat;
  }
</style>
<script type="text/javascript" src="../framemenu.js"></script>
<script type="text/javascript">
  //系统生成的菜单如果包含有下级菜单在菜单项的左边显示的图片
  FrameMenuConfig.FolderImage="leftbtn.png";
  //系统菜单生成的结构为<div ><a>...</a></div>,此处设置div的显示风格,a的显示风格请附带在div中设置
  FrameMenuConfig.CssPrefix="#fm_Container";
  //insert函数直接插入一格记录,格式为 父亲代码、节点代码、节点显示文本、节点URL、节点的目标框架,目标框架支持_self和_blank.
  FrameMenu.insert(null,"a","滚动规划");
  //add2函数插入一个菜单,返回这个菜单的父亲节点的实例,格式为 节点显示文本、节点URL、节点的目标框架,目标框架支持_self和_blank.节点的ID自动生成
  FrameMenu.insert(null,"b","立项管理").add2("立项1").add2("立项2");
  //add函数插入一个菜单,返回这个新的菜单的实例,格式为 节点显示文本、节点URL、节点的目标框架,目标框架支持_self和_blank.节点的ID自动生成
  FrameMenu.insert(null,"c","工程实施").add("工程实施1").add("工程实施1_1");
  FrameMenu.insert(null,"d","验收管理").add2("测试用例").add2("测试用例");
  FrameMenu.insert(null,null,"系统菜单").add2("用户管理").add2("测试用例").add2("测试用例").add("角色权限").add2("角色授权").add2("用户授权").add2("资源授权");
  FrameMenu.insert(null,null,"帮助系统").add2("关于本系统").add2("退出系统");
  FrameMenu.insert("a","a1","本地文件","localfile.htm","body");
  FrameMenu.insert("a","a12","新浪网(弹出窗口)","http://wwww.sina.com","_blank");
  FrameMenu.insert("a","a13","多级菜单");
  FrameMenu.insert("a13","a13_1","新浪网(本窗口)","http://www.sina.com","_self");
  FrameMenu.insert("a13","a13_2","新浪网(本窗口)","http://www.sina.com");
  FrameMenu.insert("a13","a13_3","新浪网(Body)","http://www.sina.com","body");
</script>
<body topmargin="0" leftmargin="0" oncontextmenu="FrameMenuConfig.showMenu();return false;">
  这个是TopFrame,Name=TopFrame
  <div id="fm_MainContainer">系统菜单是安排在这里滴,嘻嘻</div>
  <br/><button onmouseover="FrameMenuConfig.showMenu()">鼠标悬停方式显示完整菜单</button>
<script defer>
  FrameMenuConfig.createFrameMenu("fm_MainContainer",false);
</script>
</body>

 

posted @ 2007-11-14 09:41 Jeason 阅读(1503) | 评论 (4)编辑
我的BLOG搬家到自己的站点
站点链接
RSS

在处理前面的文章中的级联菜单的时候,我发现了一个有意思的现象,使用CreateELement/InnerHTML/document.write的表现各自不一,自己测试了一下,呵呵,算得总结一下
1、CreateELement
createElement生成一个动态对象,这个对象创建之后是个无主对象,没有加到创建它的document中,需要使用appendChild或者insertBefore插入到document的DOM模型中才能生效。
createElement函数依附于Document对象,在使用Frame、IFrame或者popupWindow的时候一定需要注意,一个Document创建的对象是不能直接复制到另外的一个document中,所以创建对象的时候一定要站好队,不要加入了一个对象死活找不到,哈哈。
createElement可以使用两种用法,第一种最常用,直接输入一个标签的名称进行创建(大小写不敏感),例如document.createElement("A"),这种方式下创建的对象是一个空壳子,需要自己去填写属性。另外一种方法就是使用一段脚本创建,例如document.createElement("<a href='www.sina.com'>"),这种方式下,属性被带入到了对象中,需要注意的是,无论使用何种方式创建,document的createElement函数只创建单层对象,不会创建嵌套对象,例如脚本document.createElement("<div><a/></Div>")只会创建外层的DIV对象,不会创建A,同理,在DOM模型中文本作为一个特殊的节点存在,实例脚本document.createElement("<div>SSSS</div>")不会创建文本节点"SSS",也就是说节点创建完成之后还是一个光秃秃的DIV。

2、write
这个函数就有点意思了,先看看IE的官方说明:

You should not use the write or writeln methods on the current document after the document has finished loading unless you first call the open method, which clears the current document's window and erases all variables.

这个函数在初始化的时候(文档没有最终生成的时候)会将文本信息如实写入到当前HTML的位置;但是初始化完成之后调用这个函数的时候则会清除掉当前的所有文档信息,看看实例

<b>OutterText</b><br/>
<script>
document.write("document.write:before init");
</script>
<b>InnerText</b><br/>

这个时候三段文本都可以正常显示,没有什么问题,但是我们试试在defer中调用

<b>OutterText</b><br/>
<script>
document.write("document.write:before init");
</script>
<b>InnerText</b><br/>
<script defer>
document.write("document.write:After init");
</script>

此时则只显示After Init这段文本,如文档所述,使用open函数可以避免将HTML的内容完全替代,结果我尝试了很多次,都是不行反倒频繁刷新当前页面,此处就不测试了。
我关心的是document在写入CSS和javascript的时候的表现
先测试的是写Javascript,看看能否实时生效,使用下面的脚本报错,原因是javascript的解析机制存在问题

<b>OutterText</b><br/>
<script>
document.write("<script>alert('aaa')</script>");
</script>
<b>InnerText</b><br/>

只好重新改改道路了

<b>OutterText</b><br/>
<script>
document.write("&lt;script&gt;alert('aaa')&lt;/script&gt;");
</script>
<b>InnerText</b><br/>

很遗憾,直接显示的是
<script>alert('aaa')</script>
也就是说,在document中write脚本是作为文本直接处理,那么CSS又如何?

<script>
document.write("<style>a{color:red;font-weight:bold;}</style>");
</script>
<a href='javascript:void(0)'>This is a Anchor!</a>

奇妙的事情发生了,这个时候CSS风格居然奏效了Embarassed
我还想测试一下在popwindow中的行为是否和在普通的document中一致

<script>
function testFun()
{
  var win=window.createPopup();
  win.document.write("&lt;script&gt;function fx(){alert();}&lt;/script&gt;");
  win.document.write("<a href='' onclick='fx();return false'>this is a anchor</a>");
  win.show(0,0,100,100);
}
</script>
<button onclick="testFun()">点偶试试</button>

果无二致!不能生成<script>到新的窗口中,同样CSS可以成功写入。

3、innerHTML

这个属性的作用不用明说了,还是测试能够写入javascript和CSS

<script>
function testFun()
{
    var x=document.getElementById("DIX");
    x.innerHTML="<style>a{color:red;font-weight:bold;}</style>"+
      "<a href='' onclick='fx();return false'>this is a anchor</a>";
}
</script>
<div id="DIX">
</div>
<button onclick="testFun()">点偶试试</button>

有些遗憾,CSS没有生效,同样,javascript页没有生效

测试表明,CSS的写入必须使用write方式,或者直接构造DOM对象方式,而javascript动态加入只能使用eval或者动态构造DOM对象方式,都不是一件轻松的活啊

4、document.createElement("script")
C盘下的atest.js的内容很简单

alert("偶被成功的加载鸟");
function fx()
{
  alert("处理点击事件");
}

测试脚本如下

<script>
function testFun()
{
  var win=window.createPopup();
  var x=win.document.createElement("script");
  x.src="c:\\atest.js";
  win.document.body.appendChild(x);
  win.document.write("<button onclick='fx()'>this is a anchor</button>");
  win.show(0,0,100,100);
  
}
</script>
<div id="DIX">
</div>
<button onclick="testFun()">点偶试试</button>
<button onclick='fx()'>this is a anchor</button>

上面一段代码运行之后点击"点偶试试",会加载atest到新的窗口中并弹出“偶被成功的加载鸟”消息,然后点击弹出窗口中的按钮则弹出“处理点击事件”,而实际上,“偶被成功的加载鸟”消息能够正常显示,而事件处理的消息没有显示,无论在主页面中点击还是弹出窗口中点击都无效,有些郁闷呢!

posted @ 2007-11-14 09:39 Jeason 阅读(853) | 评论 (1)编辑
我的BLOG搬家到自己的站点了,呵呵,这里可能还是不定期的更新相关软件开发的东东。最近在开发一套JAVA的报表系统,可能更新的概率小了,呵呵
站点链接
RSS
posted @ 2007-11-14 09:37 Jeason 阅读(52) | 评论 (0)编辑
  2007年10月21日

Syncfusion 的编辑器组件的确非常强悍,但是我拿到的5.1的Ent版本确不支持中文,输入的时候出现??,

尝试修改了一下基本满足要求

StreamEditControl.cs

函数protected void TextInsertInternal( int iLine, int iColumn, string str, bool update, bool bUseTabStops )
修改
if (m_wrapper.Encoding.GetMaxByteCount(1) == 1 && Encoding.Default.GetByteCount(str) > str.Length &&
      m_wrapper.Encoding.GetString( m_wrapper.Encoding.GetBytes( str ) ) != str)
     {
      ChangeEncoding( Encoding.Default );//强制转换成default的编码方式
     }

protected override void OnKeyPress( KeyPressEventArgs e )
if( !e.Handled )
     {
      ProcessAutoReplace( e.KeyChar );
      InsertChar( e.KeyChar );
      ProcessIntellisenseKey( e );
                        e.Handled = true;//增加本行,如果不增加则输入中文的时候会重复输入一次,寒
     } 

RegexTokenizer.cs
构造函数
public RegexTokenizer(Stream input)
        {
            m_reader = new StreamReader(input, Encoding.Default, true);     //这里最重要,否则什么都是白搭

修改之后没解决的问题

光标移动的时候会出现错位,暂时没办法解决,达人可以帮忙看看。

另外附上Syncfusion  Ent源码授权的取消方法

1、删除所有工程里面没有源代码的工程Core.
2、删除所有的Core的引用代码,大胆删除,没有任何作用

方法简单,但是操作非常繁琐,花一个下午才全部搞定,呵呵,的确不道德,自己玩玩可以,拿来商用被逮住自找,哈哈

hiddenLink
posted @ 2007-10-21 10:00 Jeason 阅读(231) | 评论 (0)编辑
  2007年8月1日

使用POI打开一个Excel的时候出现
RecordFormatException: java.lang.UnsupportedOperationException:错误,具体是查看源代码为org.apache.poi.hssf.record.formula.Ptg.java
原有代码为


            default :

                 //retval = new UnknownPtg();
                 throw new java.lang.UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+Integer.toHexString(( int ) id) + " (" + ( int ) id + ")");
        }

修改为
retval = new UnknownPtg();
                 //throw new java.lang.UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
                 //       Integer.toHexString(( int ) id) + " (" + ( int ) id + ")");

解决问题,但是治标不治本

posted @ 2007-08-01 20:48 Jeason 阅读(333) | 评论 (0)编辑
  2007年7月31日
按照官方文档
http://poi.apache.org/hssf/eval.html
上面的源代码
CellReference cellReference = new CellReference("B3");
HSSFRow row = sheet.getRow(cellReference.getRow());
HSSFCell cell = row.getCell(cellReference.getCol());
HSSFFormulaEvaluator.CellValue cellValue = evaluator.evaluate(cell);

得到百分之百是一个空指针错误,郁闷啊,查了半天,总算知道了

CellReference cellReference = new CellReference("B3");
HSSFRow row = sheet.getRow(cellReference.getRow());
HSSFCell cell = row.getCell(cellReference.getCol());
evaluator.setCurrentRow(row);
HSSFFormulaEvaluator.CellValue cellValue = evaluator.evaluate(cell);

就这么一行,靠,查了我半个小时,郁闷中
posted @ 2007-07-31 13:50 Jeason 阅读(329) | 评论 (0)编辑
  2007年7月30日

我个人不是很喜欢Hibernate,主要是它的配置文件实在令人烦躁,但是我不能用JDK1.5,所以我想找个简单的办法配置
问题1、Spring和Hibernate同时需要数据库链接,如何只配置一份?
       直接使用相同的配置信息文件,例如JDBC.Properties配置,Spring里面使用PropertyPlaceholderConfigurer配置Bean,而Hibernate则手工加载。
问题2、直接生成Hibernate HBM文件
      从Class文件直接生成、
初始化JDBC
 private void initJDBC()
        throws DocumentException,ResourceException,IOException
    {
        m_jdbcProperty.load(ResourceHelper.getResourceAsStream("cfg/jdbc.properties"));
        XMLHelper.each(new Node[]
                       {
                       cfg.Configuration.getInstance().getSystemNode(),
                       cfg.Configuration.getInstance().getModNode()
        },
            "hibernate/property",new IXMLNodeCallback()
        {
            public Object process(Node node)
                throws DocumentException
            {
                String strPropertyName = node.valueOf("@name");
                String strValue = node.valueOf("@value");
                if(strPropertyName != null && strPropertyName.trim().length() > 0)
                {
                    m_jdbcProperty.setProperty(strPropertyName,strValue);
                }
                return null;
            }
        });
    }
配置HBM信息
private String getHibernateMapXml(Node node)
    {
        String strClassName = node.valueOf("@name");
        String strTableName = node.valueOf("@table");
        String strPrimaryTableField = node.valueOf("@idfield");
        strPrimaryTableField = strPrimaryTableField == null || strPrimaryTableField.trim().length() < 1 ? null : strPrimaryTableField;
        if(strClassName == null
           || strTableName == null
           || strClassName.trim().length() < 1
           || strTableName.trim().length() < 1)
        {
            log.error("不能完成映射,配置的映射信息必须包含name和table属性");
            return null;
        }
        if(strPrimaryTableField == null)
        {
            log.error("不能完成映射,配置的映射信息" + strClassName + ">" + strTableName + "必须包含idfield属性");
            return null;
        }
        log.info("开始映射" + strClassName + ">" + strTableName);
        String strGenerator = node.valueOf("@idgenerator");
        String[] strInitMaps = node.valueOf("@map").split(";");
        StringHashtable mapClassField2Column = new StringHashtable();
        for(int n = 0;null != strInitMaps && n < strInitMaps.length;n++)
        {
            String[] m = strInitMaps[n].split(":");
            if(m.length > 1)
            {
                mapClassField2Column.put(m[0].trim().toUpperCase(),m[1].trim().toUpperCase());
            }
        }
        try
        {
            Class class2Map = Class.forName(strClassName);
            HBTable mapInfo = new HBTable(class2Map,strTableName);
            PropertyInfo pInfo = PropertyInfoFactory.getInstance().getPropertyInfo(class2Map);
            boolean bFoundPK = false;
            StringBuffer buf = new StringBuffer();
            StringCollection collFileds = pInfo.getFields();
            for(int n = 0;n < collFileds.size();n++)
            {
                String strFieldName = collFileds.elementAt(n);
                String strColumnName = mapClassField2Column.get(strFieldName.toUpperCase());
                if(null == strColumnName)
                {
                    strColumnName = strFieldName;
                }
                boolean isPK = strPrimaryTableField.equalsIgnoreCase(strColumnName) ||
                    strPrimaryTableField.equalsIgnoreCase(strFieldName);
                Class cls = pInfo.getFieldClass(strFieldName);
                if(null == cls || cls.isArray())
                {
                    throw new ConfigurationException("类" + class2Map.getName() +
                        "中找不到字段" + strFieldName + "或者其类型为数组类型");
                }
                Class clsClassFieldType = DataTypes.boxedClass(cls);
                mapInfo.addMap(strFieldName,strColumnName,isPK);
                if(isPK)
                {
                    bFoundPK = true;
                    String strID = ("<id name=\"" + strFieldName + "\" type=\"" + clsClassFieldType.getName() + "\">");
                    strID += ("<column name=\"" + strColumnName + "\" not-null=\"false\" />");
                    if(strGenerator != null && strGenerator.trim().length() > 0)
                    {
                        String strG = getGenerator(cls,strGenerator);
                        log.info(strTableName + "使用 " + strG + "作为 " + strColumnName + " 的自动生成参数");
                        strID += ("<generator class=\"" + strG + "\" />");
                    }
                    strID += ("</id>");
                    buf.insert(0,strID);
                }
                else
                {
                    buf.append("<property name=\"" + strFieldName + "\" type=\"" + clsClassFieldType.getName() + "\">");
                    buf.append("<column name=\"" + strColumnName + "\" not-null=\"false\" />");
                    buf.append("</property>");
                }
            }
            if(bFoundPK == false)
            {
                throw new ConfigurationException("配置中强制指定的idfield:" + strPrimaryTableField + "不存在");
            }
            if(buf.length() > 0)
            {
                buf.insert(0,"<class " +
                           "name=\"" + class2Map.getName() + "\" " +
                           "table=\"" + strTableName + "\" " +
                           "dynamic-update=\"true\" dynamic-insert=\"true\" >");
                buf.append("</class>");
            }
            m_hash.put(mapInfo.getMapClass(),mapInfo);
            return buf.toString();
        }
        catch(Exception excep)
        {
            log.error("映射" + strClassName + ">" + strTableName + "出现错误:" + excep.getMessage(),excep);
            return null;
        }
    }
private String getGenerator(Class cls,String str)
        throws ConfigurationException
    {
        if(null != str && str.length() > 0 && str.equals("#") == false)
        {
            return str;
        }
        DataTypes dt = DataTypes.fromClass(cls);
        if(dt.getId() == DataTypes.DOUBLE.getId() || dt.getId() == DataTypes.INT.getId())
        {
            return "increment";
        }
        else if(dt.getId() == DataTypes.STRING.getId())
        {
            return "uuid.hex";
        }
        else
        {
            throw new ConfigurationException("不能找到类型" + cls.getName() + "的默认生成器!");
        }
    }
完成HIBernate配置

private static void initHibernateConfig()
    {
        getInstance();
        if(null == sessionFactory)
        {
            synchronized(HibernateHelper.class)
            {
                if(null == sessionFactory)
                {
//    &nbs