﻿<?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-Jiangshachina</title><link>http://www.blogjava.net/jiangshachina/</link><description>同是Java爱好者，相逢何必曾相识！&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;a cup of Java, cheers!</description><language>zh-cn</language><lastBuildDate>Thu, 24 Jul 2008 21:57:23 GMT</lastBuildDate><pubDate>Thu, 24 Jul 2008 21:57:23 GMT</pubDate><ttl>60</ttl><item><title>判定一个点是否在三角形内(原)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/07/24/217214.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Thu, 24 Jul 2008 09:02:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/07/24/217214.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/217214.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/07/24/217214.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/217214.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/217214.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 10pt;"><span style="font-size: 14pt;">判定一个点是否在三角形内</span></span></strong><br />
</div>
<span style="font-size: 10pt;">如何判定一个点P是否存在于指定的三角形ABC内，这肯定是一个简单的问题，本文仅用一个图形界面程序展示了该问题，有兴趣的朋友可以看看。(2008.07.24最后更新)<br />
<br />
在此处使用一种常见且简便的方法：<strong>如果三角形PAB，PAC和PBC的面积之和与三角形ABC的面积相等，即可判定点P在三角形ABC内(包括在三条边上)</strong>。<br />
可知，该方法的关键在于如何计算三角形的面积。幸运地是，当知道三角形顶点(A，B和C)的坐标((Ax, Ay)，(Bx, By)和(Cx, Cy))之后，即可计算出其面积：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">S&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"> |(Ax&nbsp;*&nbsp;By&nbsp;+&nbsp;Bx&nbsp;*&nbsp;Cy&nbsp;+&nbsp;Cx&nbsp;*&nbsp;Zy&nbsp;-&nbsp;Ay&nbsp;*&nbsp;Bx&nbsp;-&nbsp;By&nbsp;*&nbsp;Cx&nbsp;-&nbsp;Cy&nbsp;*&nbsp;Ax)&nbsp;/&nbsp;</span><span style="color: #000000;">2|</span></div>
<span style="font-size: 10pt;"><br />
关键的代码如下，<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;由给定的三个顶点的坐标，计算三角形面积。<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Point(java.awt.Point)代表点的坐标。</span><span style="color: #008000;"><br />
</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;">double</span><span style="color: #000000;">&nbsp;triangleArea(Point&nbsp;pos1,&nbsp;Point&nbsp;pos2,&nbsp;Point&nbsp;pos3)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Math.abs((pos1.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos2.y&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;pos2.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos3.y&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;pos3.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos1.y<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;pos2.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos1.y&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;pos3.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos2.y&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;pos1.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos3.y)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2.0D</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result;<br />
}</span></div>
<span style="font-size: 10pt;"><br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;判断点pos是否在指定的三角形内。</span><span style="color: #008000;"><br />
</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;">boolean</span><span style="color: #000000;">&nbsp;inTriangle(Point&nbsp;pos,&nbsp;Point&nbsp;posA,&nbsp;Point&nbsp;posB,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point&nbsp;posC)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;triangleArea&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;triangleArea(posA,&nbsp;posB,&nbsp;posC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;area&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;triangleArea(pos,&nbsp;posA,&nbsp;posB);<br />
&nbsp;&nbsp;&nbsp;&nbsp;area&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;triangleArea(pos,&nbsp;posA,&nbsp;posC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;area&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;triangleArea(pos,&nbsp;posB,&nbsp;posC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;epsilon&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0.0001</span><span style="color: #000000;">;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;由于浮点数的计算存在着误差，故指定一个足够小的数，用于判定两个面积是否(近似)相等。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(Math.abs(triangleArea&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;area)&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;epsilon)&nbsp;{<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;">true</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
}</span></div>
<span style="font-size: 10pt;"><br />
执行该应用程序，用鼠标在其中点击三次，即可绘制一个三角形，如下组图所示：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/jiangshachina/t01.PNG" width="300" height="200" /> <img alt="" src="http://www.blogjava.net/images/blogjava_net/jiangshachina/t02.PNG" width="300" height="200" /><br />
然后仅需移动鼠标，就会出现一个空心圆圈。如果圆圈的中心在三角内(包含在三条边上)，则圆圈显示为红色；否则，显示为蓝色。如下组图所示：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/jiangshachina/t03.PNG" width="300" height="200" /> <img alt="" src="http://www.blogjava.net/images/blogjava_net/jiangshachina/t04.PNG" width="300" height="200" /> <img alt="" src="http://www.blogjava.net/images/blogjava_net/jiangshachina/t05.PNG" width="300" height="200" /><br />
<br />
完整代码如下：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CanvasPanel&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;JPanel&nbsp;{<br />
<br />
&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;">long</span><span style="color: #000000;">&nbsp;serialVersionUID&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">6665936180725885346L</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Point&nbsp;firstPoint&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Point&nbsp;secondPoint&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Point&nbsp;thirdPoint&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CanvasPanel()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setBackground(Color.WHITE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addMouseListener(mouseAdapter);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addMouseMotionListener(mouseAdapter);<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;">void</span><span style="color: #000000;">&nbsp;paintComponent(Graphics&nbsp;g)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.paintComponent(g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;drawTriangel(g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&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;drawTriangel(Graphics&nbsp;g)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(firstPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;secondPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;secondPoint.x, secondPoint.y);<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;(thirdPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;thirdPoint.x, thirdPoint.y);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(secondPoint.x,&nbsp;secondPoint.y,&nbsp;thirdPoint.x, thirdPoint.y);<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;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;inTriangle(Point&nbsp;pos,&nbsp;Point&nbsp;posA,&nbsp;Point&nbsp;posB,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point&nbsp;posC)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;triangeArea&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;triangleArea(posA,&nbsp;posB,&nbsp;posC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;area&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;triangleArea(pos,&nbsp;posA,&nbsp;posB);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;area&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;triangleArea(pos,&nbsp;posA,&nbsp;posC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;area&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;triangleArea(pos,&nbsp;posB,&nbsp;posC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;epsilon&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0.0001</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(Math.abs(triangeArea&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;area)&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;epsilon)&nbsp;{<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;</span><span style="color: #0000ff;">true</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;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&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;">double</span><span style="color: #000000;">&nbsp;triangleArea(Point&nbsp;pos1,&nbsp;Point&nbsp;pos2,&nbsp;Point&nbsp;pos3)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Math.abs((pos1.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos2.y&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;pos2.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos3.y&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;pos3.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos1.y<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; </span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;pos2.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos1.y&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;pos3.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos2.y&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;pos1.x&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pos3.y)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2.0D</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;MouseInputAdapter&nbsp;mouseAdapter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;MouseInputAdapter()&nbsp;{<br />
<br />
&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;mouseReleased(MouseEvent&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point&nbsp;pos&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.getPoint();<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;(firstPoint&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstPoint&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pos;<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;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(secondPoint&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondPoint&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pos;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphics&nbsp;g&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CanvasPanel.</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.getGraphics();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CanvasPanel.</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.paintComponent(g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;secondPoint.x, secondPoint.y);<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;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(thirdPoint&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thirdPoint&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pos;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphics&nbsp;g&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CanvasPanel.</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.getGraphics();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CanvasPanel.</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.paintComponent(g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;secondPoint.x, secondPoint.y);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;thirdPoint.x, thirdPoint.y);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(secondPoint.x,&nbsp;secondPoint.y,&nbsp;thirdPoint.x, thirdPoint.y);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&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;mouseMoved(MouseEvent&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point&nbsp;pos&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.getPoint();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphics2D&nbsp;g2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(Graphics2D)&nbsp;CanvasPanel.</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.getGraphics();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CanvasPanel.</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.paintComponent(g2);<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;(firstPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;secondPoint&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g2.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;pos.x,&nbsp;pos.y);<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;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(firstPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;secondPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null </span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;thirdPoint&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g2.drawLine(firstPoint.x,&nbsp;firstPoint.y,&nbsp;pos.x,&nbsp;pos.y);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g2.drawLine(secondPoint.x,&nbsp;secondPoint.y,&nbsp;pos.x,&nbsp;pos.y);<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;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(firstPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;secondPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;"> </span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;thirdPoint&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</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;">if</span><span style="color: #000000;">&nbsp;(inTriangle(pos,&nbsp;firstPoint,&nbsp;secondPoint,&nbsp;thirdPoint))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g2.setColor(Color.RED);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;g2.setColor(Color.BLUE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;radius&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g2.drawOval(pos.x&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;radius,&nbsp;pos.y&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;radius,&nbsp;radius&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">, radius&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</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 />
</span></div>
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Triangle&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;JFrame&nbsp;{<br />
<br />
&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;">long</span><span style="color: #000000;">&nbsp;serialVersionUID&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1L</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;CanvasPanel&nbsp;mainPanel&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Triangle()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setTitle(</span><span style="color: #000000;">"</span><span style="color: #000000;">Triangle</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setSize(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Dimension(</span><span style="color: #000000;">300</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">200</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setResizable(</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container&nbsp;container&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;getContentPane();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.add(mainPanel);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setVisible(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&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;init()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mainPanel&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CanvasPanel();<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;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Triangle();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<span style="font-size: 10pt;"><br />
</span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/217214.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-07-24 17:02 <a href="http://www.blogjava.net/jiangshachina/archive/2008/07/24/217214.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>下一代Java Applet插件技术(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/07/14/214703.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Mon, 14 Jul 2008 11:56:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/07/14/214703.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/214703.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/07/14/214703.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/214703.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/214703.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 14pt;">下一代Java Applet插件技术</span></strong><br />
</div>
&nbsp;&nbsp;&nbsp; <span style="font-size: 10pt;">Java SE 6对Java桌面应用进行较大的升级，并启动了Java SE 6 Update N计划，该计划旨在简化JRE的大小，增进用户的安装体验，并提供了一个新的Applet浏览器插件，该插件将会随<a href="https://jdk6.dev.java.net/6u10ea.html">Java SE 6 Update 10</a>发布。<a href="http://java.sun.com/developer/technicalArticles/javase/newapplets/">本文</a>全面介绍了这个新插件的关键特性，并以<a href="http://www.nasa.gov/">NASA</a>的<a href="http://worldwind.arc.nasa.gov/java/">World Wind</a>为例介绍了该插件的应用。(2008.07.15最后更新)<br />
<br />
</span><span style="font-size: 10pt;">Applet回来了！<br />
为了在网络中传递你的程序，是时候再次考虑Java Applet技术了。<a href="http://jdk6.dev.java.net/6u10ea.html">下一代Java插件技术</a>以一种不同的，比过去更高效、更可靠的途径来运行Applet。现在你可以获得如下好处：<br />
</span>
<ul>
    <li><span style="font-size: 10pt;">
    增强的可靠性</span></li>
    <li><span style="font-size: 10pt;">
    改进的用户体验</span></li>
    <li><span style="font-size: 10pt;">
    在后台启动Applet</span></li>
    <li><span style="font-size: 10pt;">
    内建的JNLP支持</span></li>
    <li><span style="font-size: 10pt;">
    针对每个Applet的命令行参数</span></li>
    <li><span style="font-size: 10pt;">
    堆内存大小，Java 2D API加速选项</span></li>
    <li><span style="font-size: 10pt;">
    改进的Java/JavaScript程序设计语言集成</span></li>
    <li><span style="font-size: 10pt;">
    改进的Windows Vista支持</span></li>
    <li><span style="font-size: 10pt;">
    签名的Applet现在可以在Internet Explorer的保护模式中正常运行</span></li>
</ul>
<span style="font-size: 10pt;">
下一代Java插件提供了一种完全重新设计的架构，它将出现在<a href="http://jdk6.dev.java.net/6u10ea.html">Java SE 6 Update 10</a>中。该插件为运行在网络浏览器中的Applet提供了强大的新功能，它以向后兼容的方式改进了整个Applet的可靠性及功能。<br />
下一代Java插件最有意义的新特性是它内建支持通过JNLP文件启动Applet。使用JNLP文件格式作为Applet的描述符就能允许Applet马上复用之前为Java Web Start应用所写的JNLP扩展。<br />
<strong><br />
<span style="font-size: 12pt;">执行Applet的新途径</span></strong><br />
执行Applet的新途径在结构上与Java Web Start技术相似，但与浏览器整合的更为紧密。 Applet不在运行于网络浏览器内的JVM中，而是会启动一个独立的JVM进程去运行Applet。默认地，只有一个JVM将被启动，但你也能启动多个JVM，并且可以为每个Applet都设置命令行参数，所以你能影响堆内存的大小或其它的要求。<br />
<img alt="" src="http://java.sun.com/developer/technicalArticles/javase/newapplets/images/architecture.jpg" width="424" height="320" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><span style="font-size: 10pt;"><strong>Figure 1.</strong> <em>Applet Architecture</em></span><br />
<span style="font-size: 10pt;">
在上图中，云表示JVM实例。在浏览器内有一个小的，headless JVM被用于管理一个或多个客户端JVM之间的连接，这些JVM运行着Applet。在该图中，Duke表示Applet。其中，一个JVM实例运行着两个Applet，另一个运行着一个Applet。<br />
Applet直接从JNLP文件启动，它使用的JNLP文件与Java Web Start软件使用的描述符文件相同，并且允许使用比典型的"archive"，"code"和"cache_archive"更为强大的参数。<br />
新的插件提供了：<br />
</span>
<ul>
    <li><span style="font-size: 10pt;">
    能够访问之前仅由Java Web Start软件专用的高级JNLP扩展。之前有少部分参数能够使用，但有一些限制，现在这些限制则被去除。</span></li>
    <li><span style="font-size: 10pt;">
    通过Applet访问JNLP API。</span></li>
    <li><span style="font-size: 10pt;">
    支持PersistenceService和DownloadService。</span></li>
    <li><span style="font-size: 10pt;">
    能够控制堆内存大小，命令行参数，JRE版本选择和自动下载。你具有Java Web Start软件所拥有的相同功能。</span></li>
</ul>
<span style="font-size: 10pt;">
现在你就可以在Web页面中使用像下面这样的语句了：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">applet&nbsp;width</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;</span><span style="color: rgb(0, 0, 0);">500</span><span style="color: rgb(0, 0, 0);">&#8221;&nbsp;height</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;</span><span style="color: rgb(0, 0, 0);">500</span><span style="color: rgb(0, 0, 0);">&#8221;</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">param&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;jnlp_href&#8221;&nbsp;value</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;my_applet.jnlp&#8221;</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">applet</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">调用Applet生命周期方法init，start，stop和destroy会更为确定，并且已经改进了跨浏览器行为。完全支持Applet类装载器缓存，遗留的Applet生命周期及对向后兼容性的需求，并且这些行为都已得到了改进。<br />
Applet运行的就像一个由Java Web Start启动的应用。参数jnlp_href在Web页面和Applet的JNLP描述之间起到了桥接的作用。在如宽度与高度这样的特定方面，Applet标签与JNLP文件具有重叠的机制。<br />
一般地，你应该使用<a href="https://jdk6.dev.java.net/testDT.html">Deployment Toolkit</a>，这也是一个出现在Java SE 6 Update 10中的新工具，它能自动地为Applet标签生成HTML。<a href="https://jdk6.dev.java.net/deployment_advice.html">部署建议</a>指南展示了如何使用Deployment Toolkit简便地发布Applet。<br />
<br />
<strong><span style="font-size: 12pt;">配置Applet</span></strong><br />
现在也能更为简单地在多个方面来配置Applet，包括堆内存大小，需要被使用的Java版本，类加载器缓存，边界，及其它。<br />
&lt;applet&gt;与JNLP文件在针对某些参数时有重叠的机制。这些冲突可以用如下方法解决：<br />
</span>
<ul>
    <li><span style="font-size: 10pt;"><strong>width and height</strong>：这些属性将总是从&lt;applet&gt;，而不是JNLP文件，中获取。这是假设浏览器知道Applet在Web页面上应该显示多大，也只有浏览器才能支持相对于页面的宽度与高度(例如，width="50%")。</span></li>
    <li><span style="font-size: 10pt;">
    <strong>codebase</strong>：如果JNLP文件在&lt;jnlp&gt;标签中指定了一个绝对的codebase，那么就使用它。否则，将使用在<a href="https://jdk6.dev.java.net/plugin2/jnlp/#CODEBASE">codebase handling</a>一节中描述的规则进行组织。</span></li>
    <li><span style="font-size: 10pt;">
    <strong>code</strong>：当指定了jnlp_href参数，Applet的主类名将从main-class参数换成JNLP文件中的applet-desc标签，并且code属性会被忽略。注意，该特性允许你为经典Java插件写一个拥有反馈的Applet标签，但在新的Java插件中，该标签可使用更高级的功能。请见下面的"兼容性"一节。</span></li>
    <li><span style="font-size: 10pt;">
    任何一个由&lt;param&gt;标签指定的Applet参数将与JNLP文件中指定的参数进行合并。如果&lt;applet&gt;标签和JNLP文件都指定了同一个参数，&lt;applet&gt;标签中的版本将覆盖JNLP文件中的版本，除了参数java_arguments和java_version。</span></li>
    <li><span style="font-size: 10pt;">
    新的java_arguments和java_version参数在JNLP Applet中是不必要的。会替换为通过JNLP文件请求JRE版本或向JVM传递参数的机制。所以，命令行参数和JNLP文件请求的JRE版本将会覆盖HTML中为Applet指定的这些值。</span></li>
    <li><span style="font-size: 10pt;">
    特定的参数，例如image，boxbgcolor等等，在Applet的启动过程中是有用的。在HTML而不是JNLP文件中指定这些参数可能更好些，以便于在加载Web页面时就可立即获取它们，而不用再等到单独下载JNLP文件之后。</span></li>
</ul>
<span style="font-size: 10pt;">
过去，通过Java控制面板设置最大堆内存是有限制的。在新的Java插件中，这些限制被取消。现在Applet可以像命令行应用那样使用大量堆空间。<br />
指定一个比默认值大的堆空间：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">APPLET&nbsp;archive</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">my_applet.jar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;code</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">MyApplet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;width</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;height</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">PARAM&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">java_arguments</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;value</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">-Xmx128m</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">APPLET</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">指定一个非默认大小的堆内存以及一个Java 2D硬件加速器选项，该选项常通过JOGL使用OpenGL应用于Applet。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">APPLET&nbsp;archive</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">my_applet.jar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;code</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">MyApplet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;width</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;height</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">PARAM&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">java_arguments</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;value</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">-Xmx256m&nbsp;-Dsun.java2d.noddraw=true</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">APPLET</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">如果你喜欢，一个Applet可强制进入一个属于它自己的JVM实例，而与所有其它的Applet隔离开：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">param&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;separate_jvm&#8221;&nbsp;value</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">&#8221;&nbsp;</span><span style="color: rgb(0, 0, 0);">/&gt;</span></div>
<span style="font-size: 10pt;">当把某些桌面应用移植到Web浏览器时，这就有用了。<br />
你也能使特定的Applet运行在特定版本的JRE上，如下所示：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">j2se&nbsp;version</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;</span><span style="color: rgb(0, 0, 0);">1.4</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&#8221;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">j2se&nbsp;version</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;</span><span style="color: rgb(0, 0, 0);">1.5</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&#8221;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">当想针对特定版本的JRE，或Applet取代早期版本的选择机制(如同IE浏览器中的CLSID)，进行质量测评时，该方法就很有用了。如果请求了一个非常老的JRE版本，就会强制执行限制；如果Applet试图加载未签名的代码，将会提示用户。<br />
注意，因为支持JNLP的Java插件是在Java SE 6 Update 10中才首次出现的，所以指定像&#8220;1.4+&#8221;这样的版本基本上没有意义的。当需要&#8220;1.7+&#8221;时，这才有意义。<br />
另外，你可以在JNLP文件中使用&lt;update&gt;标签来显著降低第二次及接下来各次启动的时间。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">update&nbsp;check</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&#8221;background&#8221;</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">在这种情况下，将使用缓存中已有的Applet程序，并且在后台下载该应用的更新版本。在下次启动时，就会使用新版本。<br />
新的插件也能更好地对图像进行定制，在Applet被加载之前会展示该图像。image参数会以支持动画GIF文件作为目标，<a href="http://java.sun.com/javase/6/docs/technotes/guides/plugin/developer_guide/contents.html">Java Plug-in Developers' Guide</a>的<a href="http://java.sun.com/javase/6/docs/technotes/guides/plugin/developer_guide/special_attributes.html">Special Attributes</a>一节对此有描述。此外，现也支持如下新的参数：<br />
<strong>boxborder</strong><br />
一个布尔型参数，用于指定在Applet被加载之前是否在Applet区域的边缘绘制一个宽度一象素的边框。默认为true。我们建议将该值设置为false，特别是将一个动画GIF用作加载期图像时，以避免可能的闪烁。<br />
<strong>centerimage</strong><br />
一个布尔型参数，用于指定是否将加载期图像在Applet区域内居中显示，而不是从左上角起始。默认为false。<br />
使用参数boxborder和centerimage的例子：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">APPLET&nbsp;archive</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">large_archive.jar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;code</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">MyApplet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;width</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;height</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;!--</span><span style="color: rgb(0, 0, 0);">&nbsp;Use&nbsp;an&nbsp;animated&nbsp;GIF&nbsp;as&nbsp;an&nbsp;indeterminate&nbsp;progress&nbsp;bar<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">&nbsp;the&nbsp;applet&nbsp;is&nbsp;loading&nbsp;</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">PARAM&nbsp;NAME</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">image</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;VALUE</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">animated_gif.gif</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;!--</span><span style="color: rgb(0, 0, 0);">&nbsp;Turn&nbsp;off&nbsp;the&nbsp;box&nbsp;border&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;better&nbsp;blending&nbsp;</span><span style="color: rgb(0, 0, 255);">with</span><span style="color: rgb(0, 0, 0);">&nbsp;the<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;surrounding&nbsp;web&nbsp;page&nbsp;</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">PARAM&nbsp;NAME</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">boxborder</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;VALUE</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">false</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;!--</span><span style="color: rgb(0, 0, 0);">&nbsp;Center&nbsp;the&nbsp;image&nbsp;</span><span style="color: rgb(0, 0, 255);">in</span><span style="color: rgb(0, 0, 0);">&nbsp;the&nbsp;applet's&nbsp;area&nbsp;</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">PARAM&nbsp;NAME</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">centerimage</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;VALUE</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">APPLET</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;"><br />
<strong><span style="font-size: 12pt;">兼容性</span></strong><br />
现在可更容易维护向后兼容性。你可创建运行在更早Java插件版本上的程序，但仅需提供一个与jnlp_href参数一样的格式完整的&lt;applet&gt;标签就可使用这些新特性了。早期版本的JRE会忽略jnlp_href参数，转而使用&lt;applet&gt;标签。新的Java插件技术将忽略archive和code参数，而仅使用JNLP文件去启动Applet。<br />
<br />
<strong><span style="font-size: 12pt;">World Wind Applet示例</span></strong><br />
由World Wind Java开发组创建的<a href="http://download.java.net/javadesktop/plugin2/wwj/">NASA World Wind Java</a> Applet示例阐述了如果发布像NASA World Wind Java这样的领先类库。同样地，也用示例说明了如何使用JavaScript在Web页面中高效地整合HTML和Applet内容。<br />
<img alt="" src="http://java.sun.com/developer/technicalArticles/javase/newapplets/images/nasaapplet.jpg" width="450" height="283" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
</span><span style="font-size: 10pt;"><strong>Figure 2.</strong> </span><em><span style="font-size: 10pt;">NASA World Wind Applet</span></em><br />
<span style="font-size: 10pt;">该Web页面包含了关于喀斯喀特山脉的信息(要感谢维基百科)，并且将World Wind Java作为一个Applet嵌入其中，以图示该山脉中各山的位置。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">applet&nbsp;id</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">wwjApplet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;width</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">600</span><span style="color: rgb(0, 0, 0);">&nbsp;height</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">380</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;code</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">gov.nasa.worldwind.examples.applet.WWJApplet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;archive</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">BackwardCompatibility.jar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">param&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">jnlp_href</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;value</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">WWJApplet.jnlp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">applet</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">WWJApplet随标准的<a href="http://worldwind.arc.nasa.gov/java/">World Wind Java发行包</a>发布。如下所述，你可选择编写你自己的Applet类并将World Wind嵌入其中：<br />
下面是WWJApplet.jnlp文件中相关的部分：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">jnlp&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">WWJApplet.jnlp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">resources&nbsp;os</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Windows</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">property&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">sun.java2d.noddraw</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;value</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">/&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">resources</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">resources</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">j2se&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://java.sun.com/products/autodl/j2se</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;version</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">1.4+</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">/&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">jar&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">worldwind.jar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;main</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">/&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">extension&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">jogl</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">/&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">resources</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">applet</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">descname</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">WWJ&nbsp;Applet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;main</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">class</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">gov.nasa.worldwind.examples.applet.WWJApplet</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;!--</span><span style="color: rgb(0, 0, 0);">&nbsp;Overwritten&nbsp;by&nbsp;the&nbsp;surrounding&nbsp;web&nbsp;page&nbsp;</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;width</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;height</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">applet</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">desc</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">jnlp</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
<span style="font-size: 10pt;">注意几点：<br />
</span>
<ul>
    <li><span style="font-size: 10pt;">
    在本例中，worldwind.jar作为主类使用。理想地，从NASA的网站引用它，将其作为一个JNLP扩展，这就使得许多不同的都嵌入了World Wind的应用程序或Applet共享相同的jar文件。详情请见下面的内容。</span></li>
    <li><span style="font-size: 10pt;">
    为了它的硬件加速的3D图形，World Wind Java使用了针对OpenGL API的Java绑定，<a href="http://jogl.dev.java.net/">JOGL</a>。注意，JOGL JNLP扩展仅使用一行代码与应用程序进行结合。也要注意，在Windows平台上，由于OpenGL API与DirectDraw/Direct3D API(该API用于Windows平台默认的Java 2D实现)之间在驱动层面的冲突，需要指定系统参数-Dsun.java2d.noddraw=true。Windows平台上所有使用JOGL的应用程序与Applet程序都需要该系统参数。</span></li>
</ul>
<span style="font-size: 10pt;">
Web页面中的HTML链接调用JavaScript函数，该函数会与Applet进行交互并将其导向合适的山峰。下面是这些链接中的一个：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">a&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">javascript:gotoLocation(MOUNT_RAINIER);</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">Mount&nbsp;Rainier</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;(southeast&nbsp;of&nbsp;Tacoma,&nbsp;Washington)&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span></div>
<span style="font-size: 10pt;">当点击该链接后，将会调用JavaScript函数gotoLocation。该函数定义在同一个Web页面中：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;gotoLocation(locationString)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;params&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;locationString.split(';');<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(params.length&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">)&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Lat/lon</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;getWWJApplet().gotoLatLon(parseFloat(params[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">]),<br />
&nbsp;&nbsp;&nbsp;&nbsp;parseFloat(params[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">]));<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />
}</span></div>
<span style="font-size: 10pt;">Web页面HTML中的山峰位置将被解码为JavaScript字符串。将从这些字符串中解析出纬度，经度及其它视觉信息，并将它们传递给Applet。 gotoLatLon方法是在WWJApplet类中定义的；上面的方法调用将起动一个JavaScript-to-Java调用，把参数从JavaScript引擎传给Java。World Wind Applet接收该通知，并将视点以动画的方式切换到适当的地方。注意，gotoLatLon方法会迅速地返回，以便浏览器不必等待它的完成；该动画会在一个单独的Java线程中运行。<br />
<img alt="" src="http://java.sun.com/developer/technicalArticles/javase/newapplets/images/mtsthelens.jpg" /><br />
&nbsp;&nbsp;
</span><span style="font-size: 10pt;"><strong>Figure 3.</strong> <em>World Wind Applet with Mount St. Helen's Clicked</em><br />
</span>
<span style="font-size: 10pt;">如上所述，将World Wind Java集成到你的应用程序或Applet程序中的最好方法是将其作为一个JNLP扩展。这允许很多来自网络的集成了World Wind Java的应用程序或Applet程序能够共享World Wind代码资源。为了引用World Wind JNLP扩展，你需将下面的语句行加入到你的应用程序或Applet程序的JNLP文件中的&lt;resources&gt;部分：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">extension&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">worldwind</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://worldwind.arc.nasa.gov/java/0.4.1/webstart/worldwind.jnlp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">/&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">extension&nbsp;name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">jogl</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;href</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">/&gt;</span></div>
<span style="font-size: 10pt;">注意，World Wind扩展JNLP是区分版本的，所以你需参考World Wind文档或访问<a href="http://forum.worldwindcentral.com/forumdisplay.php?f=37">论坛</a>去找到你的JNLP会引用到的扩展的最新版本。<a href="http://worldwindcentral.com/">World Wind Central</a>是一个关于World Wind最新信息的有用资源。<br />
将World Wind作为一个扩展使用就意味着你不能将WWJApplet直接作为你的main-class使用。由于JNLP文件格式的语义，主jar (main="true")必须定义在主JNLP文件中。但很容易就能适应该限制，你可简单地创建你自己的WWJApplet子类(称之为MyWWJApplet)，而它并不做任何事情：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">class&nbsp;MyWWJApplet&nbsp;extends&nbsp;WWJApplet&nbsp;{}</span></div>
<span style="font-size: 10pt;">将worldwind.jar置于classpath中，并编译上述类，然后将该类放入它自己的jar文件中。引入这个jar作为你的主jar，MyWWJApplet就成为了你的main-class，然后将其作为JNLP扩展引入到World Wind中。<br />
<br />
<strong><span style="font-size: 12pt;">结论</span></strong><br />
介绍了Java插件对JNLP的支持，这为Applet的发布提供了很多新的可能，这对在浏览器内外发布Java内容的方法的统一又进了一大步。Applet自从它们起始已过了很长的时间，现在随着对JNLP的支持，它们会比以往更快，也更易于定制。<br />
<br />
</span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/214703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-07-14 19:56 <a href="http://www.blogjava.net/jiangshachina/archive/2008/07/14/214703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>何时编写单元测试？(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/06/09/206812.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Mon, 09 Jun 2008 12:55:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/06/09/206812.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/206812.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/06/09/206812.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/206812.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/206812.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 10pt;"><span style="font-size: 14pt;">何时编写单元测试？</span></span></strong><br />
</div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 是在编写一个方法之前就编写它的单元测试，还是在写完这个方法，甚至是整个类之后才编写单元测试呢？John Ferguson Smart<sup>[1]</sup>在他的<a href="http://weblogs.java.net/blog/johnsmart/archive/2008/06/tests_first_or.html">blog</a>中再次提出了这个问题，并根据自己的经验给出了一些建议。(2008.06.10最后更新)<br />
<br />
&nbsp;&nbsp;&nbsp; 都别书生气。在你编写一个方法之前或是之后编写单元测试--根据我的经验，只要你在编写代码的<em>几乎同时</em>就考虑并编写单元测试程序，那么这就无关紧要了。过后再返回去(或者根本就不回去)写测试程序将导致问题。就我个人而言，我喜欢在编写少量代码之前或紧接着的之后就编写单元测试--这不会打破工作流程，因为<em>它就是流程的一部分</em>。<br />
&nbsp;&nbsp;&nbsp; 这需要一点儿实践经验--缺乏经验的开发者经常为要写什么样的测试程序而烦恼。但这可能也反映出一个事实：他们同样也不知道要写什么样的代码。一些人评说TDD能够鼓励进行微设计--一种非常底层的设计，它不需要考虑较大的场景。这会发生在缺乏经验的开发者身上；如果你教条般地应用这种方法，同样也会遇上。像行为驱动开发这样的方法在此处就会很酷。当你在写getter方法之前，你会写一个针对这个getter方法的单元测试吗？如果是的话，那么你的单元测试专注的层次就较高了，也会更接近于用户(或系统)的需求。<br />
&nbsp;&nbsp;&nbsp; 回到问题的本质，为什么我喜欢把单元测试放在最开始的位置？很简单！我的实践经验告诉我，那样可以帮助提高代码的质量，并且节约调试时间。在开始时写十个小的单元测试所花的时间比在以后修复Bug所花的时间要少，如果代码经过了正确的单元测试，那就不会有Bug了。<br />
&nbsp;&nbsp;&nbsp; 事实上，我屡屡见到，如果某些代码经过了适当的单元测试，那么就不会有编码问题。最近就有一个例子：花了一个小时的时间去搜寻Web应用中的一个问题，该问题出现在一个编写正确的Spring-MVC程序中。结果是由于一个检验器类忽略了一个异常。很容易就发现了这个问题，实际上，在看了代码(代码检查(Code Review)也很有效)之后立刻就发现了。但关键是，我们花了一个小时甚至更多的时间去找这个需要进行检查的类。如果这些代码经过了适当的测试，那么就能很快地发现并解决这个问题。<br />
&nbsp;&nbsp;&nbsp; 根据我的经验，当人们在编写完程序之后才开始编写单元测试，就如同事后才有这样的想法，他们很难写出这些测试了 ("我已经完成了所有的代码，此时我还得去写单元测试")。或者根本就不去做。在这种情况下，代码是否完成了呢？如果代码运行地很好，那就算是完成了。这样的话，再写单元测试就大大地丧失了它的价值。还不仅如此，事后编写的单元测试将是肤浅的，不会对代码进行良好地测试。或者，开发者已经耗完了时间，他们根本就不想再为单元测试伤神了。<br />
&nbsp;&nbsp;&nbsp; TDD与任何其它的编码实践一样。当你正在学习某个新的技术时，你会倾向于对学习指导亦步亦趋。类似地，当你学习一项武术时，你也会试着一步步地模仿大师的动作，而不必去理解其中的逻辑。一旦你熟悉了某个技术，能够熟练地使用它，并对它有了更深入地理解，<em>然后</em>，你就能改进它，并与你之前掌握的其它技术进行溶合了。<br />
<br />
<strong><span style="font-size: 12pt;">
译注</span></strong><br />
[1]John是<a href="http://www.javapowertools.com/">Java Power Tools</a>一书的主作者，也是<a href="http://www.java.net/">java.net</a>中一位活跃的<a href="http://weblogs.java.net/blog/johnsmart/">Bloger</a>。<br />
<br />
<strong><span style="font-size: 12pt;">译后</span></strong><br />
&nbsp;&nbsp;&nbsp; 上周在java.net上看到这篇Blog，再联想到自己在平时工作中的单元测试实践，有些感触，故将其翻译了出来，与大家共享。<br />
&nbsp;&nbsp;&nbsp; 事先就编写单元测试，还是事后才编写单元测试？这是一个老问题。按照TDD的思想，自然是要先编写单元测试，然后再编写能够通过该单元测试的方法。<br />
&nbsp;&nbsp;&nbsp; 但，单元测试并不是TDD的专属领地，很多不实践TDD的项目也在应用着单元测试。<br />
&nbsp;&nbsp;&nbsp; 我认为，在不实践TDD的项目中(我自己所处的环境就是如此)，事后编写单元测试仍有着其合理性：<br />
&nbsp;&nbsp;&nbsp; 1. 以消极的态度来看，既然项目本身不严格要求事先编写单元测试，那么就可以在事后去做了。这至少比不去做要好，聊胜于无嘛。(嘿嘿，是够消极的，但也拿你没办法)<br />
&nbsp;&nbsp;&nbsp; 2. 事后编写单元测试至少也是一种检验手段，当然，肯定比不上事先编写的单元测试。因为，事后编写的单元测试很可能会"将就"已经写好的应用程序，正如John所说"事后编写的单元测试将是肤浅的，不会对代码进行良好地测试"。但...仍然是聊胜于无嘛 :-D (哈哈，有完没完了)<br />
&nbsp;&nbsp;&nbsp; 3. 可以把单元测试，其中就包含事后单元测试，作为"后来者"了解、学习应用程序的手段。因为单元测试程序就是应用程序的"客户"，所以无论它是事先写的，还是事后写的，都能够表现出应用程序的行为。<br />
&nbsp;&nbsp;&nbsp; 4. 事后单元测试，也可能转化为事先单元测试。在应用程序的整个生命周期中，维护阶段是最长的。在"漫长"的维护过程中，"之前"所写的"事后"单元测试将会成为"后来者"(包括原始作者本人)的"事先"单元测试。在改进程序的过程中，这些单元测试仍然能起到监督的作用。(orz，有点儿诡辩)<br />
&nbsp;&nbsp;&nbsp; 虽然，事后单元测试明显不如事先单元测试，但它的作用仍然不可低估。只要编写了优秀的单元测试程序，无论是在哪个阶段，它都会对改进应用程序有莫大的帮助。(这可不是"聊胜于无"能够表达的)<br />
<br />
</span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/206812.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-06-09 20:55 <a href="http://www.blogjava.net/jiangshachina/archive/2008/06/09/206812.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Rock Star 2008 -- Chet Haase(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/06/01/205180.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Sun, 01 Jun 2008 13:02:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/06/01/205180.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/205180.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/06/01/205180.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/205180.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/205180.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 10pt;"><span style="font-size: 14pt;">Rock Star 2008 -- Chet Haase</span></span></strong><br />
</div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 这是一篇在今年的JavaOne会议期间<a href="http://java.sun.com/javaone/sf/2008/articles/rockstar_chethaase.jsp">对Chet Haase的访谈</a>。关注Swing，Java 2D的朋友，对这位图形/UI开发方面的大牛肯定不会陌生。很高兴在不久前由他与Romain Guy合著的<a href="http://www.china-pub.com/39895">Filthy Rich Clients一书的中文版</a>已经出版了^_^ (2008.06.01最后更新)<br />
&nbsp;&nbsp;&nbsp; 祝大家六.一国际儿童节愉快！愿大家都能保持一颗年轻的心*_*<br />
&nbsp;&nbsp;&nbsp; <span style="color: rgb(255, 0, 0);">特别祝地震灾区的小朋友们节日快乐，愿他们在今后的岁月中能够幸福地成长:-)<br />
</span><br />
简历：<a href="http://graphics-geek.blogspot.com/">Chet Haase</a>是Adobe公司Flex SDK组的高级计算机科学家，他关注于图形问题及特性。早些时候，他工作于Sun Microsystems公司，是Desktop Java组的一名客户端软件架构师，涉及形如Java 2D，Swing，AWT和部署这样的客户端技术。他与Romain Guy一起是<em>Filthy Rich Clients: Developing Animated and Graphical Effects for Desktop Java Applications</em>一书的合著者。在2008 JavaOne大会中，他和Guy有一个关于Filthy Rich Client的议题。<br />
<br />
</span><span style="font-size: 10pt;">Q：若干月前，你出版了<a href="http://www.filthyrichclients.org/">Filthy Rich Clients</a>一书。关于它，开发者们应该知道些什么？<br />
A：有四点：第一，它涉及的特性丰富的功能，能帮助开发者创造更好的应用和更好的用户体验。第二，它有许多关于Swing和Java 2D的内幕，以便开发者不仅能理解我们写的功能，还能理解这些技术本身，他们就能使用这些技术去写出他们自己的功能了。第三，它是一本有趣的读物，至少我们努力去做到这一点。最后，在<a href="http://www.filthyrichclients.org/">本书的站点</a>上，可获取所有的示例和工具类库，包括源代码。<br />
<br />
Q：在Sun的Java Client组工作了8年之后，你在2008年的1月份离开了，并加入了Adobe。告诉我们你所从事的工作。<br />
A：我加入Flex组，从事与图形有关的工作--这没什么奇怪的。在目前为止，我主要专注于相关的平台：Flex，Flash，AIR，MXML，ActionScript3。对于某个在过去8年多的时间中一直从事于Java方面工作的人来说，有很多东西需要学习。同时，在全组为下一版的发布而对某些组件进行重新构架的工作中，我已在帮忙了。开始时，我关注动画方面。<br />
<br />
Q：周三下午5点，在Metreon，有一个Adobe的活动。到时你会与James Ward有一个简短的演讲。告诉我们关于它的一些情况。<br />
A：那会很有趣。James Ward将给出Flex平台的一个简介，包含如何编写与Java后台交互的Flex客户端程序。而我--也可能是我的合著者Romain Guy--将展示一些"Filthy Rich" Flex应用示例。这些示例关于如何使用Flex去实现我们在书中谈到的功能。使用Flex去实现的方法会不同，但你可以使用该平台去达到非常相似的功能。任何感兴趣的人都应去Adobe的展台，然后获取一份邀请。<br />
<br />
Q：是什么吸引你去开发图形软件？<br />
A：我喜欢从我的程序中得到可视化的反馈。当它正常工作时，你可以在屏幕中看到结果。当它坏掉了，你也能看到它在屏幕中不正常的样子。与调试某些隐蔽的数据库事务相比，这更能让我满足。还有，图形能够将我的数学背景结合到我的软件背景中。计算机图形学使用了从线性代数到三角函数到几何学再到微积分学的许多技术。使用数学在屏幕上显示美妙的图片，与我所处的数学领域能做的多数事情相比，这更加有趣。<br />
<br />
Q：对于那些想以做图形软件作为职业的人，你有什么建议？<br />
A：应用你所需要的数学课程。并不需要高级的知识，但以我已做过的很多软件来看，我着重学习了线性代数，及其一定的微积分学。<br />
<br />
Q：对于新接触Java程序设计语言的程序员，你会给出什么建议？<br />
A：不使用行号。不要把你的整个应用放在一个方法中。相信垃圾收集器能做好它的本职工作。<br />
<br />
Q：哪种产业已经准备开始大规模履行在Web服务方面的承诺？<br />
A：摔跤。当WWF(世界摔跤联合会)在万维网(World Wilde&nbsp;Web)上使用Web服务时，网络别名就将是wwwwwfws。<br />
<br />
Q：能描述一下你写代码的过程吗？<br />
A：我会试着在脑海中收集素材，可能会将一些不成熟的想法写在小纸片上，这样我之后就不用再去找了。这一机制中的某些观念将来会用得上。然后我开始写原型。<br />
我在一些书中看过一种理想化的方法，你将整个系统--API，或随便什么--以简短方法和注释的形式进行描述，然后你所要做的就是填充细节。也许真的有人用这种方法写代码，但我尚未遇到。<br />
很多软件是研究性项目，在那里并不清楚什么是可能的或需要做的细节是怎样的。所以当我快要知道我想达到的什么时，我会开始写一些代码以找出接下来要做的工作以及如何去做。<br />
<br />
Q：你创造的最让你感自豪的代码是什么？<br />
A：<a href="https://timingframework.dev.java.net/">Timing Framework</a>。这个类库增补了一项我在Java SE中见到的空白--Java SE缺乏有用的定时-动画特性。然后基于我们自己的或其他人给我们的需求，Timing Frame有机地发展起来。<br />
我也对Filthy Rich Clients中的所有代码感到十分自豪。这些代码示例意在向人们展示如何去完成一些特定的任务，但像简单执行的代码一样，作为教程而写成的这些代码也便于教学。<br />
<br />
Q：下一次大的技术革命是什么？<br />
A：香蕉电话。水果兼具通信元件与营养小吃的功能。<br />
<br />
Q：在此之前的五年内，你认为最重要的Java API是什么？<br />
A：没有什么比System.out.println更有用的了？<br />
<br />
Q：你能给我们一个优美代码的例子吗？<br />
A：这儿就有一个：<br />
&nbsp; 10 print "fart"<br />
&nbsp; 20 goto 10<br />
<br />
Q：如果你想向Santa Claus要一个<a href="http://www.netbeans.org/">NetBeans IDE</a>的新插件，那会是什么？<br />
A：<a href="http://www.adobe.com/devnet/actionscript/articles/actionscript3_overview.html">ActionScript3</a>的编辑器，如何？<br />
<br />
Q：当你感到困惑时，你会做些什么？<br />
A：拿一支笔和一张纸，然后思考着这个问题。也会散散步，或者与某个人一起讨论这个问题，或者换一杯咖啡--也许没什么帮助，但味道不错。<br />
<br />
Q：Java平台最近的什么变化使你的生活变得轻松些？<br />
A：我发现<a href="http://java.sun.com/javase/downloads/index_jdk5.jsp">J2SE 5.0</a>的一些语言变化，像新的for循环，很有用。<br />
我用过一些泛型以简化Timing Framwork API，虽然我知道泛型的真正好处是让用户泛型化API，而不是让开发者在他们自己的代码中使用泛型。<br />
<br />
Q：Swing开发者需要理解的最重要的东西是...？<br />
A：在沾手之前，先关掉食品加工器。<br />
<br />
Q：你认为Web 2.0的最大技术障碍是什么？<br />
A：有太多的框架用于"Web 2.0"应用。特别是在Ajax世界，很难知道从哪儿开始、继续或结束。从某种程度来看，一个开发者的脑海中只会中意最有可能流行的框架。可能更应该写作"Web Too"，即，"太多的选择"。<br />
<br />
Q：你是否是网络开发者社区的一位正式成员？<br />
A：我并不处在某个特定的社区内，但在我关注的开发领域内，我是一位经常写作的<a href="http://graphics-geek.blogspot.com/">博客</a>。我认为拥有伟大的类库是吸引开发者群的重要组成部分。<br />
但是向开发者们解释应该如何使用这些类库，以及使用特定的、合适的例子去展示这一点，则是另一个同等重要的部分。<br />
<br />
Q：图形软件应该如何溶入Web 2.0的画卷中？<br />
A：就我理解，Web 2.0是关于在浏览器中的更好、更动态的用户体验。不论你使用何种框架，这种体验都意味着丰富的图形与功能。甚至只是简单的如，动态地将购物商品拖入购物车，或使用有趣的图形技术在页面上使某个元素淡入淡出，这样的功能。<br />
<br />
Q：你如何看待开源软件？<br />
A：我认为开源软件很伟大，但并不是由于人们可能设想到的原因。当人们听到一个项目是开源的，他们可能猜测有一大批来自世界各个角落的人们在帮助这个项目，向其中塞入代码，并以这种松散的方式进行协作。<br />
我见过的大多数开源项目已较少关心人人贡献了，而更多的是关心源码库的透明性以及来自开发者的广泛反馈。多数的公司和人可能更关心的是，他们能够看到黑箱中的东西，然后会建议进行适当的改进，而不会是实际地去做这些改进，也不会使自己亲自加入到项目中。<br />
所以，就像我的Timing Framwork所获得的好处，并不是大家直接地向它提交代码，而是大家能够去看它是如何工作的，然后与我讨论怎样去改进它，以去适应他们的特定情形。<br />
Java和Flex SDK都是开源。不论选择加入的人的水平如何，我希望它们都能从社区的参与中获益。<br />
<br />
Q：大家知道你在博客中写有滑稽和诙谐的东西。你是否认为幽默与滑稽能保持你作为一个开发者的敏锐、自由与创意。<br />
A：是的，就是那样。这就是我那样做的原因。<br />
不，我这么做其实也没有什么理由。我只是喜欢博得一笑罢了。然而我也知道，如果人们都睡着了，你就不能教他们了。<br />
所以，使一次讲演具有趣味性，与使其信息丰富一样重要。我见过十分乏味但内容很好的讲演，但一般来说，对于越活跃的讲演，大家越能记住它，也越想再听一次。<br />
这同样适用于文章：为了使你的观点具有穿越性，如果你能使用一些有趣的比喻或词汇，就比只是在他们面前弄一些代码和方程式，更有机会使你的读者们继续看下去。<br />
<br />
Q：能与我们分享两个你最喜欢的奇客<sup>[1]</sup>笑话或故事吗？<br />
A：我不能保证他们是我最喜欢的或是最好笑的，但至少它们都很新--在本周才把它们帖到我的博客中--也很奇客：<br />
&nbsp;&nbsp;What do you call it when a chip manufacturer loses money?<br />
&nbsp;&nbsp;A cash miss.<br />
<br />
&nbsp; What do you call someone that has to use a dull web application?<br />
&nbsp;&nbsp;Bored to tiers.<sup>[2]</sup>
<br />
<strong style="font-size: 12pt;">译注</strong><br />
[1]奇客，Geek，指性格奔放甚至怪僻，擅长计算机的人。<br />
[2]由于对这两则笑话的"本质"尚未领悟，所以暂不翻译。<br />
<br />
<strong><span style="font-size: 12pt;">请关注上一篇译文：<a href="http://www.blogjava.net/jiangshachina/archive/2008/05/31/204939.html"><span style="font-size: 10pt;"><strong></strong></span><strong>Rock Star 2008 -- Joshua Bloch</strong></a></span></strong></span><strong></strong>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/205180.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-06-01 21:02 <a href="http://www.blogjava.net/jiangshachina/archive/2008/06/01/205180.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Rock Star 2008 -- Joshua Bloch(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204939.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Sat, 31 May 2008 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204939.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/204939.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204939.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/204939.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/204939.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 14pt;">Rock Star 2008 -- Joshua Bloch</span><br />
</strong></div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 这是一篇在今年的JavaOne会议期间对<a href="http://java.sun.com/javaone/sf/2008/articles/rockstar_joshuabloch.jsp">Joshua Block的访谈</a>。作为闻名的Java guru，大家已经从Joshua的<a href="http://java.sun.com/docs/books/effective/"><em>Effective Java</em></a>，<em>Java Collection Framework</em>，...中获益了。相信，Joshua Block在访谈中的一些真知灼见，仍然会使大家受益良多。(2008.06.02最后更新)<br />
<br />
<strong>简历</strong>：Joshua Block，Google公司的首席Java构架师，曾为Sun Microsystems公司的杰出工程师，由于<em>Effective Java Programming Language Guide</em>一书，他获得了<em>Software Development Magazine</em>极富盛名的Jolt大奖。在Sun公司时，他领导设计并实现了众多的Java平台特性，包括JDK 5.0的语言升级以及获奖的Java集合框架。他拥有卡纳基-梅隆大学计算机科学博士学位，目前还是<em>Effective Java, Second Edition</em>的作者。<br />
<br />
Q：你和Brian Goetz将会有一个名为"撰写下一本伟大的Java技术书籍"(BOF-6588)的议题。写一本伟大的Java书籍需要做些什么？<br />
A：这要看实际情况。你可以以书籍的形式介绍那些之前还没有被介绍过的重要知识，就如Brian Goetz和Tim Peierls 在<em>Java Concurrency in Practice</em>一书中所做的那样。或者，你也可以写一部对现有资料的原创讲解，使它能被所有未接触过Java的人所接受，就如Kathy Sierra和Bert Bates在<em>Head First Java</em>一书中所做的那样。你也可以先弄一大堆资料，然后提炼出其中的精华，就像Peter Sestoft在<em>Java Precisely</em>一书中做的那么出色。这还可以接着说下去。<br />
Q：对于你写的<em>Effective Java</em>，开发者经常告诉我，那是他们最喜欢的Java技术书籍。你将二次贡献名为"More 'Effective Java'"(TS-6623)的议题，在那儿，你将谈论Java平台新近的最佳实践。让我们先了解一点儿它的情况。<br />
A：我正在收集新出现在该书第二版中的素材。去年，我花了大量时间在谈论泛型，所以今年我仍将重点关注它，我确实有一个新的期望能够分享的泛型小窍门。<br />
我也将介绍一些关于enum类型的有趣素材，并有一个针对延迟初始化的最佳实践的简明指导。是的，我还计划展示我们州长年轻时的一张祼照<sup>[1]</sup>。<br />
<br />
<strong style="font-size: 12pt;">一天的生活<br />
</strong>Q：描述一下你在Google的一天中的生活。<br />
A：那是个工作的好地方。我与许多来自世界各地的聪明人一起工作，那儿不缺乏挑战性的工作去做。 Google理解开源以及回馈社区的重要性，所以他们一直支持我在Java平台方面的持续工作。额外的好处就是他们因此而获得的好名声。<br />
Q：你在Google吃的最好的一餐是什么？<br />
A：嗯...可能是两年前在Cafe 7吃的烤鹌鹑？或者可能是在Pinxto吃的Shiro Maguro Sashimi？有些饮品也是很棒的。<br />
Q：这些食物真的很好吃吗？<br />
A：是的。我不是说在那儿我就没吃过差的食物，但总的来看，确实很好。<br />
<br />
<strong style="font-size: 12pt;">将"Bloch"作为动词</strong><br />
Q：如果你能将"Bloch"变成动词，就如已对"Google"做的那样，那么动词"Bloch"会是什么意思？<br />
A：天啊，这是个很难的问题。可能是"写出好的API"？当然，这将不会发生，而我也乐于接受。在每一代中，只会有很少的人够得上用一个词去称呼，并且经常是一个形容词。如你所知的：牛顿的，笛卡尔的，莎士比亚的，就像这样的。<br />
由于某种原因，这使我想起多年前看到的一则头条。当Miles Davis<sup>[2]</sup>逝世时，纽约时报上他的讣告说："Miles Davis，小号手，去逝了；爵士天才，65岁，绝对的酷"。我也想到了自己，"是的，这就是一个总结。而且还没人能上这样的头条"。<br />
<br />
<span style="font-size: 12pt;"><strong>最美的代码</strong></span><br />
Q：你所喜爱的代码是怎样的？或者说，你所见过的最漂亮的代码是什么样的？如诗般的代码？<br />
A：我看过许多代码都能激起这种反响。就像真的诗歌一样，在某人看来很美的一段代码可能在其它人看来很丑陋。这儿有一段神秘的代码诗：<br />
&nbsp;&nbsp;&nbsp; static int inverse(int val) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t *= 2 - val * t;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t *= 2 - val * t;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t *= 2 - val * t;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t *= 2 - val * t;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return t;<br />
&nbsp;&nbsp;&nbsp; }<br />
正如它的名字所暗示的，该方法计算奇参数的乘法逆值，mod 2^32。换言之，对于所有的奇整数i，有i * inverse(i) == 1。它根据牛顿迭代原理。<br />
有严格的证据表明这四个迭代--方法中非回转的循环--对于任何输入值都足够了。那么这是我见过的最漂亮的代码吗？不，但它确实十分的聪明。<br />
如果你喜欢这样的东西，你应该去看看Henry S. Warren的书<em>Hacker's Delight</em>(Addison-Wesley，2003)。当你能看这本书时，要翻到"The Quest for an Accelerated Population Count"一章。在Osram和Wilson的<em>Beautiful Code</em>(O'Reilly，2007)一书中，当你手里也有这本书的话，也要读一下Jon Bentley 写的"The Most Beautiful Code I Never Wrote"一章。Jon写了许多诗歌般的代码。<br />
<br />
<strong style="font-size: 12pt;">最有趣的代码<br />
</strong>Q：你能想到的最有趣的代码是什么？<br />
A：<a href="http://thedailywtf.com/">The Daily WTF</a>中满是有趣的代码。Bill Pugh也经常发给我一些由<a href="http://findbugs.sourceforge.net/">FindBugs</a>发现的有趣代码。这儿有一个令人欣喜的例子--我发誓，它从未被透露过：<br />
&nbsp;&nbsp; public Object getObject(java.util.Map&lt;String,Class&lt;?&gt;&gt; map)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws SerialException<br />
&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map = new Hashtable(map);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!object.equals(null)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return map.get(object);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new SerialException("The object is not set");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
Q：代码是世界语吗？如果是，那为什么？<br />
A：我认为音乐才称得上，其次就是数学了。因为音乐将自然语言与数学符号联系了起来。代码很像数学：创建具有良好可读性程序的很大一部分工作就是选择好的标识符名称，而这就要基于自然语言。<br />
Q：哪位Java达人深深地影响了你？是在什么方面？<br />
A：应该是Doug Lea<sup>[3]</sup>。他知道很多事情中的很多东西，多年来，他激发了我数不清的想法。他总有让人感兴趣的事情可说。并且他有一种不可思异的能力，能发挥出VM的最佳性能。幸运的是，他已教给我一些他的窍门。例如，Branch Free代码会运行的很快，缓存的作用将会终结，内联探索法(I<font size="2">nlining Heuristics</font>)在性能方面有着巨大的效用。<br />
Q：能给我们一个你创造的最让你感到自豪的代码例子吗？并解释一下为什么？<br />
A：集合框架。虽远非完美，但多年来，已经证明了它的可维护性与优雅。而前面提到的Doug Lea构建的java.util.concurrent包中的许多部分就构建集合框架之上。并且在程序员的来信中，他们总是告诉我，集合框架是如何使他们的工作更加赏心悦目。它能使你写像下面这个程序那样的代码，这个程序通过标准输入流计算文件中所有的片语：<br />
public class Anagram {<br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int minGroupSize = Integer.parseInt(args[0]);<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read words from input and put into simulated multimap<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Map&lt;String, List&lt;String&gt;&gt; anagrams =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new HashMap&lt;String, List&lt;String&gt;&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Scanner s = new Scanner(System.in); s.hasNext(); ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String word = s.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String alphagram = alphagram(word);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;String&gt; group = anagrams.get(alphagram);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (group == null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anagrams.put(alphagram, group = new ArrayList&lt;String&gt;());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; group.add(word);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Print all permutation groups above size threshold<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (List&lt;String&gt; group : anagrams.values())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (group.size() &gt;= minGroupSize)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(group.size() + ": " + group);<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; private static String alphagram(String s) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] chars = s.toCharArray();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Arrays.sort(chars);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return String.valueOf(chars);<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
Q：当你感到困惑时，你会做些什么？<br />
A：我会喝一杯美味的热咖啡。Google有很好的咖啡机，这些机器来自于Barefoot Coffee Roasters。如果不管用，我就会去走一走。如果还不管用，我就会去叫Doug Lea。<br />
Q：你使用哪些网络资源，以紧跟Java技术。<br />
A：规范，还有Google。无论走到哪里，这都能帮上我。<br />
Q：是否有一种益智的训练或有趣的行为让你觉得能使你成为一名更好的开发者？<br />
A：我认为数学和写作能使你成为更好的开发者。数学与编程一样，要求严谨的思维。而写作会强迫你去组织你的想法。数学和写作都训练了相同的审美机能，而这对于写出好的程序也是必需的。<br />
Q：你希望在工科学校中你还应该学到哪些东西？<br />
A：我希望我能更好地学会弹吉他，现在我弹的可不好。我希望能学一门外语，还有艺术史。当然，还想学一些商业和金融方面的知识。这样说起来，哥伦比亚大学会对我有更好的帮助。我会鼓励本科生们，当他们还有时间时，就要创造机会去获取更宽泛的知识。以后，他们会有足够的时间深入到其中。<br />
<br />
<strong style="font-size: 12pt;">译注</strong><br />
[1]这张"祼照"就是加利福尼亚州现任州长</span><span style="font-size: 10pt;">阿诺.施瓦辛格的健美祼肤照。</span><br />
<span style="font-size: 10pt;">[2]Miles Davis，爵士乐大师。点击<a href="http://www.nytimes.com/learning/general/onthisday/bday/0525.html">此处</a>可以看到纽约时报上关于他的讣告全文。<br />
[3]<a href="http://g.oswego.edu/">Doug Lea</a>，java.util.concurrent的创始人，目前也是<a href="http://openjdk.java.net/">OpenJDK</a>临时管理委员会的成员。<br />
<br />
<strong style="font-size: 12pt;">请关注下一篇译文：<a href="http://www.blogjava.net/jiangshachina/archive/2008/06/01/205180.html">Rock Start 2008 -- Chet Haase</a></strong></span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/204939.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-05-31 23:39 <a href="http://www.blogjava.net/jiangshachina/archive/2008/05/31/204939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Callable返回结果(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Sat, 31 May 2008 14:24:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/204007.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/204007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/204007.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 10pt;"><span style="font-size: 14pt;">使用Callable返回结果</span></span></strong><br />
</div>
<span style="font-size: 10pt;">
&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">本文是Sun官方以Blog形式发布的Java核心技术窍门(<a href="http://blogs.sun.com/CoreJavaTechTips/">JavaCoreTechTip</a>)中的一个。本文主要介绍了Callable及其相关接口和类的使用，篇幅不长且易于理解，故翻译在了此处，相信对于准备或刚接触java.util.concurrent的朋友会有所帮助。(2008.05.31最后更新)<br />
<br />
</span><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 自从Java平台的最开始，Runnable接口就已存在了。它允许你定义一个可由线程完成的任务。如大多数人所已知的那样，它只提供了一个run方法，该方法既不接受任何参数，也不返回任何值。如果你需要从一个未完成的任务中返回一个值，你就必须在该接口之外使用一个方法去等待该任务完成时通报的某种消息。例如，下面的示例就是你在这种情景下可能做的事情：<br />
&nbsp;&nbsp;&nbsp; Runnable runnable = ...;<br />
&nbsp;&nbsp;&nbsp; Thread t = new Thread(runnable);<br />
&nbsp;&nbsp;&nbsp; t.start();<br />
&nbsp;&nbsp;&nbsp; t.join();<br />
&nbsp;&nbsp;&nbsp; String value = someMethodtoGetSavedValue()<br />
严格来说，上述代码并无错误，但现在可用不同的方法去做，这要感谢J2SE 5.0引入的Callable接口。不同于Runnable接口拥有run方法，Callable接口提供的是call方法，该方法可以返回一个Object对象，或可返回任何一个在泛型化格式中定义了的特定类型的对象。<br />
&nbsp;&nbsp;&nbsp; public interface Callable&lt;V&gt; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; V call() throws Exception;<br />
&nbsp;&nbsp;&nbsp; }<br />
因为你不可能把Callable对象传到Thread对象去执行，你可换用ExecutorService对象去执行Callable对象。该服务接受Callable对象，并经由submit方法去执行它。<br />
&nbsp;&nbsp;&nbsp; &lt;T&gt; Future&lt;T&gt; submit(Callable&lt;T&gt; task)<br />
如该方法的定义所示，提交一个Callable对象给ExecutorService会返回一个Future对象。然后，Future的get方法将会阻塞，直到任务完成。<br />
&nbsp;&nbsp;&nbsp; 为了证明这一点，下面的例子为命令行中的每个词都创建一个单独的Callable实例，然后把这些词的长度加起来。各个Callable对象将只是计算它自己的词的长度之和。Futures对象的Set集合将被保存以便从中获得计算用的值。如果需要保持返回值的顺序，则可换用一个List对象。<br />
import java.util.*;<br />
import java.util.concurrent.*;<br />
<br />
public class CallableExample {<br />
<br />
&nbsp;&nbsp;&nbsp; public static class WordLengthCallable<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; implements Callable {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String word;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public WordLengthCallable(String word) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.word = word;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Integer call() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Integer.valueOf(word.length());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static void main(String args[]) throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExecutorService pool = Executors.newFixedThreadPool(3);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set&lt;Future&lt;Integer&gt;&gt; set = new HashSet&lt;Future&amp;lg;Integer&gt;&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (String word: args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Callable&lt;Integer&gt; callable = new WordLengthCallable(word);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Future&lt;Integer&gt; future = pool.submit(callable);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set.add(future);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sum = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Future&lt;Integer&gt; future : set) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum += future.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.printf("The sum of lengths is %s%n", sum);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(sum);<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
WordLengthCallable保存了每个词并使用该词的长度作为call方法的返回值。这个值可能会花点儿时间去生成，不过在这个例子中，可以立即知道它。 call方法的唯一要求是这个值要在call方法的结尾处返回。当Future的get方法稍后被调用时，如果任务运行得很快的话，Future将会自动得到这个值(如同本例的情况)，否则将一直等到该值生成完毕为止。多次调用get方法不会导致任务从该线程返回。因为该程序的目的是计划所有字的长度之和，它不会强令Callable任务结束。如果最后一个任务在前三个任务之前完成，也是没错的。对Future的get方法的第一次调用将只会等待Set中第一个任务结束，而不会阻塞其它的任务分别执行完毕。它只会等待当次线程或任务结束。这个特定的例子使用固定数线程池来产生ExecutorService对象，但其它有效的方法也是可行的。<br />
&nbsp;&nbsp;&nbsp; 关于执行器和线程池用法的更多信息，请见Java Tutorial中<a href="http://java.sun.com/tutorial/essential/concurrency/executors.html">Executors</a>一节。SwingWorker类是另一个使用Future的Runnable对象的例子，尽管有些微不同之处。更多信息请见Java Tutorial中<a href="http://java.sun.com/docs/books/tutorial/uiswing/concurrency/worker.html">Worker Threads and SwingWorker</a>一节。<br />
<br />
</span>
<img src ="http://www.blogjava.net/jiangshachina/aggbug/204007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jiangshachina/" target="_blank">Sha Jiang</a> 2008-05-31 22:24 <a href="http://www.blogjava.net/jiangshachina/archive/2008/05/31/204007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串排序(译)</title><link>http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html</link><dc:creator>Sha Jiang</dc:creator><author>Sha Jiang</author><pubDate>Mon, 07 Apr 2008 01:10:00 GMT</pubDate><guid>http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html</guid><wfw:comment>http://www.blogjava.net/jiangshachina/comments/190912.html</wfw:comment><comments>http://www.blogjava.net/jiangshachina/archive/2008/04/07/190912.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jiangshachina/comments/commentRss/190912.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jiangshachina/services/trackbacks/190912.html</trackback:ping><description><![CDATA[<div align="center"><strong><span style="font-size: 14pt;">字符串排序</span></strong><br />
</div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 本文是Sun官方以Blog形式发布的Java核心技术窍门(<a href="http://blogs.sun.com/CoreJavaTechTips/">JavaCoreTechTip</a>)中的一个。我之前尚未关注过java.text.Collator类，看过<a href="http://blogs.sun.com/CoreJavaTechTips/entry/sorting_strings"><span style="font-size: 10pt;">Sorting Strings</span></a></span><span style="font-size: 10pt;">这个tip之后觉得有些意义，故翻译在了此处，也希望对其它朋友有所助益。(2008.04.07最后更新)</span><br />
<br />
&nbsp;&nbsp;&nbsp; <span style="font-size: 10pt;">使用Java平台进行字符串排序被认为是一件简单的工作，但为国际市场开发程序时，则需要有更多的考虑。如果你陷入只关注英语的心态中，并认为你的程序会工作的很好，因为它所显示的字符串从今往后都是一样的，你可能认为一切都很正常。但一旦你有一位西班牙用户，他希望能够正常地对ma&#241;ana进行排序，但如果你都是使用String类中缺省的compare方法去做排序，字符&#241;将会跟在字符z之后，而在正常的西班牙语排序中，&#241;应该在字符n和o之间。这就是java.text包的类Collator发挥作用的地方了。
<br />
想像这样的一组词
<ul>
    <li> first
    </li>
    <li> ma&#241;ana
    </li>
    <li> man
    </li>
    <li> many
    </li>
    <li> maxi
    </li>
    <li> next
    </li>
</ul>
使用String类的默认排序机制，即它的compare()方法，排序的结果将会是：
<ul>
    <li> first
    </li>
    <li> man
    </li>
    <li> many
    </li>
    <li> maxi
    </li>
    <li> ma&#241;ana
    </li>
    <li> next
    </li>
</ul>
&nbsp;&nbsp;&nbsp; 此处，ma&#241;ana出现在maxi与next之间。而在西班牙语世界中，ma&#241;ana应该出现在many和maxi之间，
因为在字母表中，字符&#241;(读作e&#241;e)跟在n之后。当来了一个德语用户，想用他们自己的变音符时，你就可以写一个自己的定制排序规则来处理&#241;，
否则一组使用fa&#231;ade的设计模式将会怎样呢？你是否想让fa&#231;ade出现在factory之前或之后呢？(关键是如同对c或其它字符那样去处理&#231;的小写变音符。)
<br />
&nbsp;&nbsp;&nbsp; 这就是类Collator能派上用场的地方了。类Collator用于对语言敏感的排序问题，并不会只基于它们的ASCII/Unicode字符去尝试排序。
使用Collator要求你在完全应用它的特性之前要理解一个额外的属性，即称之为强度(Strength)的属性。Collator的强度设置决定了在排序时如何使用强(或弱)匹配。
该属性有4个可能的值：PRIMARY，SECONDARY，TERTIARY和IDENTICAL。具体是哪个强度在产生作用取决于语言环境。
典型地，会有如下的情况。按从后往前的顺序，IDENTICAL强度表示能够被进行相同的处理的字符必须是一致的。TERTIARY通常用于忽略大小写差异。SECONDARY用于忽略变音符，如n和&#241;。
PRIMARY与IDENTICAL相似也是基于字母之间差异，但是当处理控制字符和发音时还是有所不同。查看<code>Collator</code>的javadoc，
以获取更多关于这些强度之间的差异及分解(Decomposition)模式规则的信息。
<br />
&nbsp;&nbsp;&nbsp; 为了使用Collator，你需要先得到它的一个实例。你既可以调用getInstance方法以得到一个针对默认语言环境的Collator对象，
也可以传递一个指定的Locale对象给getInstance方法以得到一个针对特定语言环境的Collator对象。例如，为了获得针对一个西班牙语的
Collator对象，你应使用new Locale("es")去创建一个西班牙语的Locale对象，然后将它传入getInstance方法中：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">Collator&nbsp;esCollator&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;Collator.getInstance(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Locale(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">es</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));</span></div>
<span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp; 假设针对该语言环境的默认Collator强度，针对西班牙语的默认强度是SECONDARY已经足够了。然后你将这个Collator对象如任一Comparator对象
那样传入Collections类的sort方法的比较规则参数中，以得到排序后的List对象。<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">Collections.sort(list,&nbsp;esCollator);</span></div>
<span style="font-size: 10pt;">操作之前的单词列表，你现在就会得到一个基于西班牙语字母表的恰当排序结果：
<ul>
    <li> first
    </li>
    <li> man
    </li>
    <li> many
    </li>
    <li> ma&#241;ana
    </li>
    <li> maxi
    </li>
    <li> next
    </li>
</ul>
如果你在上述Collator中换用US的Locale对象，由于&#241;并不是US中本有的字母，所以ma&#241;ana将会出现在man和many之间。
<br />
这儿有一个简洁的例子以显示这些差异。
import java.awt.*;<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.text.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.List;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Explicit&nbsp;import&nbsp;required</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;javax.swing.</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;S