﻿<?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>语源科技BlogJava-Tommy Jian 的博客</title><link>http://www.blogjava.net/tommyjian/</link><description>生活就是一个目标，接着一个目标。</description><language>zh-cn</language><lastBuildDate>Thu, 30 Apr 2026 06:24:12 GMT</lastBuildDate><pubDate>Thu, 30 Apr 2026 06:24:12 GMT</pubDate><ttl>60</ttl><item><title>NetBeans 6 Beta 1出来了！(转自Let's swing java博客）</title><link>http://www.blogjava.net/tommyjian/archive/2007/09/14/145034.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Fri, 14 Sep 2007 01:26:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/09/14/145034.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/145034.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/09/14/145034.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/145034.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/145034.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 本文转自Let's swing java，请到<a href="http://blogs.sun.com/Swing/">这里</a>查看详细情况。<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 我一直在用netbeans nightly build，因为netbeans 6 m10说实在的还是非常不稳定。今天按照惯例又去下载nightly build时，发现在milestone中已经包含了netbeans 6 beta 1的下载版本：
<p align="left"><a href="http://bits.netbeans.org/download/6.0/milestones/latest/">&nbsp;&nbsp;&nbsp; http://bits.netbeans.org/download/6.0/milestones/latest</a></p>
<p align="center"><img src="http://blogs.sun.com/Swing/resource/netbeans_6_beta_1.png" alt="" align="bottom" border="0" hspace="0" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以肯定的是，netbeans team准备在下周一正式向外界发布beta 1版本，但是他们的build已经出来了。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
netbeans最近越来越红火，不断传出好消息。netbeans ruby ide被众口一词的评价为目前最优秀的ruby
ide，netbeans 最近又从infoQ获得本年度的Bossie奖。大家对netbeans 6的评价尤其高，许多人在等待netbeans
6的正式发版。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这几天看的一个eclipse
fans的博客说，不得不承认netbeans的进步。最近他试用netbeans ruby
ide，对它评价是，唯一的不满意就是netbeans这个名字，因为bean这个名字老是使他想起使用weblogic时各种java
beans蜗牛般的速度。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 更有许多人因为netbeans的进步渐渐认识到java最近版本5和6的进步，更多的人正在转移到最新的java平台上来。这对java来说是个好消息，因为如果没有一个核心有竞争力的平台，java可能会重蹈linux当前四分五裂、一盘散沙的局面。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; netbeans注定会在2007的IDE世界留下最浓重的一笔。</p>
<p>----------------------------------------------------------------------------------------------------------------------------------------</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
刚刚试用了一下，就发现了一个令人激动的新功能，代码热替换(netbeans称作debug fix)。什么是代码热替换？如果你用过Visual
Age for
Java，你就很清楚了。就是调试时，往往单步跟踪到某处代码处发现了问题所在，也知道了怎么修改了。通常做法是停止程序，修改完代码后，再编译、运行、
调试单步跟踪到此处，这个过程非常消耗事件、浪费精力。而代码热替换允许你在发现问题时就直接修改源代码，然后apply code
change后，调试器就自动恢复到函数调用开始，重新执行新的代码，避免了重新编译、运行调试的过程。这个功能非常好，eclipse早期版本中的调试
器曾添加了这种功能，但是经常出错，后来干脆这个功能就取消了，不知道eclipse现在是否还有这个功能。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 就是下图这个按钮：</p>
<p align="center"><img src="http://blogs.sun.com/Swing/resource/hotswap.png" alt="" align="bottom" border="0" hspace="0" /></p>
<img src ="http://www.blogjava.net/tommyjian/aggbug/145034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-09-14 09:26 <a href="http://www.blogjava.net/tommyjian/archive/2007/09/14/145034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 2.0.9 GA版本发布</title><link>http://www.blogjava.net/tommyjian/archive/2007/07/25/132192.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Wed, 25 Jul 2007 00:22:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/07/25/132192.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/132192.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/07/25/132192.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/132192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/132192.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;此版本包含了OGNL安全问题的修正，因此建议开发者及时升级。可以到<a href="http://apache.ziply.com/struts/binaries/struts-2.0.9-all.zip">这里</a>下载。</p>
<p>&nbsp;&nbsp;&nbsp;关于这一版本的更新信息请参见<a  href="http://struts.apache.org/2.0.9/docs/release-notes-209.html">这里</a>。</p><img src ="http://www.blogjava.net/tommyjian/aggbug/132192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-07-25 08:22 <a href="http://www.blogjava.net/tommyjian/archive/2007/07/25/132192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：OpenOffice.org API介绍（三）</title><link>http://www.blogjava.net/tommyjian/archive/2007/07/18/131000.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Wed, 18 Jul 2007 03:37:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/07/18/131000.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/131000.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/07/18/131000.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/131000.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/131000.html</trackback:ping><description><![CDATA[<h3>&nbsp;&nbsp;3.3&nbsp; 数据的设置</h3>
<p>&nbsp;&nbsp;&nbsp;我们需要使用的有三种类型的数据。在开始之前，我们需要有个方法来获得对单元格的访问。这一节的其他辅助性方法也将使用此方法，定义如下：
</p>
<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;XCell&nbsp;getXCellByPosition(XSpreadsheet&nbsp;xSpreadsheet,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y)<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; return</span><span style="color: #000000;">&nbsp;xSpreadsheet.getCellByPosition(x,&nbsp;y);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;首先，我们将要接触到文本类型的数据，比如说Javalobby文章的标题。对于这种数据，辅助性方法需要电子表对象、列位置、行位置以及数据本身作为参数。
</p>
<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;">void</span><span style="color: #000000;">&nbsp;setTextValueOfXCellAtPosition(XSpreadsheet<br>&nbsp;&nbsp;&nbsp; xSpreadsheet,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y,&nbsp;String&nbsp;value)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">We&nbsp;first&nbsp;identify&nbsp;the&nbsp;cell&nbsp;we&nbsp;need&nbsp;to&nbsp;work&nbsp;with,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">using&nbsp;the&nbsp;incoming&nbsp;x&nbsp;and&nbsp;y&nbsp;values:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCell&nbsp;xCell&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;getXCellByPosition(xSpreadsheet,&nbsp;x,&nbsp;y);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Next,&nbsp;since&nbsp;we're&nbsp;working&nbsp;with&nbsp;text,&nbsp;we&nbsp;define<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">a&nbsp;text&nbsp;object&nbsp;and&nbsp;a&nbsp;cursor&nbsp;object&nbsp;and&nbsp;insert&nbsp;the&nbsp;received&nbsp;content&nbsp;into&nbsp;the&nbsp;cell:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XText&nbsp;xText&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(com.sun.star.text.XText)UnoRuntime.queryInterface(com.sun.<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; star.text.XText.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;xCell);<br>&nbsp;&nbsp;&nbsp; XTextCursor&nbsp;xTextCursor&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xText.createTextCursor();<br>&nbsp;&nbsp;&nbsp; xText.insertString(xTextCursor,&nbsp;value,&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;其次，对于数字类型的数据，比如说&#8220;Reply&#8221;列的数据，辅助性方法要求传递double类型的参数：
</p>
<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;">void</span><span style="color: #000000;">&nbsp;setNumValueOfXCellAtPosition(XSpreadsheet<br>&nbsp;&nbsp;&nbsp; xSpreadsheet,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y,&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;value)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">First&nbsp;we&nbsp;get&nbsp;the&nbsp;cell&nbsp;identified&nbsp;by&nbsp;the&nbsp;received&nbsp;x&nbsp;and&nbsp;y&nbsp;values:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCell&nbsp;xCell&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;getXCellByPosition(xSpreadsheet,&nbsp;x,&nbsp;y);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Then&nbsp;we&nbsp;add&nbsp;the&nbsp;received&nbsp;value&nbsp;to&nbsp;the&nbsp;identified&nbsp;cell:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCell.setValue(value);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;最后，尽管Calc的公式是普通的字符串，我们可以使用OpenOffice.org的API所包含的单元格样式属性来为单元格设置预定义的&#8220;Result&#8221;样式，这主要是针对我们汇总回复总数的计算公式来进行设置：
</p>
<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;">void</span><span style="color: #000000;">&nbsp;setFormulaOfXCellAtPosition(XSpreadsheet<br>&nbsp;&nbsp;&nbsp; xSpreadsheet,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y,&nbsp;String&nbsp;formula)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">We&nbsp;get&nbsp;the&nbsp;cell&nbsp;defined&nbsp;by&nbsp;the&nbsp;incoming&nbsp;x&nbsp;and&nbsp;y&nbsp;values"</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCell&nbsp;xCell&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;getXCellByPosition(xSpreadsheet,&nbsp;x,&nbsp;y);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">We&nbsp;add&nbsp;a&nbsp;Calc&nbsp;formula&nbsp;to&nbsp;the&nbsp;cell,&nbsp;as&nbsp;received&nbsp;by&nbsp;the&nbsp;helper&nbsp;method:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCell.setFormula(formula);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">We&nbsp;attach&nbsp;a&nbsp;property&nbsp;set&nbsp;to&nbsp;our&nbsp;cell,&nbsp;so&nbsp;that&nbsp;we&nbsp;can&nbsp;define&nbsp;a&nbsp;property:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XPropertySet&nbsp;xCellProps&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(XPropertySet)UnoRuntime.<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; queryInterface(XPropertySet.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;xCell);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">We&nbsp;set&nbsp;the&nbsp;style&nbsp;of&nbsp;the&nbsp;cell,&nbsp;using&nbsp;a&nbsp;predefined&nbsp;"Result"&nbsp;style,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">which&nbsp;comes&nbsp;out&nbsp;of&nbsp;the&nbsp;box&nbsp;with&nbsp;the&nbsp;OpenOffic.org&nbsp;API:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCellProps.setPropertyValue(</span><span style="color: #000000;">"</span><span style="color: #000000;">CellStyle</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Result</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>}<br></span></div>
<p>&nbsp;</p>
<h3>&nbsp;&nbsp;3.4&nbsp; 颜色的使用</h3>
<p>&nbsp;&nbsp;&nbsp;下面的代码将在随后被使用：
</p>
<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;">if</span><span style="color: #000000;">&nbsp;(position</span><span style="color: #000000;">%</span><span style="color: #000000;">2</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp; oooHelper.setColorRow(xSpreadsheet,&nbsp;position,&nbsp;</span><span style="color: #000000;">0xFF9933</span><span style="color: #000000;">);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;在ARGB颜色空间中，0xFF9933代表橙色。如果行数是偶数，那么电子表、行数以及橙色会被作为参数传递给方法：
</p>
<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;">void</span><span style="color: #000000;">&nbsp;setColorRow(XSpreadsheet<br>&nbsp;&nbsp;&nbsp; xSpreadsheet,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;row,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;color)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">First&nbsp;we&nbsp;get&nbsp;the&nbsp;range&nbsp;of&nbsp;cells&nbsp;we&nbsp;want&nbsp;to&nbsp;deal&nbsp;with,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">which&nbsp;is&nbsp;the&nbsp;whole&nbsp;spreadsheet:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCellRange&nbsp;xCellRange&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(XCellRange)UnoRuntime.queryInterface<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (&nbsp;XCellRange.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;xSpreadsheet&nbsp;);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Next,&nbsp;we&nbsp;narrow&nbsp;down&nbsp;our&nbsp;selection&nbsp;further,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">going&nbsp;from&nbsp;column&nbsp;0/current&nbsp;row&nbsp;to&nbsp;column&nbsp;3/current&nbsp;row,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">which&nbsp;is&nbsp;a&nbsp;whole&nbsp;row&nbsp;from&nbsp;left&nbsp;to&nbsp;right:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCellRange&nbsp;xSelectedCells&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xCellRange.getCellRangeByPosition(</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;row,&nbsp;</span><span style="color: #000000;">3</span><span style="color: #000000;">,&nbsp;row);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Next,&nbsp;we&nbsp;create&nbsp;a&nbsp;property&nbsp;set&nbsp;and&nbsp;assign&nbsp;it&nbsp;to&nbsp;our&nbsp;selected&nbsp;range:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XPropertySet&nbsp;xCellProps&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (XPropertySet)UnoRuntime.queryInterface(XPropertySet.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,xSelectedCells);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">This&nbsp;line&nbsp;sets&nbsp;the&nbsp;color&nbsp;to&nbsp;white,&nbsp;which&nbsp;basically<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">refreshes&nbsp;the&nbsp;row&nbsp;color&nbsp;before&nbsp;we&nbsp;add&nbsp;our&nbsp;new&nbsp;row&nbsp;color:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCellProps.setPropertyValue(</span><span style="color: #000000;">"</span><span style="color: #000000;">CellBackColor</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Integer(</span><span style="color: #000000;">16777215</span><span style="color: #000000;">));<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">This&nbsp;line&nbsp;sets&nbsp;the&nbsp;color&nbsp;to&nbsp;whatever&nbsp;is&nbsp;received,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">in&nbsp;this&nbsp;case&nbsp;orange:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCellProps.setPropertyValue(</span><span style="color: #000000;">"</span><span style="color: #000000;">CellBackColor</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Integer(color));<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;如果用户需要看到&#8220;Most Replies&#8221;或者&#8220;Least Replies&#8221;，我们将使用以下代码进行设置：
</p>
<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;">ooHelper.setColorCell(xSpreadsheet,&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">,&nbsp;jTable1.getRowCount()</span><span style="color: #000000;">+</span><span style="color: #000000;">5</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0x008000</span><span style="color: #000000;">);</span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;以下的方法需要电子表、列数、行数以及颜色值作为参数：
</p>
<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;">void</span><span style="color: #000000;">&nbsp;setColorCell(XSpreadsheet&nbsp;xSpreadsheet,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;column,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;row,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;color)<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">First,&nbsp;we&nbsp;select&nbsp;the&nbsp;entire&nbsp;received&nbsp;spreadsheet:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCellRange&nbsp;xCellRange&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(XCellRange)UnoRuntime.queryInterface(&nbsp;XCellRange.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; xSpreadsheet&nbsp;);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">From&nbsp;the&nbsp;received&nbsp;spreadsheet,&nbsp;we&nbsp;select&nbsp;a&nbsp;single&nbsp;cell,<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">defined&nbsp;by&nbsp;the&nbsp;row&nbsp;and&nbsp;column&nbsp;received:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XCellRange&nbsp;xSelectedCells&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xCellRange.getCellRangeByPosition(column,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; row,&nbsp;column,&nbsp;row);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">We&nbsp;define&nbsp;a&nbsp;property&nbsp;set,&nbsp;an&nbsp;object&nbsp;to&nbsp;contain&nbsp;the&nbsp;cell's&nbsp;properties:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XPropertySet&nbsp;xCellProps&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(XPropertySet)UnoRuntime.queryInterface<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (XPropertySet.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;xSelectedCells);<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">This&nbsp;line&nbsp;sets&nbsp;the&nbsp;color&nbsp;to&nbsp;white,&nbsp;to&nbsp;refresh&nbsp;the&nbsp;cell:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCellProps.setPropertyValue(</span><span style="color: #000000;">"</span><span style="color: #000000;">CellBackColor</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Integer(</span><span style="color: #000000;">16777215</span><span style="color: #000000;">));<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">This&nbsp;line&nbsp;sets&nbsp;the&nbsp;background&nbsp;color&nbsp;of&nbsp;the&nbsp;cell&nbsp;to&nbsp;whatever&nbsp;is&nbsp;received:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xCellProps.setPropertyValue(</span><span style="color: #000000;">"</span><span style="color: #000000;">CellBackColor</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Integer(color));<br>}<br></span></div>
<p>&nbsp;</p>
<hr>
<p><strong>本文译自NetBeans.org中的文章,其中的代码也都经过译者测试。未完待续！！！</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/131000.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-07-18 11:37 <a href="http://www.blogjava.net/tommyjian/archive/2007/07/18/131000.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：OpenOffice.org API介绍（二）</title><link>http://www.blogjava.net/tommyjian/archive/2007/07/16/130460.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Mon, 16 Jul 2007 00:07:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/07/16/130460.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/130460.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/07/16/130460.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/130460.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/130460.html</trackback:ping><description><![CDATA[<h3>&nbsp;&nbsp;3.2&nbsp; 电子表格文档的建立和加载</h3>
<p>&nbsp;&nbsp;&nbsp;上一节描述的方法帮助我们从服务管理器中获取了com.sun.star.frame.Desktop服务。Desktop可以根据给定的URL来加载新的或者已经存在的组件。为了提供这样的服务，Desktop实现了com.sun.star.frame.XcomponentLoader接口，这个接口只有一个方法根据给定的URL加载和实例化对应的组件。要构建一个新的电子表格文档组件，可以使用&#8220;private:factory/scalc&#8221;这样的URL。关于更详细的信息请参考OpenOffice.org开发指南《第8章&nbsp; 电子表格》中的8.2.1 &#8220;电子表格文档的建立和加载&#8221;。</p>
<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;XComponent&nbsp;getSpreadsheetComponent(Object&nbsp;desktop,&nbsp;String&nbsp;templateURL)<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp; XComponentLoader&nbsp;xComponentLoader&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;desktop);<br>&nbsp;&nbsp;&nbsp; PropertyValue[]&nbsp;pPropValues;<br>&nbsp;&nbsp;&nbsp; pPropValues&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;PropertyValue[</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; return</span><span style="color: #000000;">&nbsp;xComponentLoader.loadComponentFromURL(templateURL,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">_blank</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;pPropValues);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;下面这个方法将由用户界面所调用，在调用之前用户需要将必要的参数传递给上面代码中描述的方法：
</p>
<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;">XComponent&nbsp;xSpreadsheetComponent&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp; oooHelper.getSpreadsheetComponent(desktop,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">private:factory/scalc</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;接着，我们需要获取电子表格文档对象：
</p>
<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;XSpreadsheetDocument&nbsp;getXSpreadsheetDocument(XComponent&nbsp;xSpreadsheetComponent)&nbsp;<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; throws</span><span style="color: #000000;">&nbsp;Exception<br>{<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; return</span><span style="color: #000000;">(XSpreadsheetDocument)UnoRuntime.queryInterface<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (XSpreadsheetDocument.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;xSpreadsheetComponent);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;下一个定义的方法，getXSpreadsheet( )，定义如下，这个方法帮助我们精确定位要与哪个电子表格文档进行交互。默认情况下，Calc应用程序在启动的时候就已经建立好了三个电子表。这三个电子表的名称分别是&#8220;Sheet1&#8221;、&#8220;Sheet2&#8221;、&#8220;Sheet3&#8221;，这三个电子表会随着您启动Calc应用程序而打开。如果您将字符串&#8220;Sheet1&#8221;传递给getXSpreadsheet( )方法，那么接下来您所做的改动都将在&#8220;Sheet1&#8221;电子表中进行。然而，您或许想要给自定义的电子表起一个不同于默认命名方式的名字。比如说，您将电子表命名为&#8220;Javalobby Article
Analyzer&#8221;。如果您将这个名字作为参数传递给getXSpreadsheet( )方法，一个以此字符串命名的电子表将被构建。
</p>
<p>&nbsp;&nbsp;&nbsp;然而，默认情况下，叫&#8220;Sheet1&#8221;的电子表仍然是当前电子表，所谓当前电子表就是在应用程序启动时呈现在用户面前的那个电子表。无论您是否新建电子表，默认的三个电子表始终都是存在的。假如您想将您自己定义的电子表设为当前状态，您可以有两种选择。一种是使用在getXSpreadsheet( )方法之后定义的getXActiveSpreadsheet(
)方法，另外您可以直接将默认的三个电子表删除掉，就如下面的getXSpreadsheet( )方法中的一样，而一旦这三个电子表被删除之后也就只剩下您自定义的那个电子表了，所剩的最后一个电子表也就理所当然地成为当前电子表了。
</p>
<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;XSpreadsheet&nbsp;getXSpreadsheet(XSpreadsheetDocument&nbsp;xSpreadsheetDocument,&nbsp;String&nbsp;name)<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp; XSpreadsheets&nbsp;xSpreadsheets&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xSpreadsheetDocument.getSheets();<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">See&nbsp;section&nbsp;2.5.2&nbsp;of&nbsp;the&nbsp;OpenOffice.org&nbsp;API:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; xSpreadsheets.insertNewByName(name,&nbsp;(</span><span style="color: #0000ff;">short</span><span style="color: #000000;">)</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp; Object&nbsp;sheet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xSpreadsheets.getByName(name);<br>&nbsp;&nbsp;&nbsp; xSpreadsheets.removeByName(</span><span style="color: #000000;">"</span><span style="color: #000000;">Sheet1</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp; xSpreadsheets.removeByName(</span><span style="color: #000000;">"</span><span style="color: #000000;">Sheet2</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp; xSpreadsheets.removeByName(</span><span style="color: #000000;">"</span><span style="color: #000000;">Sheet3</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; return</span><span style="color: #000000;">&nbsp;(XSpreadsheet)UnoRuntime.queryInterface(XSpreadsheet.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;sheet);<br>}<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;接下来的方法是如何将电子表设为当前电子表：
</p>
<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;XSpreadsheet&nbsp;getXActiveSpreadsheet(XComponent&nbsp;xSpreadsheetComponent,<br>&nbsp;&nbsp;&nbsp; XSpreadsheet&nbsp;xSpreadsheet)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp; XModel&nbsp;xSpreadsheetModel&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(XModel)UnoRuntime.queryInterface(XModel.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; xSpreadsheetComponent);<br>&nbsp;&nbsp;&nbsp; XController&nbsp;xSpreadsheetController&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xSpreadsheetModel.getCurrentController();<br>&nbsp;&nbsp;&nbsp; XSpreadsheetView&nbsp;xSpreadsheetView&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(XSpreadsheetView)UnoRuntime.<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; queryInterface(XSpreadsheetView.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;xSpreadsheetController);<br>&nbsp;&nbsp;&nbsp; xSpreadsheetView.setActiveSheet(xSpreadsheet);<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; return</span><span style="color: #000000;">&nbsp;xSpreadsheet;<br>}<br></span></div>
<p>&nbsp;</p>
<hr>
<p><strong>本文译自NetBeans.org中的文章,其中的代码也都经过译者测试。未完待续！！！</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/130460.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-07-16 08:07 <a href="http://www.blogjava.net/tommyjian/archive/2007/07/16/130460.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：OpenOffice.org API介绍（一）</title><link>http://www.blogjava.net/tommyjian/archive/2007/07/12/129886.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Thu, 12 Jul 2007 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/07/12/129886.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/129886.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/07/12/129886.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/129886.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/129886.html</trackback:ping><description><![CDATA[<h3>1.引言</h3>
&nbsp;
<p>&nbsp;&nbsp;&nbsp;许多商业应用程序允许用户在应用程序中生成基于某些数据的报表。电子表格特别适合用于生成这样的报表。电子表格不仅可以将数据经格式化以后以结构化的形式展现给用户，而且为用户提供了快速且高效的数据处理功能。正如上面所说的，OpenOffice.org的API提供了大量的类和方法以方便开发者将OpenOffice.org电子表格的功能集成到他们自己的应用程序中。在应用程序中，单击某个按钮就可以启动OpenOffice.org并将应用程序生成的数据以自定义电子表格的形式展现出来。
</p>
<p>&nbsp;&nbsp;&nbsp;新手可能就这个开发领域很自然地提出一个问题：&#8220;一旦开发者正确地安装了所有需要的软件后，一个应用程序如何启动OpenOffice.org的新实例以及如何获取连接呢？&#8221;。这个问题得到了需要的回答之后，开发者还可能提出：&#8220;现在用户应用程序已经获取了OpenOffice.org的连接，那么应用程序应该如何将这些数据嵌入到电子表格中呢？&#8221;。在这篇文章中，我们将首先着重满足不熟悉OpenOffice.org的API的开发者的两个基本的需求。我们将向开发者展示如何获取到OpenOffice.org的连接，如何将应用程序的数据转化为电子表格形式的数据。接着我们将讨论一些其他的主题，这些主题包括以编程方式构建和析构电子表格、设置电子表格的单元格的背景颜色以及单元格边框的格式化。然而，这里需要注意的是我们只关注OpenOffice.org本身的集成，为了代码的可读性我们忽略了诸如错误处理之类的问题。在这篇文章的结尾，您将对OpenOffice.org的API处理电子表格和如何在您自己的应用程序中利用它们的相关知识有所了解。
</p>
<p>&nbsp;&nbsp;&nbsp;这篇文章涉及的应用程序是基于Swing的应用程序，它通过使用OpenOfiice.org的API来访问OpenOffice.org的各种功能。当然，您也可以使用C++或者COM/DCOM技术来连接OpenOffice.org。此类应用程序的代码并不一定必须基于Swing来编写。这样的应用程序可以使用C++、Java servlet、Java Server Page、JavaScript、VBScript、Delphi以及Visual Basic来编写。这篇文章中使用的基于Swing的应用程序将使用NetBeans IDE来构建，并且使用NetBeans Platform作为起始点。尽管任何集成开发工具都可以被用来构建如此简单的应用程序，但是使用NetBeans进行开发具有两项优势。首先，在NetBeans中我们可以充分发挥GUI构建器（即Matisse）的功能来构建用户界面，GUI构建器可以帮助我们快速建立应用程序界面的原型。其次，将我们的应用程序基于NetBeans Platform意味着我们不需要再重头开始，而且我们可以通过其提供的模块框架来增强应用程序的可扩展性。这个应用程序将生成如下图所示的不需要任何后期处理的电子表格文档：
</p>
<p style="text-align: center;"><img src="http://www.blogjava.net/images/blogjava_net/tommyjian/24065/o_intro-oo.jpg" border="0"></p>
<p>&nbsp;&nbsp;&nbsp;电子表格中的数据来自于JTable组件。在现实情况下，这些数据往往来源于数据库中。在上面述及的应用程序中，我们将把数据硬编码在程序代码中，这主要是因为数据的来源问题已经超出本篇文章的范围了。无论数据是否是来自于数据库，当用户已经完成了数据的处理后，应用程序将把JTable中的数据转换生成电子表格来呈现。除了数据之外，上面的图还展示了以下几个元素，这些元素将在下面的章节中述及：
</p>
<ul>
    <li>&nbsp;
    表头，电子表格有一行使用特殊颜色（深蓝色）标识的表头。
    </li>
    <li>&nbsp;
    行颜色的交错，电子表格中的其他行的颜色是交错的，有的背景色是桔色，而有的是白色。
    </li>
    <li>&nbsp;
    高或者低的回复，最后一列展示了某篇文章相关的回复数量，回复量比较高的行的背景颜色是绿色，而回复量比较低的行的背景颜色是红色，另外，在主表格的下方的两个单元格分别使用相同的颜色来标识高或者低回复文章的作者。
    </li>
    <li>&nbsp;
    回复的总数，&#8220;Reply&#8221;列的最后一行的下方的单元格显示了总回复数，这个单元格的格式与其他的单元格不太一样，总回复数是通过OpenOffice.org的API来使用Calc的公式计算得到的。
    </li>
    <li>
    电子表格名称，在上面图形的左下角，您可以看到&#8220;Javalobby Analysis&#8221;这样的名称，而您并没有看到Calc打开时的默认的电子表（名称为&#8220;Sheet1&#8221;、&#8220;Sheet2&#8221;、&#8220;Sheet3&#8221;），如下文所阐述的，电子表的名称的更改和默认电子表的移除都可以使用编程方式来实现。
    </li>
</ul>
<p>&nbsp;&nbsp;&nbsp;这篇文章被分为三部分，这三部分按顺序描述了开发的过程：
</p>
<ol>
    <li>&nbsp;  简化重复的编码任务，这一节中我们将了解OpenOffice.org的API中可复用的元素，而这些元素将在后面的章节中被集成到我们的应用程序中。
    </li>
    <li>建立用户界面原型，为了测试最后一节中的业务逻辑，我们将构建Swing应用程序的原型。
    </li>
    <li> 集成辅助性方法，应用程序的核心是将辅助性方法和用户界面集成起来，并且执行计算，生成电子表格。
    </li>
    <ol></ol>
    </ol>
    <h3>2.系统需求</h3>
    <p>&nbsp;&nbsp;&nbsp;在开始之前，请先确认以下的软件已经安装好了：
    </p>
    <ul>
        <li>OpenOffice.org，尽管这篇文章中的代码也兼容Star Office，但是因为我们使用OpenOffice.org的API相关的JAR文件，所以最好是安装OpenOffice.org。我们将使用在OpenOffice.org的安装目录下的四个JAR文件，您可以在OpenOffice.org
        2.0\program\classes文件夹中找到以下四个JAR文件：juh.jar、jurt.jar、ridl.jar和unoil.jar。
        </li>
        <li>NetBeans IDE，这篇文章关注的是OpenOffice.org的API，其中讨论的代码可以使用很多种编程语言描述，可以供多种语言编写的应用程序使用。如果您想构建这篇文章中描述的基于Swing的应用程序，您就需要去下载NetBeans 5.0或者更高的版本。
        </li>
    </ul>
    <p>&nbsp;&nbsp;&nbsp;注意：这篇文章中展现的应用场景并不需要使用OpenOffice.org SDK。如果我们要使用SDK中的idlc或者javamaker等工具，那么这个时候才需要SDK。
    </p>
    <h3>3.背景知识：简化重复的编码工作</h3>
    <p>&nbsp;&nbsp;&nbsp;当我们使用OpenOffice.org的API工作时，我们可能会重复地执行某些任务。比如说，我们设置电子表格表头的颜色，但是同时我们也需要设置其他各行的颜色。实际上，我们经常交替地设置各行的颜色，这样可以使得电子表格中的行更容易分辨。如果某篇文章的回复数比较高，我们会将对应的行设置为不同的颜色（绿色），而回复数比较低的行也被设置为不同的颜色（红色）。行的颜色的设置需要编写使用OpenOffice.org的API中的很多方法的几行代码，而为了避免重复编写相同的代码，我们将这些代码组织到一个辅助性方法当中去，在需要进行设置的时候，我们只需要将颜色作为参数传递就可以了。这可以使我们的代码易读性更好，更容易维护。下面我们将更详细地讨论这些辅助性方法。
    </p>
    <p>&nbsp;&nbsp;&nbsp;请记住，以下述及的辅助性方法可以用于任何应用程序，这些辅助性方法并不依赖于本篇文章里述及的应用程序。换句话说，您可以充分地利用这些辅助性方法，在需要的时候不需要对代码进行任何修改就可以将这些代码粘贴到应用程序的Java文件中使用。您也可以在您的代码中引用这些代码，就像这篇文章中做的一样。
    </p>
    <h3>&nbsp;&nbsp;3.1 使用引导程序</h3>
    <p>&nbsp;&nbsp;&nbsp;OpenOffice.org的Java API有自己的方法来引导OpenOffice.org。所谓&#8220;引导&#8221;OpenOffice.org，我们的意思是加载OpenOffice.org的启动程序。这通过寻找juh.jar文件所在的位置，然后在这个位置或者上一级目录查找soffice（.exe）来实现。这需要将juh.jar文件置于系统变量CLASSPATH所描述的目录中，这样本章构建的应用程序就可以访问到这个文件。然而，这里需要将juh.jar文件随同应用程序一起分发，这种情况下，这种引导机制就不奏效了。
    </p>
    <p>&nbsp;&nbsp;&nbsp;为了解决这个问题，有两种可能的方法。首先，可以确保Java随时都可以查找到soffice（.exe），这可以通过将包含可执行文件的目录加入到Windows的PATH系统变量中（在Mac、Unix和Linux中就是LD_LIBRARY_PATH系统变量）。这种方法需要用户进行一些操作，而我们并不希望这样做。
    </p>
    <p>&nbsp;&nbsp;&nbsp;因此，我们更倾向于推荐第二种方法，这种方法需要与访问修饰符协同工作。在Sun的JDK中，ClassLoader系统类是URLClassLoader类的实例。这个类有一个私有方法addURL，这个方法在Java系统开始的时候将被调用，从而将JAR文件以及其他相关资源添加到系统环境中。通过反射机制，我们获取一个URLClassLoader的实例，尔后使得addURL方法达到可访问状态，然后再将包含可执行文件的目录添加到URLClassLoader的URL栈中。这虽然显得很晦涩，但是这种方法很奏效。
    </p>
    <p>&nbsp;&nbsp;&nbsp;但是，它真的那么奏效吗？与系统类的访问修饰周旋总是一件冒险的事情。addURL方法被声明为protected型的，自然有其理由。另外，谁能保证使用的一定是Sun的JDK呢？或者Sun可能在随后的版本中忽略这个方法？然而，Java规范对上述这些事情并没有作出明确的声明，因此别的JDK在默认情况下并不是将ClassLoader类的类型配置为URLClassLoader。正是这个原因，我们使用&#8220;loader instanceof URLClassLoader&#8221;这样的检查代码来确保事情是如预期那样的。这也是我们在用户没有使用Sun的JDK的情况下确保应用程序没有任何异常情况而需付出的代价。
    </p>
    <p>&nbsp;&nbsp;&nbsp;关于过程中构建对象的更详细的信息请参考OpenOffice.org的开发指南《第6章&nbsp; Office开发》。
    </p>
    <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;Object&nbsp;simpleBootstrap(String&nbsp;pathToExecutable)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Get&nbsp;the&nbsp;executable&nbsp;from&nbsp;the&nbsp;incoming&nbsp;String:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ooBaseDirectory&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pathToExecutable.replaceAll(</span><span style="color: #000000;">"</span><span style="color: #000000;">soffice(.exe){0,1}$</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;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">Your&nbsp;ooBaseDir&nbsp;is:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;ooBaseDirectory);<br>&nbsp;&nbsp;&nbsp; ClassLoader&nbsp;loader&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ClassLoader.getSystemClassLoader();<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; if</span><span style="color: #000000;">&nbsp;(loader&nbsp;</span><span style="color: #0000ff;">instanceof</span><span style="color: #000000;">&nbsp;URLClassLoader){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; URLClassLoader&nbsp;cl&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(URLClassLoader)loader;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class&nbsp;sysclass&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;URLClassLoader.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try</span><span style="color: #000000;">&nbsp;{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Method&nbsp;method&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;sysclass.getDeclaredMethod<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (</span><span style="color: #000000;">"</span><span style="color: #000000;">addURL</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Class[]{URL.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">});<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; method.setAccessible(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; method.invoke(cl,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Object[]{</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;File(ooBaseDirectory).toURL()});<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(Throwable&nbsp;t)&nbsp;{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t.printStackTrace();<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;IOException(</span><span style="color: #000000;">"</span><span style="color: #000000;">Error,&nbsp;could&nbsp;not&nbsp;add&nbsp;URL&nbsp;to&nbsp;system&nbsp;classloader</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">Error&nbsp;occured,&nbsp;URLClassLoader&nbsp;expected&nbsp;but&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loader.getClass()&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;received.&nbsp;Could&nbsp;not&nbsp;continue.</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp; }<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Get&nbsp;the&nbsp;office&nbsp;component&nbsp;context:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XComponentContext&nbsp;xContext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Bootstrap.bootstrap();<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Get&nbsp;the&nbsp;office&nbsp;service&nbsp;manager:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; XMultiComponentFactory&nbsp;xServiceManager&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xContext.getServiceManager();<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">Create&nbsp;the&nbsp;desktop,&nbsp;which&nbsp;is&nbsp;the&nbsp;root&nbsp;frame&nbsp;of&nbsp;the<br></span><span style="color: #008000;">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000;">hierarchy&nbsp;of&nbsp;frames&nbsp;that&nbsp;contain&nbsp;viewable&nbsp;components:</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp; Object&nbsp;desktop&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;xServiceManager.createInstanceWithContext<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (</span><span style="color: #000000;">"</span><span style="color: #000000;">com.sun.star.frame.Desktop</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;xContext&nbsp;);<br></span><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; return</span><span style="color: #000000;">&nbsp;desktop;<br>}<br></span></div>
    <p>&nbsp;</p>
    <p>&nbsp;&nbsp;&nbsp;另一中方法就是使用远程连接。在远程连接中，服务器名称和端口号作为参数传递给远程连接方法，然后这个方法启动OpenOffice.org并返回Desktop对象，这个对象是利用OpenOffice.org工作的起点。而且在远程连接的情况下，您可以让用户选择服务器和端口，或者您可以在代码中使用系统设置来提供服务器和端口，这都看您的选择。
    </p>
    <hr>
    <p><strong>本文译自NetBeans.org中的文章,其中的代码也都经过译者测试。未完待续！！！</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/129886.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-07-12 17:36 <a href="http://www.blogjava.net/tommyjian/archive/2007/07/12/129886.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Wicket 1.3.0 BETA 2 发布了</title><link>http://www.blogjava.net/tommyjian/archive/2007/07/02/127417.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Mon, 02 Jul 2007 00:21:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/07/02/127417.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/127417.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/07/02/127417.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/127417.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/127417.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;Wicket项目已经从Apache孵化器毕业了，开发进度好像也加快了，这不1.3.0 BETA 2版本很快发布了，请看<a  href="http://wicket.sourceforge.net/">Wicket的官方站点</a>，可以到<a  href="http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta2/">这里</a>下载。</p><img src ="http://www.blogjava.net/tommyjian/aggbug/127417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-07-02 08:21 <a href="http://www.blogjava.net/tommyjian/archive/2007/07/02/127417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：iBATIS 3.0 草案——使用标注进行配置</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/29/127054.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Fri, 29 Jun 2007 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/29/127054.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/127054.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/29/127054.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/127054.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/127054.html</trackback:ping><description><![CDATA[<p><strong>使用标注进行配置</strong></p>
<p>&nbsp;&nbsp;&nbsp;标注现在已经很流行了，许多人选择它作为XML的替代来进行元数据编程。标注中不应该包含配置信息，而iBATIS通过XML来进行的工作也不光是配置。</p>
<p>&nbsp;&nbsp;&nbsp;那么什么是配置，什么又不是呢？目前，iBATIS的XML文件包含了三方面：</p>
<ul>
    <li>配置信息</li>
    <li>元数据信息</li>
    <li>代码</li>
</ul>
<p>&nbsp;&nbsp;&nbsp;当您把环境设置改变后，您同时也需要更改配置，例如数据库连接配置、事务管理配置等等。当您将应用分发到不同的数据库，而且也使用了一些专有的SQL语句后，配置中可能还要包含SQL方言的一些配置信息。在iBATIS 3.0中我们可以将这些信息包含进去，因此，您需要针对多种方言进行编码（当然这是手工的），为它们命名，并将它们配置到适当的位置。配置信息不应该被包含在Java源文件中。</p>
<p>&nbsp;&nbsp;&nbsp;元数据信息包括诸如结果映射、参数映射和缓存模型之类的信息。这些信息控制iBATIS如何映射您的数据以及这些映射的具体表现。</p>
<p>&nbsp;&nbsp;&nbsp;编码包括SQL以及动态的SQL语句。</p>
<p>&nbsp;&nbsp;&nbsp;那么标注应该承担什么样的职责呢？</p>
<p>&nbsp;&nbsp;&nbsp;一般情况下，只有元数据信息比较适合使用标注来描述。配置应该通过属性文件或者XML文件来实现。编码也只能通过Java文件或者XML文件来实现。更进一步看，标注只能用来描述相对较简单的元数据信息。有时，标注（特别是在Java中）也会使事情变得更加复杂，使代码更加晦涩难懂。</p>
<p>&nbsp;&nbsp;&nbsp;因为上面的原因，所以我推荐只将标注作为约定配置的替代配置。这就是说，使用这种配置方式可以达到一定的效果，但是也仅仅限于此。</p>
<p>&nbsp;&nbsp;&nbsp;再一次强调，C#的Attribute在某些方面要强于Java的标注：</p>
<ul>
    <li>支持多行字符串，这使得内嵌SQL编码令人感到愉快</li>
    <li>支持使用同一标注多次，而在Java中则需要通过集合标注来实现</li>
    <li>支持顺序和命名参数，这使得代码变得更加简明扼要</li>
</ul>
<p>&nbsp;&nbsp;&nbsp;下面这个例子展示了如何使用Java中的标注来完成配置：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">//<br>// Simple select, string concatenation, inline results(!) and inline parameters<br>//<br>@Select("SELECT #id(EMP_ID:NUMERIC), #firstName(FIRST_NAME:VARCHAR), #lastName(LAST_NAME:VARCHAR) " +<br>"FROM EMPLOYEE")<br>List<employee> selectAllEmployees();<br>//<br>// Alternative syntax using an array of strings instead of string concatenation...can be "smarter" than concatenation<br>//<br>@Select({"SELECT #id(EMP_ID:NUMERIC), #firstName(FIRST_NAME:VARCHAR), #lastName(LAST_NAME:VARCHAR) ",<br>"FROM EMPLOYEE",<br>"WHERE EMP_ID = @id"})<br>Employee selectEmployee(int id);<br>//<br>// Inserts look as you might expect. We can use getGeneratedKeys to get autogen key values, selectkey still supported<br>//<br>@Insert({"INSERT INTO EMPLOYEE (EMP_ID, FIRST_NAME, LAST_NAME)",<br>"VALUES (@id, @firstName, @lastName)"})<br>void insertEmployee(Employee emp);<br>//<br>// Nothing special about update<br>//<br>@Update({"UPDATE EMPLOYEE SET",<br>"EMP_ID=@id(NUMERIC:IN), FIRST_NAME=@firstName(VARCHAR:IN), LAST_NAME=@lastName(VARCHAR:IN)"})<br>void updateEmployee(Employee emp);<br>//<br>// Delete is obvious.<br>//<br>@Delete("DELETE EMPLOYEE WHERE EMP_ID = @id")<br>void deleteEmployee(int id);<br></employee></div>
<br>
<p>&nbsp;&nbsp;&nbsp;下面这个例子要更加复杂一些，像这种使用了如此多的标注的情况就应该考虑使用XML文件来进行配置。这种情况下，我想象标注能够提供一切功能，即XML中实现的功能通过标注也能完成。然而，我们还是建议您在面对复杂的情况时使用XML来进行配置。或许某些人不是特别在意使用XML配置，所以我们为他们提供了标注配置方式。</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">//<br>// complex stuff<br>//<br>@ResultClass (Company.class)<br>@ConstructorResults({<br>@Result(property="id", column="C.COMP_ID"),<br>@Result(property="name", column="C.NAME")<br>})<br>@PropertyResults({<br>@Result(property="departments.id", column="D.DEPT_ID"),<br>@Result(property="departments.name", column="D.NAME"),<br>@Result(property="departments.employee.id", column="E.EMP_ID"),<br>@Result(property="departments.employee.firstName", column="E.FIRST_NAME"),<br>@Result(property="departments.employee.lastName", column="E.LAST_NAME")<br>})<br>@Collections ({<br>@Collection(type=Department.class, property="departments", groupBy="id"),<br>@Collection(type=Employee.class, property="departments.employees", groupBy="departments.id")<br>})<br>@Select("SELECT #id, #name, " +<br>"#departments.id, #departments.name, " +<br>"#departments.employees.id, #departments.employees.firstName, " +<br>"#departments.employees.lastName " +<br>"FROM COMPANY C, DEPARTMENT D, EMPLOYEE E " +<br>"WHERE D.DEPT_ID = E.DEPT_ID " +<br>"AND C.COMP_ID = D.COMP_ID")<br>List<company> selectAllCompaniesWithJoin();<br>/*<br>* NESTED QUERIES<br>*/<br>@ResultClass (Company.class)<br>@FieldResults({<br>@Result(property="id", column="COMP_ID"),<br>@Result(property="name", column="NAME")<br>})<br>@PropertyResults({<br>@Result(property="departments",<br>nestedQuery=@QueryMethod(type=CompanyMapper.class, methodName="getDepartmentsForCompany", parameters="id"))<br>})<br>@Select("SELECT #id, #name FROM COMPANY C ")<br>List<company> selectAllCompaniesWithNestedQueries();<br>@ResultClass (Department.class)<br>@PropertyResults({<br>@Result(property="id", column="DEPT_ID"),<br>@Result(property="name", column="NAME"),<br>@Result(property="employees",<br>nestedQuery=@QueryMethod(type=CompanyMapper.class, methodName="getEmployeesForDeparment", parameters="id"))<br>})<br>@Select("SELECT #id, #name FROM DEPARTMENT WHERE COMP_ID = @id ")<br>List<department> getDepartmentsForCompany(int id);<br>@ResultClass (Employee.class)<br>@PropertyResults({<br>@Result(property="id", column="EMP_ID"),<br>@Result(property="firstName", column="FIRST_NAME"),<br>@Result(property="lastName", column="LAST_NAME")<br>})<br>@Select("SELECT #id, #firstName, #lastName FROM EMPLOYEE WHERE EMP_ID = @id ")<br>List<employee> getEmployeesForDepartment(int id);<br></employee></department></company></company></div><img src ="http://www.blogjava.net/tommyjian/aggbug/127054.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-29 13:35 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/29/127054.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：iBATIS 3.0 草案——约定俗成的配置方式</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/26/126256.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Tue, 26 Jun 2007 01:47:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/26/126256.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/126256.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/26/126256.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/126256.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/126256.html</trackback:ping><description><![CDATA[<p><strong>约定俗成</strong></p>
<p>&nbsp;&nbsp;&nbsp;<strong>Clinton说：</strong>这一点是与我们以前所坚持的原则不相符合的。认识我的人都知道我基本上算是一个完美的人。但是如果我们从最佳实践的角度去考虑，我们必须在解决复杂问题的时候也使用尽量简单的解决方案。当然，那些不太喜欢约定俗成式配置的人可以忽略这种配置方式。但是我相信这是非常有用的，特别是对插入、删除和更新操作来说。使用这种配置方式，一些简单的查询也将从中受益。</p>
<p>&nbsp;&nbsp;&nbsp;默认情况下，iBATIS 3.0将使用约定俗成式的配置方式。Java 5的方法语义中已经包含了生成SQL、进行参数和结果映射足够的信息。例如：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">Employee getEmployee (int id);</div>
<br>
<p>&nbsp;&nbsp;&nbsp;这些信息对于生成以下SQL已经足够了：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">SELECT id, firstName, lastName FROM Employee WHERE id = ?</div>
<br>
<p>&nbsp;&nbsp;&nbsp;结果类型与方法的返回值类型是一致的。因为方法的返回值类型不是集合类型，所以我们知道正在处理&#8220;Select One&#8221;语义。表的名称被假定为与结果类型的名称一致。而查询参数就被假定为方法对应的参数。在使用其他的配置方式的时候，我们可以更改默认ID参数的配置。SQL语句中的各数据列假定与方法返回类型的同名属性一一对应，当然这些配置都是可以更改的。</p>
<p>&nbsp;&nbsp;&nbsp;集合类型也是以同样的方式工作：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">List<employee> listAllEmployees ();</employee></div>
<br>
<p>&nbsp;&nbsp;&nbsp;这个例子将产生以下SQL语句：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">SELECT id, firstName, lastName FROM Employee</div>
<br>
<p>&nbsp;&nbsp;&nbsp;我们可以将这个例子叫做&#8220;Select Many&#8221;，因为这个方法返回了一个集合类型。我们知道Where子句为空，因为这个方法没有任何参数。</p>
<p>&nbsp;&nbsp;&nbsp;如果我们想使用参数式查询，我们可以这样来做：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">List<employee> findEmployeesLike(Employee employee);</employee></div>
<br>
<p>&nbsp;&nbsp;&nbsp;假设只有参数的lastName，而其他引用类型都为null值，原始类型都被设置为非法无意义的值（比如-1），我们将得到以下的SQL语句：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">SELECT id, firstName, lastName FROM Employee WHERE lastName = 'Begin'</div>
<br>
<p>&nbsp;&nbsp;&nbsp;或者可以直接按参数来进行：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">List<employee> findEmployeeByLastNameAndFirstName (String last, String first);</employee></div>
<br>
<p>&nbsp;&nbsp;&nbsp;这将生成以下的SQL语句：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">SELECT id, firstName, lastName FROM Employee WHERE lastName = 'Begin' AND firstName = 'Clinton'</div>
<br>
<p>&nbsp;&nbsp;&nbsp;因为C#支持参数名称的反射，所以C#对这种方法提供了更好的支持。形式上也变得相对清晰，当然实质是一样的：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">// C#<br>IList<employee> FindEmployeesLike(string lastName, string firstName);<br>// And in C# 3.0, we can use anonymous types:<br>IList<employee> FindEmployeesLike(object obj);<br>//...<br>IList<employee> employees = mapper.FindEmployeesLike(new {LastName="Begin", FirstName="Clinton"});<br></employee></employee></employee></div>
<br>
<p>&nbsp;&nbsp;&nbsp;更新操作也以相同的方式操作：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">void insertEmployee (Employee emp);<br>void updateEmployee (Employee emp);<br>void deleteEmployee (Employee emp);</div>
<br>
<p>&nbsp;&nbsp;&nbsp;也可以自动接受集合参数：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">int insertEmployee (List<employee> emps); // returns rows inserted<br>int updateEmployee (List<employee> emps); // returns rows updated<br>int deleteEmployee (List<employee> emps); // returns rows deleted</employee></employee></employee></div>
<br>
<p>&nbsp;&nbsp;&nbsp;生成器相当的灵活，而且可以为大多数删除甚至更新操作生成一条SQL语句。</p><img src ="http://www.blogjava.net/tommyjian/aggbug/126256.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-26 09:47 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/26/126256.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：iBATIS 3.0 草案——多种配置方式</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/22/125784.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Fri, 22 Jun 2007 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/22/125784.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/125784.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/22/125784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/125784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/125784.html</trackback:ping><description><![CDATA[<p><strong>多种配置方式</strong></p>
<p>&nbsp;&nbsp;&nbsp;iBATIS中最古老的就是其配置方式。在项目开始的时候，XML被认为最好的配置方式。事实上，XML现在还是比较好的配置方法，因为它是进行复杂的多行SQL配置的最佳方式。因此，XML的配置方式将予以保留。但是它不再是默认的配置方式，而且也不见得是大多数应用的首选。</p>
<p>&nbsp;&nbsp;&nbsp;iBATIS 3.0将使用多种配置方式。这就是说iBATIS将可以使用多种方式进行配置，而且这些方式可以协同工作。按照实用性排序，有以下四种方法：</p>
<ul>
    <li>约定俗成</li>
    <li>Java的标识（可以覆盖前一种配置的配置信息）</li>
    <li>XML（可以覆盖前两种配置的配置信息）</li>
    <li>Java API（可以覆盖以上配置的配置信息）</li>
</ul><img src ="http://www.blogjava.net/tommyjian/aggbug/125784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-22 11:23 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/22/125784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：iBATIS 3.0 草案——事务、会话和工厂类——MapperFactory</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/20/125358.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Wed, 20 Jun 2007 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/20/125358.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/125358.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/20/125358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/125358.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/125358.html</trackback:ping><description><![CDATA[<p><strong>事务、会话和工厂类——MapperFactory</strong></p>
<p>&nbsp;&nbsp;&nbsp;我们应该在何处获取&#8220;Mapper&#8221;的实例呢？我们仍然需要一个核心类来完成iBATIS的配置和控制。这个核心类的名称尚在争论之中，但是我们不妨先叫它MapperFactory。</p>
<p>&nbsp;&nbsp;&nbsp;通常情况下，MapperFactory负责构建事务和映射类的实例。而MapperFactory本身将由某个配置类来构建。</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">MapperFactory factory = someConfiguration.buildMapperFactory();<br>EmployeeMapper employeeMapper = factory.getMapper (EmployeeMapper.class);</div>
<p>&nbsp;&nbsp;&nbsp;对于这种方式是不是会使事情变得简单...或许会吧！至于事务，Clinton是这样说的：&#8220;会话的概念应该和事务的进行合并。在iBATIS中，会话和事务很多时候是一致甚至是一样的。但是它们因为一些人为的架构方面的原因而被分开了。会话或许能够完成不少任务，但是其中的80%并不适合用会话来解决。同样的，批处理操作也从事务中分离出来，因为事务在提供批处理功能是往往会导致令人生厌的try/finally的多重嵌套。因此在我们发现真实的需求之前应该尽量避免这些。&#8221;。</p>
<p>&nbsp;&nbsp;&nbsp;iBATIS或者其他第三方库及容器都可以进行事务处理。目前，事务的处理是由SqlMapClient实例中的ThreadLocal实例来处理的。因为这种处理方法，我们配到了不少问题。不是出于技术的原因而是因为代码更加清晰，我们可以使用以下的方法：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">Transaction tx = factory.startTransaction();<br>try <br>{<br>&nbsp;&nbsp;// do work<br>&nbsp;&nbsp;tx.commit();<br>}<br> finally<br> {<br>&nbsp;&nbsp;tx.end();<br>}</div>
<p>&nbsp;&nbsp;&nbsp;批处理操作可以简单地通过启动支持批处理操作的事务来进行：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">Transaction tx = factory.startBatch();<br>try <br>{<br>&nbsp;&nbsp;// do work<br>&nbsp;&nbsp;// balk executes current batch immediately, returns total rows updated<br>&nbsp;&nbsp;// (balks on non-batched transactions)<br>&nbsp;&nbsp;int totalRowCount = tx.flush();<br>&nbsp;&nbsp;// commit executes batch too, returns total rows updated and commits<br>&nbsp;&nbsp;totalRowCount = tx.commit();<br>} <br>finally<br> {<br>&nbsp;&nbsp;tx.end();<br>}</div>
<p>&nbsp;&nbsp;&nbsp;与现在的事务的API类似，我们对事务的隔离级别以及其他选项提供支持。</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">Transaction tx = factory.startTransaction(isolationLevel);<br>try <br>{<br>&nbsp;&nbsp;// do work<br>&nbsp;&nbsp;tx.commit();<br>}<br> finally<br> {<br>&nbsp;&nbsp;tx.end();<br>}</div>
<p>&nbsp;&nbsp;&nbsp;如果第三方的库提供了事务处理的支持，那么受托管理的连接对象可以作为参数传入：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">// Can be handled by encapsulating framework (e.g. Spring)<br>Transaction tx = factory.useConnection(conn);<br>try<br> {<br>&nbsp;&nbsp;//...do work...<br>&nbsp;&nbsp;tx.flush(); // executes batched updates immediately<br>&nbsp;&nbsp;// commit simply calls commit on the connection<br>&nbsp;&nbsp;// if local commits are allowed, otherwise it is ignored.<br>&nbsp;&nbsp;tx.commit();<br>}<br> finally<br> {<br>&nbsp;&nbsp;tx.end(); // Can also be handled by encapsulating framework (e.g. Spring)<br>}</div>
<p>&nbsp;&nbsp;&nbsp;总之，这样的API十分的简洁，而且易于与诸如Spring这样的第三方框架集成。MapperFactory可以被注入到需要事务管理、批处理和隔离级别的Spring的DAO对象中。为了进一步进行必要的分离，我们可以将事务管理功能从MapperFactory中分离出来，甚至于允许开发者定义自己的事务管理接口，同时将事务管理的功能绑定到类中（这样提供了更加松耦合的架构）。</p><img src ="http://www.blogjava.net/tommyjian/aggbug/125358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-20 16:00 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/20/125358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：iBATIS 3.0 草案——接口绑定</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/19/125161.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Tue, 19 Jun 2007 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/19/125161.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/125161.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/19/125161.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/125161.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/125161.html</trackback:ping><description><![CDATA[<p><strong>接口绑定</strong></p>
<p>&nbsp;&nbsp;&nbsp;随着Java 5的推广，我们有机会来改善用户体验。其中最重要的是借助Java 5可以消除令人生惑的类型转换，可以消除SQL映射基于字符的调用方式。举例来说，现在在调用SQL映射的时候是这样的：</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">Employee employee = (Employee)sqlMapper.queryForList("getEmployee", 5);<br>//...and...<br>List employees = sqlMapper.queryForList("listAllEmployees");</div>
<p>&nbsp;&nbsp;&nbsp;问题是很明显的。第一，上面的两个例子中被映射的语句的名称都是基于字符串的，而这很容易导致错误。这种方式也不会得到IDE工具、编译器的支持和管理。</p>
<p>&nbsp;&nbsp;&nbsp;第二个问题是存在参数和返回值类型安全问题。在第一个例子中，谁能保证参数的类型一定是Integer？而谁又能保证您得到的返回值一定是Employee类型呢？这里，编译器也不会给出任何偿错误报告和提示。而只有运行时异常会被抛出。</p>
<p>&nbsp;&nbsp;&nbsp;最后，在集合的例子中问题也是相同的。在运行前，您可能会获得Dogs的集合，而不是Employees。</p>
<p>&nbsp;&nbsp;&nbsp;总之，这种方式虽然比JDBC强，但是也让人倍感难受，还是存在改善的空间。</p>
<p>&nbsp;&nbsp;&nbsp;在Java 5中我们可以充分使用范型来规范集合类型。这样，我们不需要进行特殊的配置就可以为集合类型建立一致的API。我们不需要在XML文件中声明类型，不需要通过字符名称来调用被映射的语句，相反，我们可以充分利用表达好且类型安全的接口类型。没有什么新东西需要学习，只是普通的接口就可以了。</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">public interface EmployeeMapper <br>{&nbsp; <br>&nbsp;&nbsp;Employee getEmployee (int employeeId);&nbsp; <br>&nbsp;&nbsp;List<employee> listAllEmployees();<br>}</employee></div>
<p>&nbsp;&nbsp;&nbsp;这就够了！iBATIS来帮我们实现这个接口。</p>
<p>&nbsp;&nbsp;&nbsp;现在我们可以以一种更加简洁和安全的方式来调用被映射的语句了。</p>
<div style="border: 2px dotted ; background-color: #99ccff; font-family: Courier New,Courier; font-size: small;">Employee emp = empMapper.getEmployee(5);<br>//...and...<br>List<employee> employees = empMapper.listAllEmployees();</employee></div>
<p>&nbsp;&nbsp;&nbsp;在上面的调用中没有类型转换、没有字符串，而且参数和返回值的类型是、安全的。额外的代码就是针对接口使用XML或者Java的标识进行配置。最多我们只需要配置SQL语句、需要进行重载的参数或者返回值类型。</p>
<p>&nbsp;&nbsp;&nbsp;接口描述了所需要的一切。</p>
<ul>
    <li>语句的名称（默认情况下与方法的名字一致）</li>
    <li>参数类型（如果存在的话）</li>
    <li>返回值类型（包括范型集合的元素的类型）</li>
</ul>
<p>&nbsp;&nbsp;&nbsp;而其中最有趣的就是我们可以基于方法名称这样的约定来生成SQL映射。以后关于配置的章节中将详细讨论这些细节。</p>
<p>&nbsp;&nbsp;&nbsp;接口绑定的方法使得诸如Spring这样的框架将映射类注入其他类变得容易，同时也不需要将事务管理的过多细节公开。</p><img src ="http://www.blogjava.net/tommyjian/aggbug/125161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-19 17:40 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/19/125161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iBATIS 发布其文档的多国语言版本</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/19/125032.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Tue, 19 Jun 2007 00:16:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/19/125032.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/125032.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/19/125032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/125032.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/125032.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;
&nbsp;本来还打算翻译一下iBATIS开发指南等相关文档，不过看来已经有兄弟做了这个工作了。<br></p>
<p>&nbsp;&nbsp;&nbsp; iBATIS
开发团队在6月12日发布了其文档的多国语言版本，包括中、日、韩及其他几个语言的翻译版本。可以到以下链接下载这些文档：</p>
<p>&nbsp;&nbsp;&nbsp;<a href="http://ibatis.apache.org/javadownloads.cgi" title="http://ibatis.apache.org/javadownloads.cgi">http://ibatis.apache.org/javadownloads.cgi</a></p><img src ="http://www.blogjava.net/tommyjian/aggbug/125032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-19 08:16 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/19/125032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ice Connections 24号发布</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/18/124881.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Mon, 18 Jun 2007 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/18/124881.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/124881.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/18/124881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/124881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/124881.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;Ice Connections 24号发布，可以到以下的地址下载：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.zeroc.com/newsletter/issue24.pdf" target="_blank">http://www.zeroc.com/newsletter/issue24.pdf</a></p>
<p>&nbsp;&nbsp;&nbsp; 目录如下：</p>
<ul>
    <li>编者的话：多样</li>
    <li>超越Freeze：Ice中的持久化</li>
    <li>Ice中的连接管理</li>
</ul><img src ="http://www.blogjava.net/tommyjian/aggbug/124881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-18 09:41 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/18/124881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 2.0.8 GA版本发布</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/14/124211.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Thu, 14 Jun 2007 00:33:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/14/124211.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/124211.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/14/124211.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/124211.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/124211.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 距 2.0.6 GA 版本发布没有多长时间，现在Struts 2.0.8 GA版本也发布了，可以到<a href="http://struts.apache.org/download.cgi#struts206">这里</a>下载。</p>
<p>&nbsp;&nbsp;&nbsp; 关于这一版本的更新信息请参见<a href="http://struts.apache.org/2.x/docs/release-notes-208.html">这里</a>。</p><img src ="http://www.blogjava.net/tommyjian/aggbug/124211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-14 08:33 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/14/124211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：为什么是Wicket（All In One）</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/10/123202.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Sun, 10 Jun 2007 08:49:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/10/123202.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/123202.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/10/123202.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/123202.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/123202.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;这两天把Jonathan Locke编写的《Why Wikcet?》，今天把四部分汇总集中以下方便大家的阅读，下面是这四部分译文的链接地址：&nbsp;</p>
&nbsp;
<ol>
    <li><a href="http://www.blogjava.net/tommyjian/archive/2007/06/07/122485.html"> 翻译：为什么是Wicket（一）</a></li>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;
    <li><a href="http://www.blogjava.net/tommyjian/archive/2007/06/07/122641.html"> 翻译：为什么是Wicket（二）</a></li>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;
    <li><a href="http://www.blogjava.net/tommyjian/archive/2007/06/08/122756.html"> 翻译：为什么是Wicket（三）</a></li>
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;
    <li><a href="http://www.blogjava.net/tommyjian/archive/2007/06/08/122818.html"> 翻译：为什么是Wicket（四）</a></li>
    &nbsp;&nbsp; &nbsp;</ol>
    <p>&nbsp;&nbsp;&nbsp;在网上寻了半天，已经有兄弟就Wikcet做了很多工作，请到<a href="http://gocom.primeton.com/modules/newbb/viewforum41.htm">这里</a>看看。</p>
    <p>&nbsp;&nbsp;&nbsp;因为链接地址还是以前保存的，今天试了试好像总是出错，所以索性就把下载得到的《Wikcet 开发指南》上载来和大家分享共勉吧！不过，相关权利都属于此文档的译者，大家都只作为学习之用就好了，下面是分卷文件的下载地址：</p>
    <ol>
        <li><a href="http://www.blogjava.net/Files/tommyjian/Wicket%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97.part1.rar">《Wikcet 开发指南》分卷一</a></li>
        <li><a href="http://www.blogjava.net/Files/tommyjian/Wicket%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97.part2.rar">《Wikcet 开发指南》分卷二</a></li>
    </ol><img src ="http://www.blogjava.net/tommyjian/aggbug/123202.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-10 16:49 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/10/123202.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：为什么是Wicket（四）</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/08/122818.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Fri, 08 Jun 2007 04:35:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/08/122818.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/122818.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/08/122818.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/122818.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/122818.html</trackback:ping><description><![CDATA[<p><strong>目标</strong></p>
<p>基于上面的这些动机，下面是Wicket的目标：</p>
<ol>
    <li>简单（易用性、一致性、易懂性）</li>
    <ul>
        <li>&nbsp; 以POJO为核心</li>
        <li>所有代码均使用Java编写</li>
        <li> 最小的概念域</li>
        <li>避免过度地使用XML配置文件</li>
        <li>全面解决&#8220;向后按钮&#8221;问题</li>
        <li> 最大限度地类型安全以及编译检查</li>
        <li> 最大限度地分析运行时错误</li>
        <li>对特定工具集的最小依赖</li>
        <li>组件、容器和惯例始终保持一致性</li>
    </ul>
    <li>复用</li>
    <ul>
        <li>使用Wicket编制的组件具备高度的复用性</li>
        <li> 可复用的组件可以使用JAR文件发布</li>
    </ul>
    <li>无侵入</li>
    <ul>
        <li> HTML以及其他标记性文件不会编程语法所干涉</li>
        <li> 在标记方面只有一个简单的标签</li>
        <li>&nbsp; 与任何普通的HTML编辑器兼容</li>
        <li>&nbsp; 图形开发人员很容易识别并避免修改框架标签</li>
        <li>&nbsp; 如果设计者不小心删除了标签，则很容易恢复它</li>
    </ul>
    <li> 安全</li>
    <ul>
        <li> 默认情况下代码都是安全的</li>
        <li>在页面和URL中，只有显式的声明的链接才能公布数据状态</li>
        <li>具备最大限度类型安全逻辑</li>
        <li>很容易集成到Java安全框架</li>
    </ul>
    <li>富有效率，可伸缩性</li>
    <ul>
        <li>在不牺牲其他目标的前提下保证效率和轻量级</li>
        <li> 可依附的优选会话期支持集群</li>
        <li>通过与可分离模型的协作，会话复制形成的集群很容易实现和调整</li>
    </ul>
    <li>完整</li>
    <ul>
        <li> Wicket团队乐于为开发Java Web应用贡献可用的且特性齐全的框架。核心框架是由本篇文档的作者Jonathan Locke编写和贡献的。目前的团队包括了很多经验丰富的程序员，他们中的一些人还是上面提及的其他框架的开发者，他们也都拥有构建大型Java Web应用的经验。我们对自己的处境十分的了解，因此也更能从框架使用者的角度来开发Wicket。</li>
    </ul>
</ol>
<hr>
<p><strong>注：本文由Jonathan Locke编写,相关权利由原作者享有。</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/122818.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-08 12:35 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/08/122818.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：为什么是Wicket（三）</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/08/122756.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Thu, 07 Jun 2007 23:55:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/08/122756.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/122756.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/08/122756.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/122756.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/122756.html</trackback:ping><description><![CDATA[<p><strong>大部分现存的框架需要特定的HTML代码</strong></p>
<p>&nbsp;&nbsp;&nbsp; JSP具有最深的侵入性，它允许将Java代码直接嵌入Web页面中。但是，上面列示的框架（除了Tapestry）都不同程度地针对HTML代码引入了特殊的语法。</p>
<p>&nbsp;&nbsp;&nbsp; 因为特殊语法改变了单纯而简单的HTML标记的实质，而Web设计者对于这一点是十分的熟悉，所以特殊语法并不是十分得人心。而且预览、编辑和理解这种包含特殊语法的HTML也是十分困难的事情。</p>
<p>&nbsp;&nbsp;&nbsp; Wicket并没引入任何新的HTML语法。相反，它通过Wicket命名空间（namespace）的标准兼容方式扩展了HTML，这完全兼容XHTML标准。这意味这您可以使用Macromedia Dreamweaver、Microsoft Frontpage、Word、Adobe Go Live以及其他现有的HTML编辑器来编辑您的Web页面，并且可以和Wicket的组件协同工作。为了实现这个目标，Wicket始终在Wicket命名空间内使用单个id属性（&#8220;wicket:id&#8221;）来标识那些需要框架进行特殊处理的标签。如果您并不喜欢将有Wicket命名空间修饰的标签和属性展示给您的最终用户，通过简单的设置就可以完全消除它们，从而得到普通的与标准兼容的HTML代码。</p>
<p>&nbsp;&nbsp;&nbsp; HTML中没有特殊的语法意味着设计者可以直接模拟页面，而您可以在开发的过程中直接使用这些页面。向HTML页面中添加Java组件就和设置组件的名称属性一样简单。然后，您可以直接将这些页面交给Web设计人员，他们可以充满信心地对其进行修改。</p>
<p>&nbsp;&nbsp;&nbsp; 与其他的应用框架相比，Wicket在各方面的分离上提供更多的支持。Web设计者在对应用程序代码不甚了解的情况下就可以编辑HTML（当然，他们不能移除组件名称标签，而且不能任意改变组件嵌套的层次，其他的事情都是可以的）。另一方面，编程者只需要关注与HTML混在一起的Java组件，而不需要了解页面的最终陈现是什么样子。通过这种职能清楚的工作方式，每个人都可以工作得更为顺畅。</p>
<p><strong>现存的框架易用性不好</strong></p>
<p>&nbsp;&nbsp;&nbsp; 目前存在的大部分框架工具在对象模型方面做得不够。在一些框架中，对象模型是通过特定的XML来定义的。这些语法令人生厌，而且还需要特定的工具来编辑这些配置信息。由于这些框架并不是单一的Java类库，您就不能使用包含编辑器、调试器和编译器的IDE工具来编辑它们。</p>
<p>&nbsp;&nbsp;&nbsp; Wicket是化繁为简的代表。在学习Wicket的过程中不需要了解任何配置文件。Wicket就是组件结构良好的普通的类库。在Wicket中，您的Web应用程序与普通的Swing应用程序类似，而不是JSP应用程序。如果您熟悉Java（特别是如果您熟悉Swing），那么您就已经对Wicket有不少的了解了。</p>
<p><strong>现存的框架可复用性不好</strong></p>
<p>&nbsp;&nbsp;&nbsp; Tapestry和JSF虽然有可以重用的组件模型，但是您将发现与Wicket相比这并不是特别容易做到的事情。Wicket从设计之初就十分地注重组件的复用。在Wicket中，从现有的组件扩展编制诸如SignInPanel或者AddressForm的复合组件是十分简单的事情。相对来说，针对浏览器的新特性编制新的组件也是十分容易的事情。Wicket的组件可以使用JAR格式进行打包，直接通过库引用的方式就可以实现重用——不需要任何配置文件！</p>
<p>&nbsp;&nbsp;&nbsp; Web编程应该更关注编程乐趣！</p>
<p>&nbsp;&nbsp;&nbsp; 这就是我编写Wicket的个人方面的目标。现存的框架在实现开发的直接性、快捷性和简易性方面真正地吸引我。我希望Wicket在Web应用程序开发的建议性和乐趣方面能够迈出重要的一步。</p>
<hr>
<p><strong>&nbsp;&nbsp;&nbsp; 注：本文由Jonathan Locke编写,相关权利由原作者享有。</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/122756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-08 07:55 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/08/122756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：为什么是Wicket（二）</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/07/122641.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Thu, 07 Jun 2007 08:47:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/07/122641.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/122641.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/07/122641.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/122641.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/122641.html</trackback:ping><description><![CDATA[<p><strong>动机</strong></p>
<p>&nbsp;&nbsp;&nbsp; 目前存在的大多数Web框架对于服务端的状态管理都仅仅提供了较弱的支持。</p>
<p>&nbsp;&nbsp;&nbsp; 这就意味着在Web应用程序中存在着很多特殊的代码来处理和维护繁复的状态管理机制。虽然Wicket并不允许对服务端的状态完全不考虑，但是它在状态管理的简便性和透明化方面做了很多的工作。</p>
<p>&nbsp;&nbsp;&nbsp; 在Wicket中，所有服务端的状态都被纳入了自动的管理。您始终不需要直接使用HttpSession对象或者类似的封装对象去存储状态信息。相反，状态信息已经都与组件关联起来，而在组件后端的数据模型都是传统的Java对象（POJO）。Wicket在每个用户会话期内维护着页面的映射表（Map）。这个页面映射表（以及每个一面内的组件层次）的目的在于使得框架隐藏了组件以及数据模型访问的细节。您只需要处理简单而熟悉的Java对象，而Wicket则处理诸如URL、会话期标识以及GET/POST请求的任务。</p>
<p>&nbsp;&nbsp;&nbsp; 您接着也会发现这种结构良好的服务端状态使得解决令人恐惧的&#8220;后退按钮问题&#8221;变得十分的容易。实际上，针对页面内组件数据模型的结构性变化带来的数据过期，Wicket提供了通用而且健壮的解决方案，这个方案可以有效地对浏览器缓存页面进行甄别和过期检测。</p>
<p>&nbsp;&nbsp;&nbsp; 最后，Wicket在设计的时候就考虑与诸如JDO和Hibernate的普通Java对象（POJO）序列化框架协同工作。这一点使得构建数据驱动的Web应用程序显得非常简单。</p>
<p>&nbsp;&nbsp;&nbsp; 对于很多应用程序来说，必须在额外服务端状态导致服务器负载增加和其带来的好处之间进行权衡，服务端状态管理可以降低开发成本、减少维护成本、加快对市场的响应时间以及生产高质量的软件。这里提出的基本观点是：软件是十分昂贵、复杂的，而来自于E-machines和Dell的服务器则相对便宜。</p>
<p>&nbsp;&nbsp;&nbsp; 在效率和生产性方面，Wicket对JSP的优越性则犹如Java语言对C语言一样。您使用Wicket可以实现的功能使用JSP也都可以实现。甚至于在内存和CPU消耗方面效率也非常的高。但是使用JSP开发应用程序则需要耗费您更多的时间。最后，因为在JSP中进行状态管理时使用了特别的方式，您可能发现不少的安全问题，也能看到到处蹦出来的错误。上面提及的大部分框架在这方面仅仅提供了有限的辅助。</p>
<hr>
<p><strong>&nbsp;&nbsp;&nbsp; 注：本文由Jonathan Locke编写,相关权利由原作者承担。</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/122641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-07 16:47 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/07/122641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：为什么是Wicket（一）</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/07/122485.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Wed, 06 Jun 2007 23:51:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/07/122485.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/122485.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/07/122485.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/122485.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/122485.html</trackback:ping><description><![CDATA[<p><strong>为什么是Wicket？</strong></p>
<p>&nbsp;&nbsp;&nbsp; 如果您正在寻求使用Java开发Web应用程序，目前，您有很多的选择。实际上，存在如此众多的Web应用程序框架显得有点搞笑。来自于互联网一个博客站点的问题：您能说出多少Java Web应用框架的名字？他们展现的结果如下：</p>
<p>&nbsp;&nbsp;&nbsp; 框架，到处都是框架，参看后面附带的表格。</p>
<p><strong>为什么要&#8220;重新发明轮子&#8221;？</strong></p>
<p>&nbsp;&nbsp;&nbsp; 从这个角度看，您对于&#8220;另一个Web应用程序框架有多好&#8221;这个问题总是耿耿于怀？确实，为什们要&#8220;重新发明轮子&#8221;呢？对这个古老的谚语的答复是：因为这一次可以使轮子更圆！</p>
<p>&nbsp;&nbsp;&nbsp; 但是对于高质量的期待并不是构建Wicket框架的唯一动因。甚至有很多的观点，认为没有其他的Web工具集填补这一空白，而Wicket做到了。实际上，Wicket与上面提及的众多框架不太一样。</p>
<p>&nbsp;&nbsp;&nbsp; 与Wicket最相近的或许是Tapestry和Echo，但是这种相似性也很有限。和Tapestry一样，Wicket使用特定的HTML属性来标识组件（Components）声明，这可以方便使用一般的HTML编辑器进行文件编辑。和Echo一样，Wicket拥有一流的组件模型。但是基于Wicket的应用程序和那些基于Tapestry和Echo的应用程序不一样，这是因为从Wicket框架中两方面都可以受益。您获得了一流的组件模型和对HTML没有干扰所带来的益处。在很多情况下，这种复合的好处可以带来非常重要的开发优势。</p>
<p>&nbsp;&nbsp;&nbsp; 理解了构建Wicket的动机有助于您理解为什么Wicket会表现的不一样。</p>
<div algign="center">
<table style="width: 480px; height: 366px;" align="center" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="text-align: center;" height="8"><font size="2">&nbsp;Echo</font></td>
            <td style="text-align: center;" height="8"><font size="2">Cocoon <br></font></td>
            <td style="text-align: center;" height="8"><font size="2">Millstone <br></font></td>
            <td style="text-align: center;" height="8"><font size="2">OXF <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">&nbsp;Struts</font></td>
            <td style="text-align: center;"><font size="2">SOFIA <br></font></td>
            <td style="text-align: center;"><font size="2">Tapestry<br></font></td>
            <td style="text-align: center;"><font size="2">WebWork <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">RIFE <br></font></td>
            <td style="text-align: center;"><font size="2">Spring MVC <br></font></td>
            <td style="text-align: center;"><font size="2">Canyamo&nbsp;</font></td>
            <td style="text-align: center;"><font size="2">&nbsp;Maverick</font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">JPublish <br></font></td>
            <td style="text-align: center;"><font size="2">JATO <br></font></td>
            <td style="text-align: center;"><font size="2">Folium <br></font></td>
            <td style="text-align: center;"><font size="2">Jucas <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Verge <br></font></td>
            <td style="text-align: center;"><font size="2">Niggle <br></font></td>
            <td style="text-align: center;"><font size="2">Bishop <br></font></td>
            <td style="text-align: center;"><font size="2">Barracuda <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Action Framework <br></font></td>
            <td style="text-align: center;"><font size="2">Shocks <br></font></td>
            <td style="text-align: center;"><font size="2">TeaServlet<br></font></td>
            <td style="text-align: center;"><font size="2">&nbsp;wingS</font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Expresso <br></font></td>
            <td style="text-align: center;"><font size="2">Bento <br></font></td>
            <td style="text-align: center;"><font size="2">jStatemachine <br></font></td>
            <td style="text-align: center;"><font size="2">jZonic <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">OpenEmcee <br></font></td>
            <td style="text-align: center;"><font size="2">Turbine <br></font></td>
            <td style="text-align: center;"><font size="2">Scope <br></font></td>
            <td style="text-align: center;"><font size="2">Warfare <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">JMAA <br></font></td>
            <td style="text-align: center;"><font size="2">Jaffa <br></font></td>
            <td style="text-align: center;"><font size="2">Jacquard <br></font></td>
            <td style="text-align: center;"><font size="2">Macaw <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Smile <br></font></td>
            <td style="text-align: center;"><font size="2">MyFaces <br></font></td>
            <td style="text-align: center;"><font size="2">Chiba <br></font></td>
            <td style="text-align: center;"><font size="2">JBanana <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Jeenius <br></font></td>
            <td style="text-align: center;"><font size="2">JWarp <br></font></td>
            <td style="text-align: center;"><font size="2">Genie <br></font></td>
            <td style="text-align: center;"><font size="2">Melati <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Dovetail <br></font></td>
            <td style="text-align: center;"><font size="2">Cameleon <br></font></td>
            <td style="text-align: center;"><font size="2">JFormular <br></font></td>
            <td style="text-align: center;"><font size="2">Xoplon <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Japple <br></font></td>
            <td style="text-align: center;"><font size="2">Helma <br></font></td>
            <td style="text-align: center;"><font size="2">Dinamica <br></font></td>
            <td style="text-align: center;"><font size="2">WebOnSwing <br></font></td>
        </tr>
        <tr height="8">
            <td style="text-align: center;"><font size="2">Nacho <br></font></td>
            <td style="text-align: center;"><font size="2">Cassandra <br></font></td>
            <td style="text-align: center;"><font size="2">Baritus <br></font></td>
            <td style="text-align: center;"><font size="2">&nbsp;</font></td>
        </tr>
    </tbody>
</table>
</div>
<hr>
<p><strong>&nbsp;&nbsp;&nbsp; 注：本文由Jonathan Locke编写,相关权利由原作者承担。</strong></p><img src ="http://www.blogjava.net/tommyjian/aggbug/122485.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-07 07:51 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/07/122485.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：Wicket的特性——来自Wicket孵化站点</title><link>http://www.blogjava.net/tommyjian/archive/2007/06/06/122399.html</link><dc:creator>Tommy Jian</dc:creator><author>Tommy Jian</author><pubDate>Wed, 06 Jun 2007 08:38:00 GMT</pubDate><guid>http://www.blogjava.net/tommyjian/archive/2007/06/06/122399.html</guid><wfw:comment>http://www.blogjava.net/tommyjian/comments/122399.html</wfw:comment><comments>http://www.blogjava.net/tommyjian/archive/2007/06/06/122399.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/tommyjian/comments/commentRss/122399.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tommyjian/services/trackbacks/122399.html</trackback:ping><description><![CDATA[<p><strong>与Swing类似的面向对象组件模型</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket中的页面及其他组件都是支持封装、继承和事件触发的Java对象。 </p>
<p><strong>易于开发</strong></p>
<p>&nbsp;&nbsp;&nbsp; 因为Wicket合成了Java和HTML，在使用Wicket开发应用的过程中，您可以最大限度地发挥您所掌握的Java知识，而且可以最大限度地发挥您最喜欢的HTML编辑器在开发过程中的作用。 </p>
<p><strong>关注点的分离</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket并没有将标签（比如HTML的相关标签）与Java代码混合，而且也没有在标签文件中增添任何特殊的语法。HTML和Java 的领域是不互相干扰的，它们只是通过Wicket Id来关联，Wikcet Id在HTML中表现为标签的属性，在Java代码中则表现为组件的属性。因为Wicket中的HTML文件是纯粹的HTML文件，Wicket中的Java代码是纯粹的Java代码，编程者和设计者可以最大程度地独立完成工作，而不需要依赖于任何特定的工具。 </p>
<p><strong>安全</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket在默认设置的条件下是安全的。URL不对外公布任何敏感信息，而且所有组件的路径都是相对于会话周期的，脱离了会话周期这些路径将变得无效。如果需要在会话周期间共享信息，则必须做一些特殊的工作才能达到。在下一个版本的 Wicket中，有计划将URL加密功能添加到框架中去以此来支持符合要求更高的安全特性。 </p>
<p><strong>透明的且具备伸缩性的集群支持</strong></p>
<p>&nbsp;&nbsp;&nbsp; 所有基于Wicket的应用不需要额外的设置就可以自动支持集群。一旦系统的瓶颈经评估被发现，那么Wicket将启动页面状态的复制。Wicket的下一个版本将对具备零状态伸缩性的客户端模型提供支持。 </p>
<p><strong>显式的&#8220;后退按钮&#8221;问题支持</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket支持可配置的页面版本管理。当用户提交一个表单，而后使用浏览器的后退按钮来回到以前访问过的页面时，Wicket 可以将页面对象的状态恢复过来，并且将页面以原来的面貌呈现出来。这就意味着您只需要花一点功夫就可以构建出支持&#8220; 后退按钮&#8221;的应用。 </p>
<p><strong>可复用的组件</strong></p>
<p>&nbsp;&nbsp;&nbsp; 在Wicket中，构建可复用的组件十分的简单。您不仅可以使用Java中的关键字extends来从现有的组件继承而构建新的组件，而且可以使用Panel组件来组织一批组件来构建可复用的组件单元。简单且灵活的、支持本地化的表单校验在Wikcet中编写和使用校验器也是十分的简单。而且校验错误消息的定义和本地化也是十分简单的工作。 </p>
<p><strong>类型安全的会话周期</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket消除了手动管理HttpSession属性的需求。页面和组件对象被显式地存储在会话周期中，您的应用也可以构建属性类型安全的会话周期的子类。存储在会话周期中的所有对象可以自动地发布到集群中。 </p>
<p><strong>可自定义的工厂类</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket非常具有扩展性。许多操作可以通过工厂类或者工厂方法来实现自定义。 </p>
<p><strong>可分离的模型</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket中的模型对象在集群系统中的内存和网络占用可以说是轻量级的。当一个模型正在被使用时，它将被装载，主要通过从存储单元来获得数据并激活模型。当这个模型对象已经不再被使用时，临时信息可以被重置，这样就可以消减对象占用的内存数量。 </p>
<p><strong>边框组件</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket的边框组件可以使得页面的装饰符合可重用的规则。这对一般的导航结构和布局显得十分的有用。 </p>
<p><strong>对HTML所有的基本特性提供支持</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket支持图像标签、链接、表单以及其他一切您在Web应用开发中可以用到的特性。 </p>
<p><strong>对属性的可编程操作。</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket组件可以使用编程的方式来修改任何HTML标签的属性。 </p>
<p><strong>自动的转换</strong></p>
<p>&nbsp;&nbsp;&nbsp; 一旦表单校验完成，模型可以使用Wicket的转换器来完成更新。大部分的转换器都是系统自带的，而编写新的转换器也是很简单的事情。 </p>
<p><strong>动态的图像</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wikcet使得图像的使用、共享和生成十分的简单。动态图像可以简单地通过实现绘制（paint）方法来建立。 </p>
<p><strong>可分页的ListView</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket中的ListView十分的强大。您可以将任何组件嵌入到ListView组件的行中，甚至将ListView进行循环嵌套也可以。 PageableListView支持大型数据列表的分页导航。 </p>
<p><strong>树形组件</strong></p>
<p>&nbsp;&nbsp;&nbsp; 具备导航和结点选择的树形组件。 </p>
<p><strong>本地化</strong></p>
<p>&nbsp;&nbsp;&nbsp; HTML页面、图形和字符串都可以实现本地化。 </p>
<p><strong>示例</strong></p>
<p>&nbsp;&nbsp;&nbsp; Wicket有展示其各项功能的数量巨大的例子。 </p>
<img src ="http://www.blogjava.net/tommyjian/aggbug/122399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tommyjian/" target="_blank">Tommy Jian</a> 2007-06-06 16:38 <a href="http://www.blogjava.net/tommyjian/archive/2007/06/06/122399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>