﻿<?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-Swing-随笔分类-J2SE</title><link>http://www.blogjava.net/Swing/category/26948.html</link><description>&lt;font size="3"&gt;&lt;br&gt;&lt;font color="#669933"&gt;&lt;em&gt;天行健  君子以自强不息&lt;/em&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;/font&gt;
</description><language>zh-cn</language><lastBuildDate>Tue, 03 Aug 2010 22:45:17 GMT</lastBuildDate><pubDate>Tue, 03 Aug 2010 22:45:17 GMT</pubDate><ttl>60</ttl><item><title>nativeFont和logicalFont在JDK1.4下的重大效率差异</title><link>http://www.blogjava.net/Swing/archive/2010/08/02/327745.html</link><dc:creator>zht</dc:creator><author>zht</author><pubDate>Mon, 02 Aug 2010 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/Swing/archive/2010/08/02/327745.html</guid><wfw:comment>http://www.blogjava.net/Swing/comments/327745.html</wfw:comment><comments>http://www.blogjava.net/Swing/archive/2010/08/02/327745.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Swing/comments/commentRss/327745.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Swing/services/trackbacks/327745.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: #008000; text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">
<p><font face="宋体" size="4"></p>
<p>最近遇到一个很奇怪的问题，写了一个界面程序，刚开始没有 设置字体，效率还可以，但是默认字体看着比较难看，就改用了一个字体，谁知道在jdk1.4批量测试过程中，效率居然比原来要低非常非常的多。<br />
后来发现如果是jdk1.5及以上版本两者效率几乎一样，见附件截图。<br />
而且就Swing效率和增强功能来讲，JDK1.6u10及以上版本有非常大的提高，<br />
所以如果条件运行，还是建议都改成JDK1.6u10及以上版本</font></p>
<p><font face="宋体" size="4">测试代码如下:</font></p>
<span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">
<p><font face="宋体" size="4"></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"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000"><br />
<img id="Codehighlighter1_38_2749_Open_Image" onclick="this.style.display='none'; Codehighlighter1_38_2749_Open_Text.style.display='none'; Codehighlighter1_38_2749_Closed_Image.style.display='inline'; Codehighlighter1_38_2749_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_38_2749_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_38_2749_Closed_Text.style.display='none'; Codehighlighter1_38_2749_Open_Image.style.display='inline'; Codehighlighter1_38_2749_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;FontDemo&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;JPanel&nbsp;</span><span id="Codehighlighter1_38_2749_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_38_2749_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_81_305_Open_Image" onclick="this.style.display='none'; Codehighlighter1_81_305_Open_Text.style.display='none'; Codehighlighter1_81_305_Closed_Image.style.display='inline'; Codehighlighter1_81_305_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_81_305_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_81_305_Closed_Text.style.display='none'; Codehighlighter1_81_305_Open_Image.style.display='inline'; Codehighlighter1_81_305_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</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;main(String[]&nbsp;args)&nbsp;</span><span id="Codehighlighter1_81_305_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_81_305_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JFrame&nbsp;f&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;JFrame();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setTitle(</span><span style="color: #000000">"</span><span style="color: #000000">TWaver中文社区</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setContentPane(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;FontDemo());<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setSize(</span><span style="color: #000000">800</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">600</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setLocationRelativeTo(</span><span style="color: #0000ff">null</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setVisible(</span><span style="color: #0000ff">true</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;TDataBox&nbsp;box&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;TDataBox();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;BarChart&nbsp;chart&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;BarChart(box);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.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;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;times&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1000</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.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;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;style&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Font.BOLD;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.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;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">16</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_536_580_Open_Image" onclick="this.style.display='none'; Codehighlighter1_536_580_Open_Text.style.display='none'; Codehighlighter1_536_580_Closed_Image.style.display='inline'; Codehighlighter1_536_580_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_536_580_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_536_580_Closed_Text.style.display='none'; Codehighlighter1_536_580_Open_Image.style.display='inline'; Codehighlighter1_536_580_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;FontDemo()&nbsp;</span><span id="Codehighlighter1_536_580_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_536_580_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initBox();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initChart();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initGUI();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_607_788_Open_Image" onclick="this.style.display='none'; Codehighlighter1_607_788_Open_Text.style.display='none'; Codehighlighter1_607_788_Closed_Image.style.display='inline'; Codehighlighter1_607_788_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_607_788_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_607_788_Closed_Text.style.display='none'; Codehighlighter1_607_788_Open_Image.style.display='inline'; Codehighlighter1_607_788_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;initGUI()&nbsp;</span><span id="Codehighlighter1_607_788_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_607_788_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.setLayout(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;BorderLayout());<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JScrollPane&nbsp;pane&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;JScrollPane(chart.getLegendPane());<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.add(chart,&nbsp;BorderLayout.CENTER);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.add(pane,&nbsp;BorderLayout.EAST);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_815_2396_Open_Image" onclick="this.style.display='none'; Codehighlighter1_815_2396_Open_Text.style.display='none'; Codehighlighter1_815_2396_Closed_Image.style.display='inline'; Codehighlighter1_815_2396_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_815_2396_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_815_2396_Closed_Text.style.display='none'; Codehighlighter1_815_2396_Open_Image.style.display='inline'; Codehighlighter1_815_2396_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;initBox()&nbsp;</span><span id="Codehighlighter1_815_2396_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_815_2396_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;List&nbsp;localFonts&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArrayList();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;nativeFonts&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArrayList();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;get&nbsp;all&nbsp;available&nbsp;fontFamily&nbsp;names</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Font[]&nbsp;fonts&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;SunGraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();<br />
<img id="Codehighlighter1_1065_1246_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1065_1246_Open_Text.style.display='none'; Codehighlighter1_1065_1246_Closed_Image.style.display='inline'; Codehighlighter1_1065_1246_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1065_1246_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1065_1246_Closed_Text.style.display='none'; Codehighlighter1_1065_1246_Open_Image.style.display='inline'; Codehighlighter1_1065_1246_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&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;fonts.length;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_1065_1246_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_1065_1246_Open_Text"><span style="color: #000000">{<br />
<img alt="" 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: #008000">//</span><span style="color: #008000">&nbsp;separate&nbsp;logical&nbsp;and&nbsp;native&nbsp;font</span><span style="color: #008000"><br />
<img id="Codehighlighter1_1161_1196_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1161_1196_Open_Text.style.display='none'; Codehighlighter1_1161_1196_Closed_Image.style.display='inline'; Codehighlighter1_1161_1196_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1161_1196_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1161_1196_Closed_Text.style.display='none'; Codehighlighter1_1161_1196_Open_Image.style.display='inline'; Codehighlighter1_1161_1196_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(SunGraphicsEnvironment.isLogicalFont(fonts[i]))&nbsp;</span><span id="Codehighlighter1_1161_1196_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_1161_1196_Open_Text"><span style="color: #000000">{<br />
<img alt="" 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;localFonts.add(fonts[i]);<br />
<img alt="" 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 id="Codehighlighter1_1206_1242_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1206_1242_Open_Text.style.display='none'; Codehighlighter1_1206_1242_Closed_Image.style.display='inline'; Codehighlighter1_1206_1242_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1206_1242_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1206_1242_Closed_Text.style.display='none'; Codehighlighter1_1206_1242_Open_Image.style.display='inline'; Codehighlighter1_1206_1242_Open_Text.style.display='inline';" alt="" 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">else</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1206_1242_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_1206_1242_Open_Text"><span style="color: #000000">{<br />
<img alt="" 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;nativeFonts.add(fonts[i]);<br />
<img alt="" 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 alt="" 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 alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">/////////////&nbsp;localFonts&nbsp;test&nbsp;/////////////</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_1364_1783_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1364_1783_Open_Text.style.display='none'; Codehighlighter1_1364_1783_Closed_Image.style.display='inline'; Codehighlighter1_1364_1783_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1364_1783_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1364_1783_Closed_Text.style.display='none'; Codehighlighter1_1364_1783_Open_Image.style.display='inline'; Codehighlighter1_1364_1783_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&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;localFonts.size();&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_1364_1783_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_1364_1783_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Font&nbsp;font&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Font)&nbsp;localFonts.get(i);<br />
<img alt="" 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">long</span><span style="color: #000000">&nbsp;start&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.currentTimeMillis();<br />
<img id="Codehighlighter1_1486_1513_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1486_1513_Open_Text.style.display='none'; Codehighlighter1_1486_1513_Closed_Image.style.display='inline'; Codehighlighter1_1486_1513_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1486_1513_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1486_1513_Closed_Text.style.display='none'; Codehighlighter1_1486_1513_Open_Image.style.display='inline'; Codehighlighter1_1486_1513_Open_Text.style.display='inline';" alt="" 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;k&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;k&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;times;&nbsp;k</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_1486_1513_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_1486_1513_Open_Text"><span style="color: #000000">{<br />
<img alt="" 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;createFont(font);<br />
<img alt="" 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 alt="" 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">long</span><span style="color: #000000">&nbsp;spendTime&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.currentTimeMillis()&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;start;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;n&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Node();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n.setName(font.getName());<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n.putChartValue(spendTime);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n.putChartColor(Color.GREEN);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.addElement(n);<br />
<img alt="" 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: #008000">//</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("&gt;"&nbsp;+&nbsp;spendTime&nbsp;+&nbsp;"\t"&nbsp;+&nbsp;font.getName());</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">\n/////////////&nbsp;nativeFonts&nbsp;test&nbsp;/////////////</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_1905_2323_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1905_2323_Open_Text.style.display='none'; Codehighlighter1_1905_2323_Closed_Image.style.display='inline'; Codehighlighter1_1905_2323_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1905_2323_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1905_2323_Closed_Text.style.display='none'; Codehighlighter1_1905_2323_Open_Image.style.display='inline'; Codehighlighter1_1905_2323_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&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;nativeFonts.size();&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_1905_2323_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_1905_2323_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Font&nbsp;font&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Font)&nbsp;nativeFonts.get(i);<br />
<img alt="" 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">long</span><span style="color: #000000">&nbsp;start&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.currentTimeMillis();<br />
<img id="Codehighlighter1_2028_2055_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2028_2055_Open_Text.style.display='none'; Codehighlighter1_2028_2055_Closed_Image.style.display='inline'; Codehighlighter1_2028_2055_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_2028_2055_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_2028_2055_Closed_Text.style.display='none'; Codehighlighter1_2028_2055_Open_Image.style.display='inline'; Codehighlighter1_2028_2055_Open_Text.style.display='inline';" alt="" 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;k&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;k&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;times;&nbsp;k</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_2028_2055_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_2028_2055_Open_Text"><span style="color: #000000">{<br />
<img alt="" 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;createFont(font);<br />
<img alt="" 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 alt="" 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">long</span><span style="color: #000000">&nbsp;spendTime&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.currentTimeMillis()&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;start;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;n&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Node();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n.setName(font.getName());<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n.putChartValue(spendTime);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n.putChartColor(Color.RED);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;box.addElement(n);<br />
<img alt="" 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: #008000">//</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("&gt;"&nbsp;+&nbsp;spendTime&nbsp;+&nbsp;"\t"&nbsp;+&nbsp;font.getName());</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_2435_2518_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2435_2518_Open_Text.style.display='none'; Codehighlighter1_2435_2518_Closed_Image.style.display='inline'; Codehighlighter1_2435_2518_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_2435_2518_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_2435_2518_Closed_Text.style.display='none'; Codehighlighter1_2435_2518_Open_Image.style.display='inline'; Codehighlighter1_2435_2518_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;createFont(Font&nbsp;font)&nbsp;</span><span id="Codehighlighter1_2435_2518_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_2435_2518_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;font.deriveFont(style,&nbsp;size);</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Font(font.getName(),&nbsp;style,&nbsp;size);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_2547_2747_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2547_2747_Open_Text.style.display='none'; Codehighlighter1_2547_2747_Closed_Image.style.display='inline'; Codehighlighter1_2547_2747_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_2547_2747_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_2547_2747_Closed_Text.style.display='none'; Codehighlighter1_2547_2747_Open_Image.style.display='inline'; Codehighlighter1_2547_2747_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;initChart()&nbsp;</span><span id="Codehighlighter1_2547_2747_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_2547_2747_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chart.setLegendLayout(TWaverConst.LEGEND_LAYOUT_VERTICAL);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chart.setLegendOrientation(TWaverConst.LABEL_ORIENTATION_HORIZONTAL);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chart.setYScaleTextVisible(</span><span style="color: #0000ff">true</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chart.setShadowOffset(</span><span style="color: #000000">1</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
</font></span></span>
<p><br />
<br />
<font face="宋体" size="4">1.4测试结果<br />
</font><img height="596" alt="" src="http://www.blogjava.net/images/blogjava_net/swing/blog/1.4.png" width="798" border="0" /><br />
<br />
<font face="宋体" size="4">1.6测试结果<br />
<img height="581" alt="" src="http://www.blogjava.net/images/blogjava_net/swing/blog/1.6.png" width="823" border="0" /></font></p>
<p><br />
<br />
<a href="http://twaver.servasoft.com/?p=1320">原帖地址</a></span></span></p>
 <img src ="http://www.blogjava.net/Swing/aggbug/327745.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Swing/" target="_blank">zht</a> 2010-08-02 21:32 <a href="http://www.blogjava.net/Swing/archive/2010/08/02/327745.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中取JVM中内存的方法</title><link>http://www.blogjava.net/Swing/archive/2008/04/18/194026.html</link><dc:creator>zht</dc:creator><author>zht</author><pubDate>Fri, 18 Apr 2008 06:10:00 GMT</pubDate><guid>http://www.blogjava.net/Swing/archive/2008/04/18/194026.html</guid><wfw:comment>http://www.blogjava.net/Swing/comments/194026.html</wfw:comment><comments>http://www.blogjava.net/Swing/archive/2008/04/18/194026.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/Swing/comments/commentRss/194026.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Swing/services/trackbacks/194026.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;Runtime runtime = Runtime.getRuntime();<br />
&nbsp;&nbsp;long total = runtime.totalMemory();</p>
<p>&nbsp;&nbsp;long free = runtime.freeMemory();<br />
&nbsp; System.out.println(total+"-"+free);</p>
<br />
totalMemory()<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Returns the total amount of memory in the Java virtual machine.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * The value returned by this method may vary over time, depending on <br />
&nbsp;&nbsp;&nbsp;&nbsp; * the host environment.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * &lt;p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Note that the amount of memory required to hold an object of any <br />
&nbsp;&nbsp;&nbsp;&nbsp; * given type may be implementation-dependent.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * <br />
&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp; the total amount of memory currently available for current <br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and future objects, measured in bytes.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
freeMemory()<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Returns the amount of free memory in the Java Virtual Machine.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Calling the <br />
&nbsp;&nbsp;&nbsp;&nbsp; * &lt;code&gt;gc&lt;/code&gt; method may result in increasing the value returned <br />
&nbsp;&nbsp;&nbsp;&nbsp; * by &lt;code&gt;freeMemory.&lt;/code&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; *<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp; an approximation to the total amount of memory currently<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; available for future allocated objects, measured in bytes.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
<br />
通过这个方法，可以写一个类似于Windows任务管理器的面板：<br />
<img height="126" alt="" src="http://www.blogjava.net/images/blogjava_net/swing/TWaver/nc.png" width="244" border="0" />
<img src ="http://www.blogjava.net/Swing/aggbug/194026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Swing/" target="_blank">zht</a> 2008-04-18 14:10 <a href="http://www.blogjava.net/Swing/archive/2008/04/18/194026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Reflect&amp;Proxy</title><link>http://www.blogjava.net/Swing/archive/2008/04/03/190564.html</link><dc:creator>zht</dc:creator><author>zht</author><pubDate>Thu, 03 Apr 2008 02:57:00 GMT</pubDate><guid>http://www.blogjava.net/Swing/archive/2008/04/03/190564.html</guid><wfw:comment>http://www.blogjava.net/Swing/comments/190564.html</wfw:comment><comments>http://www.blogjava.net/Swing/archive/2008/04/03/190564.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Swing/comments/commentRss/190564.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Swing/services/trackbacks/190564.html</trackback:ping><description><![CDATA[<span style="color: #008000">Reflect&amp;Proxy<br />
<br />
Reflect&amp;Proxy are two functions provided by java,<br />
Following is some example about how to use it.<br />
<br />
1.Reflect<br />
By reflect, the Class instance can be created, not using 'new' method<br />
as following:<br />
(1)Creating the class instance:<br />
&nbsp;Class clazz = Class.forName("twaver.Node");//Node.class;<br />
&nbsp;Constructor cs = clazz.getConstructor(new Class[] { Object.class });<br />
&nbsp;Object object = cs.newInstance(new Object[] { "ID-679" });<br />
&nbsp;@param parameterTypes the parameter array<br />
&nbsp;new Class[] { Object.class }<br />
&nbsp;means that the process will use the construcor <br />
&nbsp;which has one parameter to create the class instance.<br />
&nbsp;cs.newInstance method will create the class instance with the parameter "new Object[] { "ID-679" }"<br />
(2)Getting the class method:<br />
&nbsp;Method getIDMethod = clazz.getMethod("getID", new Class[] {});<br />
&nbsp;Method setNameMethod = clazz.getMethod("setName", new Class[] { String.class });<br />
&nbsp;@param name the name of the method<br />
&nbsp;@param parameterTypes the list of parameters<br />
&nbsp;setNameMethod.invoke(object, new Object[] { "todd.zhang" });<br />
&nbsp;Invokes the setNameMthod of object instance with the parameter&nbsp; new Object[] { "todd.zhang" }<br />
<br />
<br />
&nbsp;<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: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ReflectTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</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;main(String[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Node&nbsp;node&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Node(</span><span style="color: #000000">"</span><span style="color: #000000">ID-679</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.setName(</span><span style="color: #000000">"</span><span style="color: #000000">todd.zhang</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(node.getID());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(node.getName());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">-----------------------</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;clazz&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Class.forName(</span><span style="color: #000000">"</span><span style="color: #000000">twaver.Node</span><span style="color: #000000">"</span><span style="color: #000000">);</span><span style="color: #008000">//</span><span style="color: #008000">Node.class;</span><span style="color: #008000"><br />
</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor&nbsp;cs&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;clazz.getConstructor(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Class[]&nbsp;{&nbsp;Object.</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;getIDMethod&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;clazz.getMethod(</span><span style="color: #000000">"</span><span style="color: #000000">getID</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Class[]&nbsp;{});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;setNameMethod&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;clazz.getMethod(</span><span style="color: #000000">"</span><span style="color: #000000">setName</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Class[]&nbsp;{&nbsp;String.</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;getNameMethod&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;clazz.getMethod(</span><span style="color: #000000">"</span><span style="color: #000000">getName</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Class[]&nbsp;{});<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;object&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cs.newInstance(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[]&nbsp;{&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">ID-679</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setNameMethod.invoke(object,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[]&nbsp;{&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">todd.zhang</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;});<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(getIDMethod.invoke(object,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[]&nbsp;{}));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(getNameMethod.invoke(object,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[]&nbsp;{}));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<br />
<br />
2.Proxy<br />
Proxy is an application of reflect function.<br />
&nbsp;ClassLoader classLoader = ProxyAnything.class.getClassLoader();<br />
&nbsp;Class[] interfaces = new Class[] { Interface_A.class, Interface_B.class };<br />
&nbsp;//the interface array that the proxy will realize<br />
&nbsp;InvocationHandler handler = new ProxyAnything();<br />
&nbsp;//the handler of the proxy , each invoked method of Interface_A and Interface_B will be hold up by handler<br />
&nbsp;//the method invoke will turn to the handler first, and hanlder will deside how to deal with the invoke.<br />
&nbsp;Proxy proxy = (Proxy) Proxy.newProxyInstance(classLoader, interfaces, handler);<br />
&nbsp;//it is like the implement of interface ,so it can be transform to interface compulsively.<br />
&nbsp;proxy instanceof Interface_A will be true<br />
&nbsp;<br />
&nbsp;Interface_A a = (Interface_A) proxy;<br />
&nbsp;Interface_B b = (Interface_B) proxy;<br />
&nbsp;a.do_A1();<br />
&nbsp;b.do_B2();<br />
<br />
InvocationHandler may proxy sereval class,<br />
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable <br />
the proxy can be used to judge which it is.<br />
the proxy&nbsp;just is a &nbsp;rind, each operation will be deal with hanlder<br />
<br />
</span>
<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"><br />
</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;Interface_A&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_A1();<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_A2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_A3();<br />
}<br />
<br />
</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;Interface_B&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_B1();<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_B2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_B3();<br />
}<br />
<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ProxyAnything&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;InvocationHandler&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Interface_A&nbsp;businessA;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Interface_B&nbsp;businessB;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;ProxyAnything()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.businessA&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Interface_A()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_A1()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">doing&nbsp;A1</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_A2()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">doing&nbsp;A2</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_A3()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">doing&nbsp;A3</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.businessB&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Interface_B()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_B1()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">doing&nbsp;B1</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_B2()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">doing&nbsp;B2</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;do_B3()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">doing&nbsp;B3</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Object&nbsp;invoke(Object&nbsp;proxy,&nbsp;Method&nbsp;m,&nbsp;Object[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Throwable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(m.getDeclaringClass()&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;Interface_A.</span><span style="color: #0000ff">class</span><span style="color: #000000">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(m.getName().equals(</span><span style="color: #000000">"</span><span style="color: #000000">do_A3</span><span style="color: #000000">"</span><span style="color: #000000">))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">you&nbsp;can&nbsp;not&nbsp;invoke&nbsp;do_A3</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m.invoke(</span><span style="color: #0000ff">this</span><span style="color: #000000">.businessA,&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(m.getDeclaringClass()&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;Interface_B.</span><span style="color: #0000ff">class</span><span style="color: #000000">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(m.getName()&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;is&nbsp;called.</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m.invoke(</span><span style="color: #0000ff">this</span><span style="color: #000000">.businessB,&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</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;main(String[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassLoader&nbsp;classLoader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ProxyAnything.</span><span style="color: #0000ff">class</span><span style="color: #000000">.getClassLoader();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class[]&nbsp;interfaces&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Class[]&nbsp;{&nbsp;Interface_A.</span><span style="color: #0000ff">class</span><span style="color: #000000">,&nbsp;Interface_B.</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InvocationHandler&nbsp;handler&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ProxyAnything();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Proxy&nbsp;proxy&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Proxy)&nbsp;Proxy.newProxyInstance(classLoader,&nbsp;interfaces,&nbsp;handler);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(proxy&nbsp;</span><span style="color: #0000ff">instanceof</span><span style="color: #000000">&nbsp;Interface_A)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">proxy&nbsp;instanceof&nbsp;Interface_A</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;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(proxy&nbsp;</span><span style="color: #0000ff">instanceof</span><span style="color: #000000">&nbsp;Interface_B)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">proxy&nbsp;instanceof&nbsp;Interface_B</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Interface_A&nbsp;a&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Interface_A)&nbsp;proxy;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Interface_B&nbsp;b&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Interface_B)&nbsp;proxy;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.do_A1();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.do_A2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.do_A3();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.do_B1();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.do_B2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.do_B3();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
<img src ="http://www.blogjava.net/Swing/aggbug/190564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Swing/" target="_blank">zht</a> 2008-04-03 10:57 <a href="http://www.blogjava.net/Swing/archive/2008/04/03/190564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene学习</title><link>http://www.blogjava.net/Swing/archive/2007/10/30/156858.html</link><dc:creator>zht</dc:creator><author>zht</author><pubDate>Tue, 30 Oct 2007 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/Swing/archive/2007/10/30/156858.html</guid><wfw:comment>http://www.blogjava.net/Swing/comments/156858.html</wfw:comment><comments>http://www.blogjava.net/Swing/archive/2007/10/30/156858.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/Swing/comments/commentRss/156858.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Swing/services/trackbacks/156858.html</trackback:ping><description><![CDATA[<blockquote>
<p><span style="color: #008000">(转)</span></p>
<p><span style="color: #008000">本文首先介绍了Lucene的一些基本概念，然后开发了一个应用程序演示了利用Lucene建立索引并在该索引上进行搜索的过程。</span></p>
</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><a name="N1004B"><span class="atitle"><span style="color: #008000">Lucene 简介</span></span></a></p>
<p><span style="color: #008000">Lucene 是一个基于 Java 的全文信息检索工具包，它不是一个完整的搜索应用程序，而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta 家族中的一个开源项目。也是目前最为流行的基于 Java 开源全文检索工具包。</span></p>
<p><span style="color: #008000">目前已经有很多应用程序的搜索功能是基于 Lucene 的，比如 Eclipse 的帮助系统的搜索功能。Lucene 能够为文本类型的数据建立索引，所以你只要能把你要索引的数据格式转化的文本的，Lucene 就能对你的文档进行索引和搜索。比如你要对一些 HTML 文档，PDF 文档进行索引的话你就首先需要把 HTML 文档和 PDF 文档转化成文本格式的，然后将转化后的内容交给 Lucene 进行索引，然后把创建好的索引文件保存到磁盘或者内存中，最后根据用户输入的查询条件在索引文件上进行查询。不指定要索引的文档的格式也使 Lucene 能够几乎适用于所有的搜索应用程序。</span></p>
<p><span style="color: #008000">图 1 表示了搜索应用程序和 Lucene 之间的关系，也反映了利用 Lucene 构建搜索应用程序的流程：</span></p>
<br />
<a name="N1005C"><strong><span style="color: #008000">图1. 搜索应用程序和 Lucene 之间的关系</span></strong></a><br />
<span style="color: #008000"><img alt="图1. 搜索应用程序和 Lucene 之间的关系" src="http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/fig001.jpg" /> <br />
<br />
</span>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><span style="color: #008000"><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N10066"><span class="atitle"><span style="color: #008000">索引和搜索</span></span></a></p>
<p><span style="color: #008000">索引是现代搜索引擎的核心，建立索引的过程就是把源数据处理成非常方便查询的索引文件的过程。为什么索引这么重要呢，试想你现在要在大量的文档中搜索含有某个关键词的文档，那么如果不建立索引的话你就需要把这些文档顺序的读入内存，然后检查这个文章中是不是含有要查找的关键词，这样的话就会耗费非常多的时间，想想搜索引擎可是在毫秒级的时间内查找出要搜索的结果的。这就是由于建立了索引的原因，你可以把索引想象成这样一种数据结构，他能够使你快速的随机访问存储在索引中的关键词，进而找到该关键词所关联的文档。Lucene 采用的是一种称为反向索引（inverted index）的机制。反向索引就是说我们维护了一个词/短语表，对于这个表中的每个词/短语，都有一个链表描述了有哪些文档包含了这个词/短语。这样在用户输入查询条件的时候，就能非常快的得到搜索结果。我们将在本系列文章的第二部分详细介绍 Lucene 的索引机制，由于 Lucene 提供了简单易用的 API，所以即使读者刚开始对全文本进行索引的机制并不太了解，也可以非常容易的使用 Lucene 对你的文档实现索引。</span></p>
<p><span style="color: #008000">对文档建立好索引后，就可以在这些索引上面进行搜索了。搜索引擎首先会对搜索的关键词进行解析，然后再在建立好的索引上面进行查找，最终返回和用户输入的关键词相关联的文档。</span></p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><span style="color: #008000"><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N10072"><span class="atitle"><span style="color: #008000">Lucene 软件包分析</span></span></a></p>
<p><span style="color: #008000">Lucene 软件包的发布形式是一个 JAR 文件，下面我们分析一下这个 JAR 文件里面的主要的 JAVA 包，使读者对之有个初步的了解。</span></p>
<p><span style="color: #008000">Package: org.apache.lucene.document</span></p>
<p><span style="color: #008000">这个包提供了一些为封装要索引的文档所需要的类，比如 Document, Field。这样，每一个文档最终被封装成了一个 Document 对象。</span></p>
<p><span style="color: #008000">Package: org.apache.lucene.analysis</span></p>
<p><span style="color: #008000">这个包主要功能是对文档进行分词，因为文档在建立索引之前必须要进行分词，所以这个包的作用可以看成是为建立索引做准备工作。</span></p>
<p><span style="color: #008000">Package: org.apache.lucene.index</span></p>
<p><span style="color: #008000">这个包提供了一些类来协助创建索引以及对创建好的索引进行更新。这里面有两个基础的类：IndexWriter 和 IndexReader，其中 IndexWriter 是用来创建索引并添加文档到索引中的，IndexReader 是用来删除索引中的文档的。</span></p>
<p><span style="color: #008000">Package: org.apache.lucene.search</span></p>
<p><span style="color: #008000">这个包提供了对在建立好的索引上进行搜索所需要的类。比如 IndexSearcher 和 Hits, IndexSearcher 定义了在指定的索引上进行搜索的方法，Hits 用来保存搜索得到的结果。</span></p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><span style="color: #008000"><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N10093"><span class="atitle"><span style="color: #008000">一个简单的搜索应用程序</span></span></a></p>
<p><span style="color: #008000">假设我们的电脑的目录中含有很多文本文档，我们需要查找哪些文档含有某个关键词。为了实现这种功能，我们首先利用 Lucene 对这个目录中的文档建立索引，然后在建立好的索引中搜索我们所要查找的文档。通过这个例子读者会对如何利用 Lucene 构建自己的搜索应用程序有个比较清楚的认识。</span></p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><span style="color: #008000"><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N1009C"><span class="atitle"><span style="color: #008000">建立索引</span></span></a></p>
<p><span style="color: #008000">为了对文档进行索引，Lucene 提供了五个基础的类，他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途：</span></p>
<p><strong><span style="color: #008000">Document</span></strong></p>
<p><span style="color: #008000">Document 是用来描述文档的，这里的文档可以指一个 HTML 页面，一封电子邮件，或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录，而每个 Field 对象就是记录的一个字段。</span></p>
<p><strong><span style="color: #008000">Field</span></strong></p>
<p><span style="color: #008000">Field 对象是用来描述一个文档的某个属性的，比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。</span></p>
<p><strong><span style="color: #008000">Analyzer</span></strong></p>
<p><span style="color: #008000">在一个文档被索引之前，首先需要对文档内容进行分词处理，这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类，它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。</span></p>
<p><strong><span style="color: #008000">IndexWriter</span></strong></p>
<p><span style="color: #008000">IndexWriter 是 Lucene 用来创建索引的一个核心的类，他的作用是把一个个的 Document 对象加到索引中来。</span></p>
<p><strong><span style="color: #008000">Directory</span></strong></p>
<p><span style="color: #008000">这个类代表了 Lucene 的索引的存储的位置，这是一个抽象类，它目前有两个实现，第一个是 FSDirectory，它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory，它表示一个存储在内存当中的索引的位置。</span></p>
<p><span style="color: #008000">熟悉了建立索引所需要的这些类后，我们就开始对某个目录下面的文本文件建立索引了，清单1给出了对某个目录下的文本文件建立索引的源代码。</span></p>
<br />
<a name="N100CB"><strong><span style="color: #008000">清单 1. 对文本文件建立索引</span></strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode"><span style="color: #008000">package TestLucene;
            import java.io.File;
            import java.io.FileReader;
            import java.io.Reader;
            import java.util.Date;
            import org.apache.lucene.analysis.Analyzer;
            import org.apache.lucene.analysis.standard.StandardAnalyzer;
            import org.apache.lucene.document.Document;
            import org.apache.lucene.document.Field;
            import org.apache.lucene.index.IndexWriter;
            /**
            * This class demonstrate the process of creating index with Lucene
            * for text files
            */
            public class TxtFileIndexer {
            public static void main(String[] args) throws Exception{
            //indexDir is the directory that hosts Lucene's index files
            File   indexDir = new File("D:\\luceneIndex");
            //dataDir is the directory that hosts the text files that to be indexed
            File   dataDir  = new File("D:\\luceneData");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            File[] dataFiles  = dataDir.listFiles();
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            long startTime = new Date().getTime();
            for(int i = 0; i &lt; dataFiles.length; i++){
            if(dataFiles[i].isFile() &amp;&amp; dataFiles[i].getName().endsWith(".txt")){
            System.out.println("Indexing file " + dataFiles[i].getCanonicalPath());
            Document document = new Document();
            Reader txtReader = new FileReader(dataFiles[i]);
            document.add(new Field("path", dataFiles[i].getCanonicalPath(),<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Field.Store.YES, Field.Index.TOKENIZED));
            document.add(new Field("contents", txtReader));
            indexWriter.addDocument(document);
            }
            }
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
            System.out.println("It takes " + (endTime - startTime)
            + " milliseconds to create index for the files in directory "
            + dataDir.getPath());
            }
            }
            </span></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><span style="color: #008000">在清单1中，我们注意到类 IndexWriter 的构造函数需要三个参数，第一个参数指定了所创建的索引要存放的位置，他可以是一个 File 对象，也可以是一个 FSDirectory 对象或者 RAMDirectory 对象。第二个参数指定了 Analyzer 类的一个实现，也就是指定这个索引是用哪个分词器对文挡内容进行分词。第三个参数是一个布尔型的变量，如果为 true 的话就代表创建一个新的索引，为 false 的话就代表在原来索引的基础上进行操作。接着程序遍历了目录下面的所有文本文档，并为每一个文本文档创建了一个 Document 对象。然后把文本文档的两个属性：路径和内容加入到了两个 Field 对象中，接着在把这两个 Field 对象加入到 Document 对象中，最后把这个文档用 IndexWriter 类的 add 方法加入到索引中去。这样我们便完成了索引的创建。接下来我们进入在建立好的索引上进行搜索的部分。</span></p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><span style="color: #008000"><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N100D7"><span class="atitle"><span style="color: #008000">搜索文档</span></span></a></p>
<p><span style="color: #008000">利用Lucene进行搜索就像建立索引一样也是非常方便的。在上面一部分中，我们已经为一个目录下的文本文档建立好了索引，现在我们就要在这个索引上进行搜索以找到包含某个关键词或短语的文档。Lucene提供了几个基础的类来完成这个过程，它们分别是呢IndexSearcher, Term, Query, TermQuery, Hits. 下面我们分别介绍这几个类的功能。</span></p>
<p><strong><span style="color: #008000">Query</span></strong></p>
<p><span style="color: #008000">这是一个抽象类，他有多个实现，比如TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query。</span></p>
<p><strong><span style="color: #008000">Term</span></strong></p>
<p><span style="color: #008000">Term是搜索的基本单位，一个Term对象有两个String类型的域组成。生成一个Term对象可以有如下一条语句来完成：Term term = new Term(&#8220;fieldName&#8221;,&#8221;queryWord&#8221;); 其中第一个参数代表了要在文档的哪一个Field上进行查找，第二个参数代表了要查询的关键词。</span></p>
<p><strong><span style="color: #008000">TermQuery</span></strong></p>
<p><span style="color: #008000">TermQuery是抽象类Query的一个子类，它同时也是Lucene支持的最为基本的一个查询类。生成一个TermQuery对象由如下语句完成： TermQuery termQuery = new TermQuery(new Term(&#8220;fieldName&#8221;,&#8221;queryWord&#8221;)); 它的构造函数只接受一个参数，那就是一个Term对象。</span></p>
<p><strong><span style="color: #008000">IndexSearcher</span></strong></p>
<p><span style="color: #008000">IndexSearcher是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引，所以可以有多个IndexSearcher的实例在一个索引上进行操作。</span></p>
<p><strong><span style="color: #008000">Hits</span></strong></p>
<p><span style="color: #008000">Hits是用来保存搜索的结果的。</span></p>
<p><span style="color: #008000">介绍完这些搜索所必须的类之后，我们就开始在之前所建立的索引上进行搜索了，清单2给出了完成搜索功能所需要的代码。</span></p>
<br />
<a name="N10106"><strong><span style="color: #008000">清单2 ：在建立好的索引上进行搜索</span></strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode"><span style="color: #008000">package TestLucene;
            import java.io.File;
            import org.apache.lucene.document.Document;
            import org.apache.lucene.index.Term;
            import org.apache.lucene.search.Hits;
            import org.apache.lucene.search.IndexSearcher;
            import org.apache.lucene.search.TermQuery;
            import org.apache.lucene.store.FSDirectory;
            /**
            * This class is used to demonstrate the
            * process of searching on an existing
            * Lucene index
            *
            */
            public class TxtFileSearcher {
            public static void main(String[] args) throws Exception{
            String queryStr = "lucene";
            //This is the directory that hosts the Lucene index
            File indexDir = new File("D:\\luceneIndex");
            FSDirectory directory = FSDirectory.getDirectory(indexDir,false);
            IndexSearcher searcher = new IndexSearcher(directory);
            if(!indexDir.exists()){
            System.out.println("The Lucene index is not exist");
            return;
            }
            Term term = new Term("contents",queryStr.toLowerCase());
            TermQuery luceneQuery = new TermQuery(term);
            Hits hits = searcher.search(luceneQuery);
            for(int i = 0; i &lt; hits.length(); i++){
            Document document = hits.doc(i);
            System.out.println("File: " + document.get("path"));
            }
            }
            }
            </span></pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><span style="color: #008000">在清单2中，类IndexSearcher的构造函数接受一个类型为Directory的对象，Directory是一个抽象类，它目前有两个子类：FSDirctory和RAMDirectory. 我们的程序中传入了一个FSDirctory对象作为其参数，代表了一个存储在磁盘上的索引的位置。构造函数执行完成后，代表了这个IndexSearcher以只读的方式打开了一个索引。然后我们程序构造了一个Term对象，通过这个Term对象，我们指定了要在文档的内容中搜索包含关键词&#8221;lucene&#8221;的文档。接着利用这个Term对象构造出TermQuery对象并把这个TermQuery对象传入到IndexSearcher的search方法中进行查询，返回的结果保存在Hits对象中。最后我们用了一个循环语句把搜索到的文档的路径都打印了出来。好了，我们的搜索应用程序已经开发完毕，怎么样，利用Lucene开发搜索应用程序是不是很简单。</span></p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><span style="color: #008000"><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N10112"><span class="atitle"><span style="color: #008000">总结</span></span></a></p>
<p><span style="color: #008000">本文首先介绍了 Lucene 的一些基本概念，然后开发了一个应用程序演示了利用 Lucene 建立索引并在该索引上进行搜索的过程。希望本文能够为学习 Lucene 的读者提供帮助。<br />
<br />
</p>
<p><a name="N10053"><span class="atitle">架构概览</span></a></p>
<p>图一显示了 Lucene 的索引机制的架构。Lucene 使用各种解析器对各种不同类型的文档进行解析。比如对于 HTML 文档，HTML 解析器会做一些预处理的工作，比如过滤文档中的 HTML 标签等等。HTML 解析器的输出的是文本内容，接着 Lucene 的分词器(Analyzer)从文本内容中提取出索引项以及相关信息，比如索引项的出现频率。接着 Lucene 的分词器把这些信息写到索引文件中。</p>
<p><br />
<a name="N1005E"><strong>图一：Lucene 索引机制架构</strong></a><br />
<img height="345" alt="图一：Lucene 索引机制架构" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/image002.jpg" width="438" border="0" /> <br />
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N1006E"><span class="atitle">用Lucene索引文档</span></a></p>
<p>接下来我将一步一步的来演示如何利用 Lucene 为你的文档创建索引。只要你能将要索引的文件转化成文本格式，Lucene 就能为你的文档建立索引。比如，如果你想为 HTML 文档或者 PDF 文档建立索引，那么首先你就需要从这些文档中提取出文本信息，然后把文本信息交给 Lucene 建立索引。我们接下来的例子用来演示如何利用 Lucene 为后缀名为 txt 的文件建立索引。</p>
<p>1． 准备文本文件</p>
<p>首先把一些以 txt 为后缀名的文本文件放到一个目录中，比如在 Windows 平台上，你可以放到 C:\\files_to_index 下面。</p>
<p>2． 创建索引</p>
<p>清单1是为我们所准备的文档创建索引的代码。</p>
<p><br />
<a name="N10083"><strong>清单1：用 Lucene 索引你的文档</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">package lucene.index;
            import java.io.File;
            import java.io.FileReader;
            import java.io.Reader;
            import java.util.Date;
            import org.apache.lucene.analysis.Analyzer;
            import org.apache.lucene.analysis.standard.StandardAnalyzer;
            import org.apache.lucene.document.Document;
            import org.apache.lucene.document.Field;
            import org.apache.lucene.index.IndexWriter;
            /**
            * This class demonstrates the process of creating an index with Lucene
            * for text files in a directory.
            */
            public class TextFileIndexer {
            public static void main(String[] args) throws Exception{
            //fileDir is the directory that contains the text files to be indexed
            File   fileDir  = new File("C:\\files_to_index ");
            //indexDir is the directory that hosts Lucene's index files
            File   indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            File[] textFiles  = fileDir.listFiles();
            long startTime = new Date().getTime();
            //Add documents to the index
            for(int i = 0; i &lt; textFiles.length; i++){
            if(textFiles[i].isFile() &gt;&gt; textFiles[i].getName().endsWith(".txt")){
            System.out.println("File " + textFiles[i].getCanonicalPath()
            + " is being indexed");
            Reader textReader = new FileReader(textFiles[i]);
            Document document = new Document();
            document.add(Field.Text("content",textReader));
            document.add(Field.Text("path",textFiles[i].getPath()));
            indexWriter.addDocument(document);
            }
            }
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
            System.out.println("It took " + (endTime - startTime)
            + " milliseconds to create an index for the files in the directory "
            + fileDir.getPath());
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>正如清单1所示，你可以利用 Lucene 非常方便的为文档创建索引。接下来我们分析一下清单1中的比较关键的代码，我们先从下面的一条语句开始看起。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">Analyzer luceneAnalyzer = new StandardAnalyzer();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>这条语句创建了类 StandardAnalyzer 的一个实例，这个类是用来从文本中提取出索引项的。它只是抽象类 Analyzer 的其中一个实现。Analyzer 也有一些其它的子类，比如 SimpleAnalyzer 等。</p>
<p>我们接着看另外一条语句：</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>这条语句创建了类 IndexWriter 的一个实例，该类也是 Lucene 索引机制里面的一个关键类。这个类能创建一个新的索引或者打开一个已存在的索引并为该所引添加文档。我们注意到该类的构造函数接受三个参数，第一个参数指定了存储索引文件的路径。第二个参数指定了在索引过程中使用什么样的分词器。最后一个参数是个布尔变量，如果值为真，那么就表示要创建一个新的索引，如果值为假，就表示打开一个已经存在的索引。</p>
<p>接下来的代码演示了如何添加一个文档到索引文件中。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">Document document = new Document();
            document.add(Field.Text("content",textReader));
            document.add(Field.Text("path",textFiles[i].getPath()));
            indexWriter.addDocument(document);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>首先第一行创建了类 Document 的一个实例，它由一个或者多个的域(Field)组成。你可以把这个类想象成代表了一个实际的文档，比如一个 HTML 页面，一个 PDF 文档，或者一个文本文件。而类 Document 中的域一般就是实际文档的一些属性。比如对于一个 HTML 页面，它的域可能包括标题，内容，URL 等。我们可以用不同类型的 Field 来控制文档的哪些内容应该索引，哪些内容应该存储。如果想获取更多的关于 Lucene 的域的信息，可以参考 Lucene 的帮助文档。代码的第二行和第三行为文档添加了两个域，每个域包含两个属性，分别是域的名字和域的内容。在我们的例子中两个域的名字分别是"content"和"path"。分别存储了我们需要索引的文本文件的内容和路径。最后一行把准备好的文档添加到了索引当中。</p>
<p>当我们把文档添加到索引中后，不要忘记关闭索引，这样才保证 Lucene 把添加的文档写回到硬盘上。下面的一句代码演示了如何关闭索引。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">indexWriter.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>利用清单1中的代码，你就可以成功的将文本文档添加到索引中去。接下来我们看看对索引进行的另外一种重要的操作，从索引中删除文档。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N100C9"><span class="atitle">从索引中删除文档</span></a></p>
<p>类IndexReader负责从一个已经存在的索引中删除文档，如清单2所示。</p>
<p><br />
<a name="N100D2"><strong>清单2：从索引中删除文档</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">File   indexDir = new File("C:\\luceneIndex");
            IndexReader ir = IndexReader.open(indexDir);
            ir.delete(1);
            ir.delete(new Term("path","C:\\file_to_index\lucene.txt"));
            ir.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>在清单2中，第二行用静态方法 IndexReader.open(indexDir) 初始化了类 IndexReader 的一个实例，这个方法的参数指定了索引的存储路径。类 IndexReader 提供了两种方法去删除一个文档，如程序中的第三行和第四行所示。第三行利用文档的编号来删除文档。每个文档都有一个系统自动生成的编号。第四行删除了路径为"C:\\file_to_index\lucene.txt"的文档。你可以通过指定文件路径来方便的删除一个文档。值得注意的是虽然利用上述代码删除文档使得该文档不能被检索到，但是并没有物理上删除该文档。Lucene 只是通过一个后缀名为 .delete 的文件来标记哪些文档已经被删除。既然没有物理上删除，我们可以方便的把这些标记为删除的文档恢复过来，如清单 3 所示，首先打开一个索引，然后调用方法 ir.undeleteAll() 来完成恢复工作。</p>
<p><br />
<a name="N100DF"><strong>清单3：恢复已删除文档</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">File   indexDir = new File("C:\\luceneIndex");
            IndexReader ir = IndexReader.open(indexDir);
            ir.undeleteAll();
            ir.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>你现在也许想知道如何物理上删除索引中的文档，方法也非常简单。清单 4 演示了这个过程。</p>
<p><br />
<a name="N100EC"><strong>清单4：如何物理上删除文档</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">File   indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,false);
            indexWriter.optimize();
            indexWriter.close();
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>在清单 4 中，第三行创建了类 IndexWriter 的一个实例，并且打开了一个已经存在的索引。第 4 行对索引进行清理，清理过程中将把所有标记为删除的文档物理删除。</p>
<p>Lucene 没有直接提供方法对文档进行更新，如果你需要更新一个文档，那么你首先需要把这个文档从索引中删除，然后把新版本的文档加入到索引中去。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N100FC"><span class="atitle">提高索引性能</span></a></p>
<p>利用 Lucene，在创建索引的工程中你可以充分利用机器的硬件资源来提高索引的效率。当你需要索引大量的文件时，你会注意到索引过程的瓶颈是在往磁盘上写索引文件的过程中。为了解决这个问题, Lucene 在内存中持有一块缓冲区。但我们如何控制 Lucene 的缓冲区呢？幸运的是，Lucene 的类 IndexWriter 提供了三个参数用来调整缓冲区的大小以及往磁盘上写索引文件的频率。</p>
<p>1．合并因子（mergeFactor）</p>
<p>这个参数决定了在 Lucene 的一个索引块中可以存放多少文档以及把磁盘上的索引块合并成一个大的索引块的频率。比如，如果合并因子的值是 10，那么当内存中的文档数达到 10 的时候所有的文档都必须写到磁盘上的一个新的索引块中。并且，如果磁盘上的索引块的隔数达到 10 的话，这 10 个索引块会被合并成一个新的索引块。这个参数的默认值是 10，如果需要索引的文档数非常多的话这个值将是非常不合适的。对批处理的索引来讲，为这个参数赋一个比较大的值会得到比较好的索引效果。</p>
<p>2．最小合并文档数</p>
<p>这个参数也会影响索引的性能。它决定了内存中的文档数至少达到多少才能将它们写回磁盘。这个参数的默认值是10，如果你有足够的内存，那么将这个值尽量设的比较大一些将会显著的提高索引性能。</p>
<p>3．最大合并文档数</p>
<p>这个参数决定了一个索引块中的最大的文档数。它的默认值是 Integer.MAX_VALUE，将这个参数设置为比较大的值可以提高索引效率和检索速度，由于该参数的默认值是整型的最大值，所以我们一般不需要改动这个参数。</p>
<p>清单 5 列出了这个三个参数用法，清单 5 和清单 1 非常相似，除了清单 5 中会设置刚才提到的三个参数。</p>
<p><br />
<a name="N1011A"><strong>清单5：提高索引性能</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">/**
            * This class demonstrates how to improve the indexing performance
            * by adjusting the parameters provided by IndexWriter.
            */
            public class AdvancedTextFileIndexer  {
            public static void main(String[] args) throws Exception{
            //fileDir is the directory that contains the text files to be indexed
            File   fileDir  = new File("C:\\files_to_index");
            //indexDir is the directory that hosts Lucene's index files
            File   indexDir = new File("C:\\luceneIndex");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            File[] textFiles  = fileDir.listFiles();
            long startTime = new Date().getTime();
            int mergeFactor = 10;
            int minMergeDocs = 10;
            int maxMergeDocs = Integer.MAX_VALUE;
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            indexWriter.mergeFactor = mergeFactor;
            indexWriter.minMergeDocs = minMergeDocs;
            indexWriter.maxMergeDocs = maxMergeDocs;
            //Add documents to the index
            for(int i = 0; i &lt; textFiles.length; i++){
            if(textFiles[i].isFile() &gt;&gt; textFiles[i].getName().endsWith(".txt")){
            Reader textReader = new FileReader(textFiles[i]);
            Document document = new Document();
            document.add(Field.Text("content",textReader));
            document.add(Field.Keyword("path",textFiles[i].getPath()));
            indexWriter.addDocument(document);
            }
            }
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
            System.out.println("MergeFactor: " + indexWriter.mergeFactor);
            System.out.println("MinMergeDocs: " + indexWriter.minMergeDocs);
            System.out.println("MaxMergeDocs: " + indexWriter.maxMergeDocs);
            System.out.println("Document number: " + textFiles.length);
            System.out.println("Time consumed: " + (endTime - startTime) + " milliseconds");
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>通过这个例子，我们注意到在调整缓冲区的大小以及写磁盘的频率上面 Lucene 给我们提供了非常大的灵活性。现在我们来看一下代码中的关键语句。如下的代码首先创建了类 IndexWriter 的一个实例，然后对它的三个参数进行赋值。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">int mergeFactor = 10;
            int minMergeDocs = 10;
            int maxMergeDocs = Integer.MAX_VALUE;
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            indexWriter.mergeFactor = mergeFactor;
            indexWriter.minMergeDocs = minMergeDocs;
            indexWriter.maxMergeDocs = maxMergeDocs;
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
</p>
<p>下面我们来看一下这三个参数取不同的值对索引时间的影响，注意参数值的不同和索引之间的关系。我们为这个实验准备了 10000 个测试文档。表 1 显示了测试结果。</p>
<p><br />
<a name="N10135"><strong>表1：测试结果</strong></a><br />
<img height="199" alt="表1：测试结果" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/table1.gif" width="502" border="0" /> <br />
</p>
<p>通过表 1，你可以清楚地看到三个参数对索引时间的影响。在实践中，你会经常的改变合并因子和最小合并文档数的值来提高索引性能。只要你有足够大的内存，你可以为合并因子和最小合并文档数这两个参数赋尽量大的值以提高索引效率，另外我们一般无需更改最大合并文档数这个参数的值，因为系统已经默认将它设置成了最大。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N10148"><span class="atitle">Lucene 索引文件结构分析</span></a></p>
<p>在分析 Lucene 的索引文件结构之前，我们先要理解反向索引（Inverted index）这个概念，反向索引是一种以索引项为中心来组织文档的方式，每个索引项指向一个文档序列，这个序列中的文档都包含该索引项。相反，在正向索引中，文档占据了中心的位置，每个文档指向了一个它所包含的索引项的序列。你可以利用反向索引轻松的找到那些文档包含了特定的索引项。Lucene正是使用了反向索引作为其基本的索引结构。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N10151"><span class="atitle">索引文件的逻辑视图</span></a></p>
<p>在Lucene 中有索引块的概念，每个索引块包含了一定数目的文档。我们能够对单独的索引块进行检索。图 2 显示了 Lucene 索引结构的逻辑视图。索引块的个数由索引的文档的总数以及每个索引块所能包含的最大文档数来决定。</p>
<p><br />
<a name="N1015C"><strong>图2：索引文件的逻辑视图</strong></a><br />
<img height="415" alt="图2：索引文件的逻辑视图" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/image004.jpg" width="467" border="0" /> <br />
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N1016C"><span class="atitle">Lucene 中的关键索引文件</span></a></p>
<p>下面的部分将会分析Lucene中的主要的索引文件，可能分析有些索引文件的时候没有包含文件的所有的字段，但不会影响到对索引文件的理解。</p>
<p>1．索引块文件</p>
<p>这个文件包含了索引中的索引块信息，这个文件包含了每个索引块的名字以及大小等信息。表 2 显示了这个文件的结构信息。</p>
<p><br />
<a name="N1017D"><strong>表2：索引块文件结构</strong></a><br />
<img height="198" alt="表2：索引块文件结构" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/table2.gif" width="568" border="0" /> <br />
</p>
<p>2．域信息文件</p>
<p>我们知道，索引中的文档由一个或者多个域组成，这个文件包含了每个索引块中的域的信息。表 3 显示了这个文件的结构。</p>
<p><br />
<a name="N10195"><strong>表3：域信息文件结构</strong></a><br />
<img height="179" alt="表3：域信息文件结构" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/table3.gif" width="567" border="0" /> <br />
</p>
<p>3．索引项信息文件</p>
<p>这是索引文件里面最核心的一个文件，它存储了所有的索引项的值以及相关信息，并且以索引项来排序。表 4 显示了这个文件的结构。</p>
<p><br />
<a name="N101AD"><strong>表4：索引项信息文件结构</strong></a><br />
<img height="252" alt="表4：索引项信息文件结构" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/table4.gif" width="568" border="0" /> <br />
</p>
<p>4．频率文件</p>
<p>这个文件包含了包含索引项的文档的列表，以及索引项在每个文档中出现的频率信息。如果Lucene在索引项信息文件中发现有索引项和搜索词相匹配。那么 Lucene 就会在频率文件中找有哪些文件包含了该索引项。表5显示了这个文件的一个大致的结构，并没有包含这个文件的所有字段。</p>
<p><br />
<a name="N101C5"><strong>表5：频率文件的结构</strong></a><br />
<img height="124" alt="表5：频率文件的结构" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/table5.gif" width="567" border="0" /> <br />
</p>
<p>5．位置文件</p>
<p>这个文件包含了索引项在每个文档中出现的位置信息，你可以利用这些信息来参与对索引结果的排序。表 6 显示了这个文件的结构</p>
<p><br />
<a name="N101DD"><strong>表6：位置文件的结构</strong></a><br />
<img height="69" alt="表6：位置文件的结构" src="http://www.ibm.com/developerworks/cn/java/wa-lucene/images/table6.gif" width="568" border="0" /> <br />
</p>
<p>到目前为止我们介绍了 Lucene 中的主要的索引文件结构，希望能对你理解 Lucene 的物理的存储结构有所帮助。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
</p>
<p><a name="N101F0"><span class="atitle">总结</span></a></p>
<p>目前已经有非常多的知名的组织正在使用 Lucene，比如，Lucene 为 Eclipse 的帮助系统，麻省理工学院的 OpenCourseWare 提供了搜索功能。通过阅读这篇文章，希望你能对 Lucene 的索引机制有所了解，并且你会发现利用 Lucene 创建索引是非常简单的事情。</p>
<p><br />
<br />
</p>
<p><a name="resources"><span class="atitle">参考资料 </span></a></p>
<p><strong>学习</strong><br />
</p>
<ul>
    <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library//wa-lucene/?S_TACT=105AGX52&amp;S_CMP=cn-a-j" target="_blank">英文原文</a> 。<br />
    <br />
    <li><a href="http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/">实战 Lucene: 初识 Lucene</a> 介绍了 Lucene 的一些基本概念，然后开发了一个应用程序演示了利用 Lucene 建立索引并在该索引上进行搜索的过程。 <br />
    <br />
    <li><a href="http://www.ibm.com/developerworks/web/library/j-lucene/?S_TACT=105AGX52&amp;S_CMP=cn-a-j">Parsing, indexing, and searching XML with Digester and Lucene</a> 是 Otis Gospodnetic 在 developerWorks 上发表的一篇关于利用 Lucene 和 Digester 来操作 XML 文档的文章。 <br />
    <br />
    <li><a href="http://www.ibm.com/developerworks/db2/library/techarticle/dm-0601chitiveli/?S_TACT=105AGX52&amp;S_CMP=cn-a-j">IBM Search and Index APIs (SIAPI) for WebSphere Information Integrator OmniFind Edition</a> 是 Srinivas Varma Chitiveli 在 developerWorks 上发表的一篇关于如何用 SIAPI 来构建搜索解决方案的文章。 <br />
    <br />
    <li><a href="http://lucene.apache.org/">Lucene的官方网站</a>：上面有大量的 Lucene 帮助文档。 <br />
    <br />
    <li><a href="http://lucene.sourceforge.net/talks/pisa/">一个关于 Lucene 的演讲</a>：是由 Lucene 最初的作者 Doug Cutting 在 Pisa 大学所作。 <br />
    <br />
    <li><a href="http://www.amazon.com/gp/product/020139829X/104-7111632-8247925?v=glance&amp;n=283155"><em>现代信息检索</em></a>是由 Ricardo Baeza-Yates 和 Berthier Ribeiro-Neto 所写的关于信息检索方面的一本著作。 <br />
    <br />
    <li><a href="http://www.ibm.com/developerworks/cn/web">developerWorks Web Architecture 专区</a>：上面有很多关于如何构建网站的技术文章。 <br />
    <br />
    </li>
</ul>
<p><br />
<strong>获得产品和技术</strong><br />
</p>
<ul>
    <li><a href="http://www.apache.org/dyn/closer.cgi/lucene/java/">下载</a> Lucene 最新版本。 <br />
    <br />
    </li>
</ul>
</span>
<img src ="http://www.blogjava.net/Swing/aggbug/156858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Swing/" target="_blank">zht</a> 2007-10-30 10:02 <a href="http://www.blogjava.net/Swing/archive/2007/10/30/156858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>