﻿<?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-tech.cap-随笔分类-java</title><link>http://www.blogjava.net/cap/category/2141.html</link><description>我在一望无际的路上</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 17:41:44 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 17:41:44 GMT</pubDate><ttl>60</ttl><item><title>java平台的rails: Groovy on Rails (Grails) 0.1发布了</title><link>http://www.blogjava.net/cap/archive/2006/03/31/38381.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Thu, 30 Mar 2006 18:58:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2006/03/31/38381.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/38381.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2006/03/31/38381.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/38381.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/38381.html</trackback:ping><description><![CDATA[ruby和rails大红大紫的时候, java的fans们其实也没有闲着, 搞出来了<a href="http://groovy.codehaus.org/">groovy</a>作为对ruby的回应, 现在, 对rails的回应也到来了~~~~~~~~~~~~~~~ groovy on rails (Grails) 0.1 (是0.1 不是1.0) <a href="http://docs.codehaus.org/display/GRAILS/2006/03/29/Groovy+on+Rails+(Grails)+0.1+Released">发布了</a><br /><br />得益于java成熟而强大的虚拟机,数据库驱动和第三方类库, grails并不需要自己从头实现太多的东西, 从本质上来讲,grails是集成包装了Spring ,Hibernate ,SiteMesh等基础的库, 向外提供统一的基于grooy语言的接口,这些接口都不用怎么仔细设计,只要照着rails现在的api抄写即可,从这个方面来看,我觉得Grails要模仿甚至超过rails都是不难的/<br /><br />此外, Grails额外提供的功能还包括 Aop支持, 动态的Taglib, Jsp和Groovy Servers Page(GSP)支持等等java扩展过来的技术, 有了grails, 我们就可以立马在java成熟而强大的虚拟机上, 在java成熟而强大的数据库驱动上, 在java成熟而强大的第三方类库上, 以rails的方式来写应用了!!! 多么开心的事情啊. <br /><br />等等等等~....我们现在能得到的还只是0.1版....为什么搞到现在才是0.1版本呢,速度真是缓慢的说. 我记得rails还在0.x的时候就有听到了grails的消息, 现在rails都1.1了, 我们能看到的居然还是0.1版本. 如果grails真的只是包装一下spring,hibernate,sitemesh等成熟的类库的话, 我实在想不出半年多以来(好像都快1年了)grails的开发者都在作些什么? 唯一可能的<a href="http://www.pyrasun.com/mike/mt/archives/2005/01/09/20.57.06/">问题</a>应该出在groovy上, 这个语言成熟了么? robbin说groovy进展缓慢有内幕... 好奇ing, 实在不行干脆用<a href="http://jruby.sourceforge.net/">jruby</a>得了, 起码人家这个月又升级了.<img src ="http://www.blogjava.net/cap/aggbug/38381.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2006-03-31 02:58 <a href="http://www.blogjava.net/cap/archive/2006/03/31/38381.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>替换commons logging :  又一个java的log包: SLF4J</title><link>http://www.blogjava.net/cap/archive/2006/03/11/34802.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Sat, 11 Mar 2006 03:53:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2006/03/11/34802.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/34802.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2006/03/11/34802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/34802.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/34802.html</trackback:ping><description><![CDATA[Yes ~! Yet Another Java Logging Api&nbsp;<BR><BR>数一数, java现在有的loggingapi一共有log4j, jdk logging, commons logging, SLF4J4个log包了, 其中log4j和 jdk logging,是对log的封装,&nbsp;&nbsp; commons logging和SLF4J则是对log api的封装. 如果你去翻阅文档,你会发现每一个logapi都是告诉你"我们提供标准的使用log的方式", 但是出来好几个标准, 反而让人无法知道什么才是真正的"标准"<BR><BR>据说SLF4J是对commons logging的改良, 不再会有恶心的<A href="http://www.qos.ch/logging/classloader.jsp">classloader问题</A>, SLF4J采用的是编译器绑定底层实现的方式来避免classloader的问题, 这样做的一个小缺陷是无法运时候绑定底层实现了(反正偶也不用)<BR><BR>SLF4J提供了对commons logging的支持, 所以说来commons logging是可以无缝迁移的．希望这是个好消息<BR><BR><BR><img src ="http://www.blogjava.net/cap/aggbug/34802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2006-03-11 11:53 <a href="http://www.blogjava.net/cap/archive/2006/03/11/34802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>的确够恶心的(java代码)</title><link>http://www.blogjava.net/cap/archive/2006/03/04/33640.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Sat, 04 Mar 2006 14:39:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2006/03/04/33640.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/33640.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2006/03/04/33640.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/33640.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/33640.html</trackback:ping><description><![CDATA[from <A href="http://www.loudthinking.com/arc/000568.html">loudthinking</A>&nbsp;and&nbsp;<A href="http://www.netbeans.org/kb/articles/creator.html">java creator 2 demo</A><BR><BR>例子代码中有一句<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">UploadedFile&nbsp;uploadedFile&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(UploadedFile)&nbsp;fileUpload1.getUploadedFile();<BR>String&nbsp;text&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;uploadedFile.getAsString();</SPAN></DIV><BR><BR>看上去确实很恶心, 真像是在绕口令,就算是搞demo, 也应该专业一点嘛<BR><BR><BR><BR><BR><img src ="http://www.blogjava.net/cap/aggbug/33640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2006-03-04 22:39 <a href="http://www.blogjava.net/cap/archive/2006/03/04/33640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IDEA发布5.1 同时开始了新的EAP版本</title><link>http://www.blogjava.net/cap/archive/2006/02/07/29796.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Tue, 07 Feb 2006 05:28:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2006/02/07/29796.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/29796.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2006/02/07/29796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/29796.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/29796.html</trackback:ping><description><![CDATA[<p>    IntelliJ IDEA 5.1发布，和IDEA5.0相比, 增加了不少<a href="http://www.jetbrains.com/idea/features/newfeatures.html">新功能</a>,包括如下</p><ul>    <li>        JSP,HTML,XHTML和JavaScript增强     </li>    <li>        I18N支持,插件开发的支持     </li>    <li>        代码分析能力的增强, 调试JSP的支持     </li>    <li>        日文版</li></ul><p>    同时5.1还修正了多个BUG,系统更加稳定。&#160; 下载连接如下</p><p>    <a href="http://download.jetbrains.com/idea/idea-5.1.exe">http://download.jetbrains.com/idea/idea-5.1.exe</a></p><p>    IntelliJ IDEA 6.0 EAP版本也开始发布了，代号Demetra，这是一个<a href="http://www.jetbrains.net/confluence/display/IDEADEV/Demetra+Roadmap">全新的版本</a>。</p><p>    这里查看<a href="http://www.jetbrains.net/confluence/display/IDEADEV/What%27s+New+In+Demetra">Demetra的特性</a>     <br/>    &#160;</p><img src ="http://www.blogjava.net/cap/aggbug/29796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2006-02-07 13:28 <a href="http://www.blogjava.net/cap/archive/2006/02/07/29796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用ResinStatusServlet查看resin状态</title><link>http://www.blogjava.net/cap/archive/2005/09/20/resin.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Tue, 20 Sep 2005 01:53:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/09/20/resin.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/13491.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/09/20/resin.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/13491.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/13491.html</trackback:ping><description><![CDATA[<P>resin2没有resin3才有的jmx ,也没有像tomcat那样提供一个可以查看系统状态的应用，最近察看文档的时候，发现原来resin从2.0.5开始就提供了一个ResinStatusServlet，由于只是一个servlet，所以它可以嵌入到你的web应用中.  多少也算有些用处(resin3下依然可以继续使用）<BR>   默认情况下， 这个servlet是没有启用的，如果要启用，可以编辑resin.conf, 例子如下<BR></P><SPAN style="COLOR: #ff0000"><SPAN style="COLOR: #0000ff"><SPAN style="COLOR: #ff0000"><SPAN style="COLOR: #ff0000"><SPAN style="COLOR: #0000ff"><SPAN style="COLOR: #0000ff"><SPAN style="COLOR: #0000ff"><SPAN style="COLOR: #0000ff"><SPAN style="COLOR: #0000ff">
<P></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff"><</SPAN><SPAN style="COLOR: #800000">web-app </SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">='/admin'><BR>  </SPAN><SPAN style="COLOR: #ff0000"><allow-admin</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000">true</SPAN><SPAN style="COLOR: #0000ff"></</SPAN><SPAN style="COLOR: #800000">allow-admin</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR>  </SPAN><SPAN style="COLOR: #0000ff"><</SPAN><SPAN style="COLOR: #800000">servlet-mapping </SPAN><SPAN style="COLOR: #ff0000">url-pattern</SPAN><SPAN style="COLOR: #0000ff">='/resin-status'<BR>                   </SPAN><SPAN style="COLOR: #ff0000">servlet-name</SPAN><SPAN style="COLOR: #0000ff">='com.caucho.http.servlet.ResinStatusServlet'><BR>    </SPAN><SPAN style="COLOR: #ff0000"><init-param enable</SPAN><SPAN style="COLOR: #0000ff">='read'/><BR>  </SPAN><SPAN style="COLOR: #ff0000"></servlet-mapping</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR><BR>  </SPAN><SPAN style="COLOR: #008000"><!--</SPAN><SPAN style="COLOR: #008000">  ip限制 </SPAN><SPAN style="COLOR: #008000">--></SPAN><SPAN style="COLOR: #000000"> <BR>  </SPAN><SPAN style="COLOR: #0000ff"><</SPAN><SPAN style="COLOR: #800000">security-constraint</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR>    </SPAN><SPAN style="COLOR: #0000ff"><</SPAN><SPAN style="COLOR: #800000">ip-constraint</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000">127.0.0.1/32</SPAN><SPAN style="COLOR: #0000ff"></</SPAN><SPAN style="COLOR: #800000">ip-constraint</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR><BR>    </SPAN><SPAN style="COLOR: #0000ff"><</SPAN><SPAN style="COLOR: #800000">web-resource-collection</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR>      </SPAN><SPAN style="COLOR: #0000ff"><</SPAN><SPAN style="COLOR: #800000">url-pattern</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000">/*</SPAN><SPAN style="COLOR: #0000ff"></</SPAN><SPAN style="COLOR: #800000">url-pattern</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR>    </SPAN><SPAN style="COLOR: #0000ff"></</SPAN><SPAN style="COLOR: #800000">web-resource-collection</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR>  </SPAN><SPAN style="COLOR: #0000ff"></</SPAN><SPAN style="COLOR: #800000">security-constraint</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff"></</SPAN><SPAN style="COLOR: #800000">web-app</SPAN><SPAN style="COLOR: #0000ff">></SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN></DIV>
<P>这样通过url <A href="http://yourhost/yourapp/resin-status">http://yourhost/yourapp/resin-status</A> 就可以访问， 这个ResinStatusServlet同时还会注册一个com.caucho.http.admin.ApplicationAdmin的对象到你的servlet context中， 名字是"caucho.admin"。<BR></P></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN><img src ="http://www.blogjava.net/cap/aggbug/13491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-09-20 09:53 <a href="http://www.blogjava.net/cap/archive/2005/09/20/resin.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java搜索引擎: lucene学习笔记 3</title><link>http://www.blogjava.net/cap/archive/2005/08/07/9532.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Sun, 07 Aug 2005 15:52:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/08/07/9532.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/9532.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/08/07/9532.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/9532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/9532.html</trackback:ping><description><![CDATA[<H2>搜索</H2>
<P>Lucene搜索的api的类主要有4个 IndexSearcher ,Query（包括子类）,QueryParser,Hits<BR>IndexSearcher是搜索的入口，他的search方法提供了搜索功能</P>
<P>Query有很多子类， 各种不同的子类代表了不同的查询条件,下文详述</P>
<P>QueryParser是一个非常通用的帮助类，他的作用是把用户输入的文本转换为内置的Query对象（大多数web搜索引擎都提供一个查询输入框来让用户输入查询条件）。QueryParser内置提供了很多语法来使使用可以输入各种高级条件的Query。比如: "Hello AND world"会被解析为一个AND关系的BooleanQuery，他包含两个TermQuery(Hell和world)。这些语法虽然强大，但都针对英文设计，对我们需要中文搜索来说都不需要了解太多的Query类型，一般几个简单的就够用了。QueryParser的使用如下</P>
<P>QueryParser.parse(String query, String field, Analyzer analyzer) throws ParseException</P>
<P>其中：query是用户输入的内容,field是搜索默认的field（其他field需要显式指定），analyzer是用来将用户输入的内容也作分析处理（分词），一般情况下这里的anaylyzer是index的时候采用的同一analyzer。</P>
<P>另外我们也可以自己构造一个QueryParser: new QueryParser(String field, Analyzer a)(含义同上),这样做的好处是可以自己定义调整一些参数.</P>
<H2>搜索结果的处理:Hits对象</H2>Hits对象是搜索结果的集合 主要有下面几个方法 
<OL>
<LI>length() ,这个方法记录有多少条结果返回(lazy loading)</LI>
<LI>doc(n) 返回第n个记录</LI>
<LI>id(in) 返回第n个记录的Document ID</LI>
<LI>score(n) 第n个记录的相关度(积分)</LI></OL>
<P>由于搜索的结果一般比较大，从性能上考虑，Hits对象并不会真正把所有的结果全部取回，默认情况下是保留前100个记录(对于一般的搜索引擎,100个记录足够了).</P>
<H3>分页的处理</H3>
<P>100条记录还是太多，我们多半会每页显示20条记录，然后分为若干页显示，对于分页，一般有两个办法 </P>
<OL>
<LI>在session中保留indexreader对象和hit对象，翻页的时候提取内容</LI>
<LI>不使用session，每次都简单处理为重新查询</LI></OL>
<P>lucene推荐先使用第二个办法，即每次都重新查询，这样做的好处是简单方便，不需要考虑session的问题，lucene的查询效率也能保证每次查询时间不长，除非真正有了性能问题，否则不用考虑第一个办法。</P>
<H2>缓存：RAMDirectory的用法</H2>
<P>RAMDirectory对象很好用，通过它，我们可以把一个普通的index完全读取到内存中,用法如下：<BR>RAMDirectory ramDir = new RAMDirectory(dir);<BR>这样的ramdir效率自然比真正的文件系统快很多</P>
<H3>Lucene的scoring算法</H3>
<P>lucence查询的纪录默认按照相关度排序，这个相关度就是score,scoring的算法是比较复杂的,对于我们做应用的人似乎没有什么帮助，（先说一下Term: 我的理解是Term为一个独立的查询词,用户输入的的查询通过各种分词，大小写处理(正规化),消除stopwords等）以后，会已Term为基本单位），几个关键参数稍微留意一下即可。</P>
<UL>
<LI>Term在文章中出现的频率量</LI>
<LI>包含同一个Term的文章的频率</LI>
<LI>field中的boosting参数</LI>
<LI>term的长度</LI>
<LI>term在文章中的数量</LI></UL>一般来说,这些参数我们都不可能去调整, 如果你想了解更多,IndexSearcher还提供了一个explain方法, 通过传入一个Query和document ID,你可以得到一个Explaination对象,他是对内部算法信息的简单封装,toString()一下就可以看到详细的说明 
<H2>创建Query:各种query介绍</H2>
<P><STRONG>最普通的TermQuery</STRONG><BR>TermQuery最普通, 用Term t=new Term("contents","cap"); new TermQuery(t)就可以构造<BR>TermQuery把查询条件视为一个key, 要求和查询内容完全匹配,比如Field.Keyword类型就可以使用TermQuery</P>
<P><STRONG>RangeQuery</STRONG><BR>RangeQuery表示一个范围的搜索条件,RangeQuery query = new RangeQuery(begin, end, included);<BR>最后一个boolean值表示是否包含边界条件本身, 用字符表示为"[begin TO end]" 或者"{begin TO end}"</P>
<P><STRONG>PrefixQuery</STRONG><BR>顾名思义,就是表示以某某开头的查询, 字符表示为"something*"</P>
<P><STRONG>BooleanQuery</STRONG><BR>这个是一个组合的Query,你可以把各种Query添加进去并标明他们的逻辑关系,添加条件用</P>
<P>public void add(Query query, boolean required, boolean prohibited)</P>
<P>方法, 后两个boolean变量是标示AND OR NOT三种关系 字符表示为" AND OR NOT" 或 "+ -" ,一个BooleanQuery中可以添加多个Query, 如果超过setMaxClauseCount(int)的值(默认1024个)的话,会抛出TooManyClauses错误.</P>
<P><STRONG>PhraseQuery</STRONG><BR>表示不严格语句的查询,比如"red pig"要匹配"red fat pig","red fat big pig"等,PhraseQuery所以提供了一个setSlop()参数,在查询中,lucene会尝试调整单词的距离和位置,这个参数表示可以接受调整次数限制,如果实际的内容可以在这么多步内调整为完全匹配,那么就被视为匹配.在默认情况下slop的值是0, 所以默认是不支持非严格匹配的, 通过设置slop参数(比如"red pig"匹配"red fat pig"就需要1个slop来把pig后移动1位),我们可以让lucene来模糊查询. 值得注意的是,PhraseQuery不保证前后单词的次序,在上面的例子中,"pig red"需要2个slop,也就是如果slop如果大于等于2,那么"pig red"也会被认为是匹配的.</P>
<P><STRONG>WildcardQuery</STRONG><BR>使用?和*来表示一个或多个字母比如wil*可以匹配 wild ,wila ,wilxaaaa...,值得注意的是,在wildcard中,只要是匹配上的纪录,他们的相关度都是一样的,比如wilxaaaa和wild的对于wil*的相关度就是一样的.</P>
<P><STRONG>FuzzyQuery</STRONG><BR>这个Query对中文没有什么用处,他能模糊匹配英文单词(前面的都是词组),比如fuzzy和wuzzy他们可以看成类似, 对于英文的各种时态变化和复数形式,这个FuzzyQuery还算有用,匹配结果的相关度是不一样的.字符表示为 "fuzzy~"</P>
<H2>QueryParser使用</H2>
<P>对于搜索引擎, 很多情况下用户只需要一个输入框就要输入所有的查询条件(比如google), 这时,QueryParser就派上用场了,他的作用就是把各种用户输入转为Query或者Query组, 他把上面提到的Query的字符表示(Query.toString)转化为实际的Query对象,比如"wuzzy~"就会转换为FuzzyQuery, 不过<FONT color=#ff0000>QueryParser用到了Analyzer,所以QueryParser parse过后的Query再toString未必和原来的一样</FONT>.Query额外的语法有:</P>
<P><STRONG>分组:Groupping</STRONG><BR>比如"(a AND b) or C",就是括号分组,很容易理解</P>
<P><STRONG>FieldSelectiong</STRONG><BR>QueryParser的查询条件是对默认的Field进行的, 它在QueryParser解析的时候编码指定, 如果用户需要在查询条件中选用另外的Field, 可以使用如下语法: fieldname:fielda, 如果是多个分组,可以用fieldname:(fielda fieldb fieldc)表示.</P>
<P><STRONG>*号问题</STRONG><BR>QueryParse默认不允许*号出现在开始部分，这样做的目的主要是为了防止用户误输入*来头导致严重的性能问题（会把所有记录读出）</P>
<P><STRONG>boosting</STRONG><BR>通过hello^2.0 可以对hello这个term进行boosting，(我想不到什么用户会这样么bt)<BR></P>
<P>QueryParser是一个准备好的,立即可以工作的帮助类,不过他还是提供了很多参数供程序员调整，首先,我们需要自己构造一个新的QueryParser,然后对他的各种参数来定制化.</P><img src ="http://www.blogjava.net/cap/aggbug/9532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-08-07 23:52 <a href="http://www.blogjava.net/cap/archive/2005/08/07/9532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JspTaglib:一个比displaytag更好的table组件:eXtremeTable</title><link>http://www.blogjava.net/cap/archive/2005/08/04/9168.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Thu, 04 Aug 2005 02:31:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/08/04/9168.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/9168.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/08/04/9168.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/9168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/9168.html</trackback:ping><description><![CDATA[<IMG style="WIDTH: 555px; HEIGHT: 250px" height=382 alt=tag.jpg src="http://www.extremecomponents.org/extremesite/images/eXtremeTable.jpg" border=0><BR>
<P>先说displaytag：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;曾经我用displaytag来处理表格显示，displaytag界面很漂亮，但是有一个很严重的不足：数据一多就会严重损害系统性能。 displaytag默认是把所有数据取回再分页， 比如你有100条数据，分5页，display每次都会去取回100条但只显示20条，他这样做的后果是数据量一大，系统的速度就会慢下来，特别是数据源如果不做cache直接连接数据库，每次displaytag都会到数据库里重新query所有数据，哪怕你只是作一个排序。虽然后来可以通过hack代码能让他每次只取要显示那些数据，但是这样会导致display的数据导出，排序功能都无法正常工作，让人苦不堪言。 同时displaytag也很难扩展，你要加入功能就只有一个办法：Hack！直接冲入源代码中修改！这样做的后果是我得到一个自己的display包，不过他再也不能和新版本的displaytag一起工作了。<BR>eXtremeTable<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一度弃用displaytag，找到valuelist，不过这个valuelist虽然设计先进（据说还有个valuelist模式），方便修改。但是就是界面很丑陋，本人也不太懂css。一时也没有兴趣再找taglib了。今天在网上闲逛，突然看到白衣的blog中提到了eXtremTable, 上主页看了一下，不错，这个组件比valuelist好多了<BR></P>
<UL>
<LI>界面简洁大方 
<LI>displaytag的常用功能都支持 
<LI>支持表格中放置input组件 
<LI>分页机制完善，数据可以"按需索取" 
<LI>版本总算是1.0以上，本人对版本号小于1的东西都有点怕怕</LI></UL>
<P>赶忙<A href="http://extremecomponents.org/">down下来</A>研究，同时也推荐给大家了解一下</P><img src ="http://www.blogjava.net/cap/aggbug/9168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-08-04 10:31 <a href="http://www.blogjava.net/cap/archive/2005/08/04/9168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>推荐：java程序员的两个好资源站点</title><link>http://www.blogjava.net/cap/archive/2005/08/02/9060.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Tue, 02 Aug 2005 10:11:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/08/02/9060.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/9060.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/08/02/9060.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/9060.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/9060.html</trackback:ping><description><![CDATA[第一个是 <A href="http://www.koders.com/">http://www.koders.com/</A>&nbsp;是一个源代码搜索引擎，可以查询Apache，Mozilla，Novell Forge和SourceForge等组织的源代码。目前，据称可以搜索1.98亿行源代码，并可按编程语言及应用协议的不同进行查询，其查询直接深入到源代码内部进行，对开发者比较有用<BR><BR>第二个是 <A href="http://javaalmanac.com/" target=_blank>http://javaalmanac.com</A>&nbsp;Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧<BR>的用法及示例代码, 这是一个不错的去处，我经常去参阅<BR><BR><BR><img src ="http://www.blogjava.net/cap/aggbug/9060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-08-02 18:11 <a href="http://www.blogjava.net/cap/archive/2005/08/02/9060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java搜索引擎: lucene学习笔记 2</title><link>http://www.blogjava.net/cap/archive/2005/07/20/8078.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Wed, 20 Jul 2005 15:48:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/07/20/8078.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/8078.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/07/20/8078.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/8078.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/8078.html</trackback:ping><description><![CDATA[<H3>Boosting特性</H3>
<P>luncene对Document和Field提供了一个可以设置的Boosting参数， 这个参数的用处是告诉lucene， 某些记录更重要，在搜索的时候优先考虑他们 比如在搜索的时候你可能觉得几个门户的网页要比垃圾小站更优先考虑</P>
<P>lucene默认的boosting参数是1.0,&nbsp; 如果你觉得这个field重要,你可以把boosting设置为1.5, 1.2....等, 对Document设置boosting相当设定了它的每个Field的基准boosting，到时候实际Field的boosting就是(Document-boosting*Field-boosting)设置了一遍相同的boosting.</P>
<P>似乎在lucene的记分公式里面有boosting参数,不过我估计一般人是不会去研究他的公式的（复杂）,而且公式也无法给出最佳值，所以我们所能做的只能是一点一点的改变boosting, 然后在实际检测中观察它对搜索结果起到多大的作用来调整</P>
<P>一般的情况下是没有必要使用boosting的, 因为搞不好你就把搜索给搞乱了, 另外如果是单独对Field来做Bossting, 也可以通过将这个Field提前来起到近似的效果 </P>
<H3>Indexing Date</H3>
<P>日期是lucene需要特殊考虑的地方之一, 因为我们可能需要对日期进行范围搜索, Field.keyword(string,Date)提供了这样的方法,lucene会把这个日期转换为string, 值得注意的是这里的日期是精确到毫秒的,可能会有不必要的性能损失, 所以我们也可以把日期自行转化为YYYYMMDD这样的形势,就不用精确到具体时间了,通过File.keyword(Stirng,String) 来index, 使用PrefixQuery 的YYYY一样能起到简化版的日期范围搜索(小技巧), lucene提到他不能处理1970年以前的时间,似乎是上一代电脑系统遗留下来的毛病</P>
<H3>Indexing 数字</H3>
<P>
<OL>
<LI>如果数字只是简单的数据, 比如中国有56个民族. 那么可以简单的把它当字符处理 
<LI>如果数字还包含数值的意义,比如价格, 我们会有范围搜索的需要(20元到30元之间的商品),那么我们必须做点小技巧, 比如把3,34,100 这三个数字转化为003,034,100 ,因为这样处理以后, 按照字符排序和按照数值排序是一样的,而lucene内部按照字符排序,003-&gt;034-&gt;100 NOT(100-&gt;3-&gt;34)</LI></OL>
<P></P>
<H3>排序</H3>
<P>Lucene默认按照相关度(score)排序,为了能支持其他的排序方式,比如日期,我们在add Field的时候,必须保证field被Index且不能被tokenized(分词),并且排序的只能是数字,日期,字符三种类型之一</P>
<H3>Lucene的IndexWriter调整</H3>
<P>IndexWriter提供了一些参数可供设置，列表如下</P>
<TABLE border=1>
<TBODY <TR>
<TR>
<TD>&nbsp;</TD>
<TD>属性</TD>
<TD>默认值</TD>
<TD>说明</TD></TR>
<TR>
<TD>mergeFactor</TD>
<TD>org.apache.lucene.mergeFactor</TD>
<TD>10</TD>
<TD>控制index的大小和频率,两个作用</TD></TR>
<TR>
<TD>maxMergeDocs</TD>
<TD>org.apache.lucene.maxMergeDocs</TD>
<TD>Integer.MAX_VALUE</TD>
<TD>限制一个段中的document数目</TD></TR>
<TR>
<TD>minMergeDocs</TD>
<TD>org.apache.lucene.minMergeDocs</TD>
<TD>10</TD>
<TD>缓存在内存中的document数目，超过他以后会写入到磁盘</TD></TR>
<TR>
<TD>maxFieldLength</TD>
<TD>&nbsp;</TD>
<TD>1000</TD>
<TD>一个Field中最大Term数目，超过部分忽略，不会index到field中，所以自然也就搜索不到</TD></TR></TBODY></TABLE><BR>这些参数的的详细说明比较复杂：mergeFactor有双重作用 
<OL>
<LI>设置每mergeFactor个document写入一个段，比如每10个document写入一个段 
<LI>设置每mergeFacotr个小段合并到一个大段，比如10个document的时候合并为1小段，以后有10个小段以后合并到一个大段，有10个大段以后再合并，实际的document数目会是mergeFactor的指数</LI></OL>简单的来说mergeFactor 越大，系统会用更多的内存，更少磁盘处理，如果要打批量的作index，那么把mergeFactor设置大没错， mergeFactor 小了以后， index数目也会增多，searhing的效率会降低， 但是mergeFactor增大一点一点，内存消耗会增大很多(指数关系),所以要留意不要"out of memory"<BR>把maxMergeDocs设置小，可以强制让达到一定数量的document写为一个段，这样可以抵消部分mergeFactor的作用.<BR>minMergeDocs相当于设置一个小的cache,第一个这个数目的document会留在内存里面，不写入磁盘。这些参数同样是没有最佳值的， 必须根据实际情况一点点调整。<BR>maxFieldLength可以在任何时刻设置， 设置后，接下来的index的Field会按照新的length截取，之前已经index的部分不会改变。可以设置为Integer.MAX_VALUE<BR><BR>
<H3>RAMDirectory 和 FSDirectory 转化</H3>
<P>RAMDirectory(RAMD)在效率上比FSDirectyr(FSD)高不少, 所以我们可以手动的把RAMD当作FSD的buffer,这样就不用去很费劲的调优FSD那么多参数了,完全可以先用RAM跑好了index， 周期性（或者是别的什么算法）来回写道FSD中。 RAMD完全可以做FSD的buffer。</P>
<H3>为查询优化索引(index)</H3>
<P>Indexwriter.optimize()方法可以为查询优化索引（index），之前提到的参数调优是为indexing过程本身优化，而这里是为查询优化，优化主要是减少index文件数，这样让查询的时候少打开文件，优化过程中，lucene会拷贝旧的index再合并，合并完成以后删除旧的index，所以在此期间，磁盘占用增加， IO符合也会增加，在优化完成瞬间，磁盘占用会是优化前的2倍,在optimize过程中可以同时作search。</P>
<H3>并发操作Lucene和locking机制</H3>
<P>
<UL>
<LI>所有只读操作都可以并发 
<LI>在index被修改期间，所有只读操作都可以并发 
<LI>对index修改操作不能并发，一个index只能被一个线程占用 
<LI>index的优化，合并，添加都是修改操作</LI></UL>IndexWriter和IndexReader的实例可以被多线程共享，他们内部是实现了同步，所以外面使用不需要同步<BR>
<P></P>
<H3>Locing</H3>
<P>&nbsp;&nbsp;&nbsp;lucence内部使用文件来locking， 默认的locking文件放在java.io.tmpdir,可以通过-Dorg.apache.lucene.lockDir=xxx指定新的dir，有write.lock commit.lock两个文件，lock文件用来防止并行操作index，如果并行操作， lucene会抛出异常，可以通过设置-DdisableLuceneLocks=true来禁止locking，这样做一般来说很危险，除非你有操作系统或者物理级别的只读保证，比如把index文件刻盘到CDROM上。</P>
<H3>调试IndexWriter</H3>
<P>IndexWriter 有一个infoStream的变量，调试信息从这里输出。可以把System.out设置给它</P><img src ="http://www.blogjava.net/cap/aggbug/8078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-07-20 23:48 <a href="http://www.blogjava.net/cap/archive/2005/07/20/8078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Swing技巧. 设置全局字体 </title><link>http://www.blogjava.net/cap/archive/2005/07/20/8061.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Wed, 20 Jul 2005 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/07/20/8061.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/8061.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/07/20/8061.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/8061.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/8061.html</trackback:ping><description><![CDATA[<TABLE class=tf width="98%" border=0>
<TBODY>
<TR>
<TD height=30><FONT class=red_3><B>Swing技巧. 设置全局字体（sun jdk）<BR><BR>为什么要这么做？<BR><BR>&nbsp;&nbsp;&nbsp;因为java默认的字体显示中文都很难看<BR><BR>&nbsp;&nbsp;&nbsp;因为比如jgoodies这样的skin默认不支持中文<BR><BR>&nbsp;&nbsp;&nbsp;因为jdk1.4中文字体mapping有严重bug,用过IDEA的人都知道<BR><BR>&nbsp;&nbsp;&nbsp;因为大家只有sun的jdk可用，ibm的，bea的都不适合跑client<BR><BR>if you are smart....<BR></B></FONT></TD></TR>
<TR>
<TD class=bw><FONT class=htd>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">设置全局字体</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;initGlobalFontSetting(Font&nbsp;fnt){<BR>&nbsp;&nbsp;&nbsp;&nbsp;FontUIResource&nbsp;fontRes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;FontUIResource(fnt);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(Enumeration&nbsp;keys&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;UIManager.getDefaults().keys();&nbsp;keys.hasMoreElements();){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;key&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;keys.nextElement();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;UIManager.</SPAN><SPAN style="COLOR: #0000ff">get</SPAN><SPAN style="COLOR: #000000">(key);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(value&nbsp;instanceof&nbsp;FontUIResource)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UIManager.put(key,&nbsp;fontRes);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</SPAN></DIV></DIV></FONT></TD></TR></TBODY></TABLE>if you aren't...<BR><BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">Font&nbsp;font&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Font(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Dialog</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,Font.PLAIN,</SPAN><SPAN style="COLOR: #000000">12</SPAN><SPAN style="COLOR: #000000">);<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ToolTip.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Table.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TableHeader.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TextField.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ComboBox.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TextField.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">PasswordField.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TextArea.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TextPane.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">EditorPane.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">FormattedTextField.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Button.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">CheckBox.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">RadioButton.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ToggleButton.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ProgressBar.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">DesktopIcon.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TitledBorder.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Label.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">List.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TabbedPane.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">MenuBar.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Menu.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">MenuItem.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">PopupMenu.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">CheckBoxMenuItem.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">RadioButtonMenuItem.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Spinner.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Tree.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ToolBar.font</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">OptionPane.messageFont</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR>UIManager.put(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">OptionPane.buttonFont</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,font);&nbsp;<BR></SPAN></DIV></DIV><img src ="http://www.blogjava.net/cap/aggbug/8061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-07-20 17:33 <a href="http://www.blogjava.net/cap/archive/2005/07/20/8061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Graphviz来画图 2</title><link>http://www.blogjava.net/cap/archive/2005/07/20/8056.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Wed, 20 Jul 2005 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/07/20/8056.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/8056.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/07/20/8056.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/8056.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/8056.html</trackback:ping><description><![CDATA[<H2>graphviz 虽然很强大，不过有两个地方不足</H2>
<OL>
<LI>对中文支持很差，在windows下还可以用utf-8来处理，在linux下面就很麻烦，我尝试多次也解决不了 
<LI>是graphviz和java之间无法交互，在java中我只能通过新开一个进程来调用graphviz,完全是blackbox,无法控制,也无法确保图形是否正确绘制。</LI></OL>
<H2>经过多次尝试，我发现了几个解决方案</H2>
<P>1，我发现了graphviz还有一个不起眼的子项目<A href="http://www.research.att.com/~john/Grappa/">grappa</A>，这个项目是完全用java写的，按照它的文挡说，算是一个简化版本的graphviz (下载grappa比较麻烦，似乎对方的网页有错误，直接给出的连接是下载不到的，我展转在maillist上才成功得到下载地址，带源代码的，如果想要这个的朋友，可以email给我索取)&nbsp;下载回来一用, 开始是大失所望,原来简化版居然没有graphviz最有价值的自动布局功能.直接生成的图形全部都堆叠在一起, 完全不可用,正打算放弃的时候,发现grappa的的归类在graphviz的view类别中,突然开窍了, 返回回去查,原来graphviz支持多种输出,包括输出.dot文件,svg文件等. 这些文件都是文本的,很好处理,我试了试通过graphviz来生成dot文件和svg文件, 很快,而且中文也没有问题, 经过处理以后的dot文件比原始的dot文件大了不少,查看了以下,发现所有的结点,图形都的是自动布局好了,dot文件里面一一标明了坐标. 这下用grappa处理很成功.&nbsp; 顺利在java中画出图形,(效率明显比graphviz慢不少), 这样一来,第一个办法就是通过graphviz来生成dot, 然后通过grappa来显示. 可以在applet中显示都没有问题, grappa支持很老的java1.1,看来ie中是可以用的</P>
<P>2, graphviz原来可以生成svg文件!,这下就好办多了, 不需要grappa,&nbsp; 通过jakarta的batik包, 我很顺利的通过servlet把svg转换为jpg图片,&nbsp; 中文是支持的 如果有问题可以参见(jdk1.5 在linux下字体设置) . 需要注意的是graphviz对中文没有做特殊处理,在最后生成的xml他会写encoding="utf-8", 但是实际上的编码是你系统默认的编码(我的是gbk) ,所以要手动去调整一下编码.&nbsp; 如果你够变态. 可以用batik把svg读入, 再输出为svg,&nbsp; 最终的svg兼容性就非常好了,&nbsp; 可以通过adobe的svg插件直接在ie中显示.<BR><BR>ps,&nbsp; 使用graphivz的时候, graphiviz没有对长行做自动换行处理, 如果有较长的行, 需要你手动换行, 比如写个程序把12345678换成123\n456\n78,这样最后的效果是换行. 下面这段代码就是干这个事情的<BR></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG id=Codehighlighter1_43_531_Open_Image onclick="this.style.display='none'; Codehighlighter1_43_531_Open_Text.style.display='none'; Codehighlighter1_43_531_Closed_Image.style.display='inline'; Codehighlighter1_43_531_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_43_531_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_43_531_Closed_Text.style.display='none'; Codehighlighter1_43_531_Open_Image.style.display='inline'; Codehighlighter1_43_531_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #000000">&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;filter(String&nbsp;raw)&nbsp;</SPAN><SPAN id=Codehighlighter1_43_531_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_43_531_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;lines&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;raw.trim().split(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG id=Codehighlighter1_125_473_Open_Image onclick="this.style.display='none'; Codehighlighter1_125_473_Open_Text.style.display='none'; Codehighlighter1_125_473_Closed_Image.style.display='inline'; Codehighlighter1_125_473_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_125_473_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_125_473_Closed_Text.style.display='none'; Codehighlighter1_125_473_Open_Image.style.display='inline'; Codehighlighter1_125_473_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(lines.length&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_125_473_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_125_473_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer&nbsp;newline&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;StringBuffer();<BR><IMG id=Codehighlighter1_233_424_Open_Image onclick="this.style.display='none'; Codehighlighter1_233_424_Open_Text.style.display='none'; Codehighlighter1_233_424_Closed_Image.style.display='inline'; Codehighlighter1_233_424_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_233_424_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_233_424_Closed_Text.style.display='none'; Codehighlighter1_233_424_Open_Image.style.display='inline'; Codehighlighter1_233_424_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;lines.length;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_233_424_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_233_424_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;line&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;lines[i];<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newline.append(shortLine(line));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(i&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;lines.length&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newline.append(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;newline.toString();<BR><IMG id=Codehighlighter1_480_525_Open_Image onclick="this.style.display='none'; Codehighlighter1_480_525_Open_Text.style.display='none'; Codehighlighter1_480_525_Closed_Image.style.display='inline'; Codehighlighter1_480_525_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_480_525_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_480_525_Closed_Text.style.display='none'; Codehighlighter1_480_525_Open_Image.style.display='inline'; Codehighlighter1_480_525_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_480_525_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_480_525_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;shortLine(raw);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_582_1030_Open_Image onclick="this.style.display='none'; Codehighlighter1_582_1030_Open_Text.style.display='none'; Codehighlighter1_582_1030_Closed_Image.style.display='inline'; Codehighlighter1_582_1030_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_582_1030_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_582_1030_Closed_Text.style.display='none'; Codehighlighter1_582_1030_Open_Image.style.display='inline'; Codehighlighter1_582_1030_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;shortLine(String&nbsp;line)&nbsp;</SPAN><SPAN id=Codehighlighter1_582_1030_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_582_1030_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_616_981_Open_Image onclick="this.style.display='none'; Codehighlighter1_616_981_Open_Text.style.display='none'; Codehighlighter1_616_981_Closed_Image.style.display='inline'; Codehighlighter1_616_981_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_616_981_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_616_981_Closed_Text.style.display='none'; Codehighlighter1_616_981_Open_Image.style.display='inline'; Codehighlighter1_616_981_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(line.length()&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_616_981_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_616_981_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]&nbsp;chars&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;line.toCharArray();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer&nbsp;sb&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;StringBuffer();<BR><IMG id=Codehighlighter1_766_937_Open_Image onclick="this.style.display='none'; Codehighlighter1_766_937_Open_Text.style.display='none'; Codehighlighter1_766_937_Closed_Image.style.display='inline'; Codehighlighter1_766_937_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_766_937_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_766_937_Closed_Text.style.display='none'; Codehighlighter1_766_937_Open_Image.style.display='inline'; Codehighlighter1_766_937_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;chars.length;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_766_937_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_766_937_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;aChar&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;chars[i];<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(i&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">12</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">)<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.append(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.append(aChar);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;sb.toString();<BR><IMG id=Codehighlighter1_988_1023_Open_Image onclick="this.style.display='none'; Codehighlighter1_988_1023_Open_Text.style.display='none'; Codehighlighter1_988_1023_Closed_Image.style.display='inline'; Codehighlighter1_988_1023_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_988_1023_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_988_1023_Closed_Text.style.display='none'; Codehighlighter1_988_1023_Open_Image.style.display='inline'; Codehighlighter1_988_1023_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_988_1023_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_988_1023_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;line;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV></DIV>
<P></P><img src ="http://www.blogjava.net/cap/aggbug/8056.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-07-20 16:28 <a href="http://www.blogjava.net/cap/archive/2005/07/20/8056.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Graphviz来画图 1</title><link>http://www.blogjava.net/cap/archive/2005/07/17/7895.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Sun, 17 Jul 2005 15:57:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/07/17/7895.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/7895.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/07/17/7895.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/7895.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/7895.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;做了一个系统，通过配置来完成一些简单或者复杂的产品逻辑， 系统投入使用以后， 产品人员在上面配置了不少产品，产品的流程都是存放在一个xml里面，前几天突然有个想法， 打算把这个流程通过图形表示出来， 于是打开google，上网查找java画图的工具，找来找去，没有看到什么好用的免费库，商业的又觉得破解太麻烦，于是无意中找到Graphviz，初步使用以后，发现这个工具真的是很强大。除了不能用java直接操作以外，画各种流程图，网络图，简直是异常简单，而且画图的效果也很好。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphviz的主页在<A href="http://www.graphviz.org/">http://www.graphviz.org/</A> ， 他是AT&amp;T Labs-Research开发的图形绘制工具,&nbsp; 他可以很方便的用来绘制结构化的图形网络，支持多种格式输出， 生成图片的质量和速度都不错</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphviz本身是开源的产品，下载可以到 <A href="http://www.graphviz.org/Download.php">这里</A> ，以及他的<A href="http://www.graphviz.org/Gallery.php">演示界面</A>&nbsp;&nbsp; Graphviz在windows上和Linux上都可以顺利运行<BR></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;安装好Graphviz以后， Graphviz的默认命令会自动添加到命令行走， 使用它很简单，我们需要写一个dot文件， 格式如下 <BR></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">注释的格式，&nbsp;很熟悉吧</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">digraph&nbsp;表示一个有向图&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;digraph&nbsp;G&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR></SPAN></DIV></DIV>
<P>把上面的内容保存为test.dot以后，在命令行下通过"dot test.dot&nbsp; -Tpng -o result.png" 就会在当前目录生成test.png,，非常方便<BR><IMG height=120 alt=t_cap.png src="http://www.blogjava.net/images/blogjava_net/cap/2217/t_cap.png" width=66 border=0><BR>具体的dot格式可以查阅系统的pdf文档，&nbsp; 我可以给出一个复杂一点的小例子和windows下面中文解决办法</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">digraph&nbsp;G&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;graph&nbsp;[<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ratio</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">auto</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello&nbsp;,我的测试</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;labelloc</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">t<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontname</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">simyou.ttf</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;&nbsp;[<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shape</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">box</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">dotted</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontname</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">simyou.ttf</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontsize</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edge&nbsp;&nbsp;[&nbsp;fontname</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">simyou.ttf</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">张三</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;peripheries</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">filled,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">市民张三</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;color</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">#eecc80</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;];<BR>&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">李四</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[<BR>&nbsp;&nbsp;style</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">filled,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">农民李四</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;color</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">#eecc80</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;];<BR>&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">王五</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[<BR>&nbsp;&nbsp;style</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">filled,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">农民王五</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;color</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">#eecc80</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">张三</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">李四</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">亲戚</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">张三</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">王五</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">朋友</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">李四</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">王五</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[label</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">不认识</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;<BR>}<BR><BR></SPAN></DIV></DIV>
<P>在windows下面 ，把文件保存为utf-8格式，然后在文件中设置 &nbsp;fontname="simyou.ttf"（也可以通过命令行参数-E -N -G fontname="xx" 设置）,在我的简体中文windowsxp中生成的图片是可以正常显示中文的。<BR><IMG height=340 alt=o_cap.jpg src="http://www.blogjava.net/images/blogjava_net/cap/2217/o_cap.jpg" width=242 border=0><BR><BR>通过java来调用Graphviz的方法，代码如下<BR><BR>记得通过通过freemarker来生成dot脚本以后，必须要在本地保存为utf-8，然后用dot去处理， 直接通过管道传String的方法是不行的。我试过多种编码，全部都失败了，另外就是simyou.ttf是字体文件的名字，可以到你的windows\fonts\目录下面找到他们的列表<BR></P><img src ="http://www.blogjava.net/cap/aggbug/7895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-07-17 23:57 <a href="http://www.blogjava.net/cap/archive/2005/07/17/7895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java搜索引擎: lucene学习笔记 1</title><link>http://www.blogjava.net/cap/archive/2005/07/17/7849.html</link><dc:creator>tech.cap</dc:creator><author>tech.cap</author><pubDate>Sun, 17 Jul 2005 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/cap/archive/2005/07/17/7849.html</guid><wfw:comment>http://www.blogjava.net/cap/comments/7849.html</wfw:comment><comments>http://www.blogjava.net/cap/archive/2005/07/17/7849.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cap/comments/commentRss/7849.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cap/services/trackbacks/7849.html</trackback:ping><description><![CDATA[<H2>简介</H2>Doug Cutting 于2000年开始的项目 2001年9月后加入apache, Lucene是Doug Cutting的middle name 。 目前Lucene已经是apache的top level的项目， 已经不在jakarta下面， 同时也有了python，perl，c++，.net, Ruby(进行中)多个版本<BR>
<H2>Lucene 主要的两个任务:indexing and searching</H2>
<TABLE height=177 width=565>
<CAPTION>Indexing主要使用的类 </CAPTION>
<TBODY>
<TR>
<TD width=107>IndexWriter</TD>
<TD width=196>较核心的类，index文件由它创建</TD></TR>
<TR>
<TD>Directory</TD>
<TD>一个抽象的标示index文件地址的类，有两个实现:FSDirectory和RAMDirectory， 前者是基于文件系统，后者使用内存</TD></TR>
<TR>
<TD>Analyzer</TD>
<TD>文件的分析器（听起来别扭，还是叫Analyzer好了)的抽象，这个类用来处理分词(对中文尤其重要，转换大小写(Computer-&gt;computer,实现查询大小写无关)，转换词根(computers-&gt;computer),消除stop words等,还负责把其他格式文档转换为纯文本等</TD></TR>
<TR>
<TD>Document</TD>
<TD>一个Document对应一个文档记录,他有很多Field,用来处理不同的信息,和检索相关</TD></TR>
<TR>
<TD>Field</TD>
<TD>有4(5?)种类型的Field, 下面专门列出</TD></TR></TBODY></TABLE>
<P>stop words: 出现频率非常高的一些词汇,它们一般没有检索的意义, 比如英文中的(as a, an, the, in)</P>
<P></P>
<TABLE width=603>
<TBODY>
<TR>
<TH scope=col width=231>类型</TH>
<TH scope=col width=64>Analyzed</TH>
<TH scope=col width=56>Indexed</TH>
<TH scope=col width=48>Stored</TH>
<TH scope=col width=109>说明</TH></TR>
<TR>
<TD>Field.Keyword(String,String/Date)</TD>
<TD>&nbsp;</TD>
<TD>Y</TD>
<TD>Y</TD>
<TD>这个Field用来储存会直接用来检索的比如(身份证号,姓名,日期等)</TD></TR>
<TR>
<TD>Field.UnIndexed(String,String)</TD>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
<TD>Y</TD>
<TD>不会用来检索的信息,但是检索后需要显示的,比如,硬件序列号,文档的url地址</TD></TR>
<TR>
<TD>Field.UnStored(String,String)</TD>
<TD>Y</TD>
<TD>Y</TD>
<TD>&nbsp;</TD>
<TD>大段文本内容,会用来检索,但是检索后不需要从index中取内容,可以根据url去load真实的内容</TD></TR>
<TR>
<TD>Field.Text(String,String)</TD>
<TD>Y</TD>
<TD>Y</TD>
<TD>Y</TD>
<TD>检索,获取都需要的内容,直接放index中,不过这样会增大index</TD></TR>
<TR>
<TD>Field.Text(String,Reader)</TD>
<TD>Y</TD>
<TD>Y</TD>
<TD>&nbsp;</TD>
<TD>如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.</TD></TR></TBODY></TABLE>
<P>
<TABLE height=177 width=565>
<CAPTION>Searching主要使用的类 </CAPTION>
<TBODY>
<TR>
<TD width=107>IndexSearcher</TD>
<TD width=196>以只读的方式访问index（注意IndexReader不是只读的),需要传给他一个Query对象来搜索</TD></TR>
<TR>
<TD>Term</TD>
<TD>Term是一个搜索的基本单位,包含一个Field(目标)和一个value(条件),可以直接用new Term("field","condition value")构造</TD></TR>
<TR>
<TD>Query</TD>
<TD>Query有很多子类,比如BooleanQuery,PhraseQuery等,可以在Term基础上加上逻辑(是 否, 或) </TD></TR>
<TR>
<TD>TermQuery</TD>
<TD>一个很基本的Query, 可以由term构造 new TermQuery(term); </TD></TR>
<TR>
<TD>Hits</TD>
<TD>包含了搜索的结构,默认按照相关度排序,hits并不会把所有记录(可能很大)直接保存,而是有一个lazy loading机制</TD></TR></TBODY></TABLE></P>
<P>tips</P>
<UL>
<LI>Lucene允许一个index中的多个Document可以为Heterogeneous(异类) 也就是说,一个Document 有Field (name,price), 下一个Document可以有Field(name,age),两个Document可以代表完全不同的记录,不过这点我还没有想到有什么特别的用处</LI>
<LI>如果需要对Field增加内容的, 可以使用doc.add(Field.Text("word",newword));如果doc中已经有word这个Field, newword会被自动加入进去,原来的会继续存在, 相当于一个"word"实际上对应一个数组，相当于append 
<LI>Document的编号是不固定的, 如果对index做了修改, document编号会重新计算 
<LI>如果要删除删除index中的记录，使用IndexReader类完成, IndexReader会先标记删除，真实的删除行为在indexReader关闭时执行.也就是说IndexReader也会修改index 
<LI>通过indexReader.undeleteAll()方法只能恢复同一个indexreader实例标记删除的记录 
<LI>没有update方法，要更新记录, 只能通过delete以后再add来进行, 如果要批量进行, 一次性delete完毕以后关闭Reader再打开Writer来add的效率较高</LI></UL><img src ="http://www.blogjava.net/cap/aggbug/7849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cap/" target="_blank">tech.cap</a> 2005-07-17 11:57 <a href="http://www.blogjava.net/cap/archive/2005/07/17/7849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>