﻿<?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-Pudgy's World-随笔分类-Java Newbie</title><link>http://www.blogjava.net/Pudgy/category/2754.html</link><description>&lt;SCRIPT&gt;
var dict_width   = 'auto'
var dict_height  = '72px'
var dict_background = 'transparent'
var dict_border  = '0px dotted #000000'
var dict_textColor = '#6FBC4C'
var dict_fontSize = '100%'
var dict_encoding = 'Utf-8'
&lt;/SCRIPT&gt;
&lt;SCRIPT src="http://livid.cn/services/fortune"&gt;&lt;/SCRIPT&gt;
&lt;script src="http://www.google-analytics.com/urchin.js" type="text/javascript"&gt;
&lt;/script&gt;</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 06:32:08 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 06:32:08 GMT</pubDate><ttl>60</ttl><item><title>时标和历法</title><link>http://www.blogjava.net/Pudgy/archive/2005/08/29/11420.html</link><dc:creator>Pudgy's World</dc:creator><author>Pudgy's World</author><pubDate>Mon, 29 Aug 2005 03:42:00 GMT</pubDate><guid>http://www.blogjava.net/Pudgy/archive/2005/08/29/11420.html</guid><wfw:comment>http://www.blogjava.net/Pudgy/comments/11420.html</wfw:comment><comments>http://www.blogjava.net/Pudgy/archive/2005/08/29/11420.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Pudgy/comments/commentRss/11420.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Pudgy/services/trackbacks/11420.html</trackback:ping><description><![CDATA[<!--StartFragment -->&nbsp;转自<A href="http://fmddlmyy.home4u.china.com/text8.html">http://fmddlmyy.home4u.china.com/text8.html</A>
<H2>时标和历法</H2>
<H3>1、时标</H3>时标（Time Scale）就是标度时间的方法。在时间的标度上，存在着两个相互独立的需求：一方面，我们希望时间标度能与地球的自转相吻合，可以称作天文学需求；另一方面，我们要求时间标度的单位是精确的，便于大家获得准确的时间。由于地球自转的不均匀性，从这两个需求出发制定的时标会有细微的差异。<BR>世界时（UT1）是基于地球自转的时标，下文会详细介绍。国际原子时（TAI）是基于单位时间的时标，它以“铯-133原子基态两个超精细能级间跃迁辐射 9,192,631,770周所持续的时间”为一秒，可以称作原子时标。原子时标的准确度为每日数纳秒，而世界时的准确度只有数毫秒。
<P></P>
<H4>1.1 本初子午线</H4>对于基于天文观测的时标，地球上位于不同经度的观测者，在同一瞬间测得的结果是不同的。因此需要统一的地理经度基准。<BR>1884年在华盛顿举行的国际子午线会议决定，采用英国伦敦格林威治（Greenwich）天文台埃里中星仪所在的子午线作为时间和经度计量的标准参考子午线，称为本初子午线，又称格林威治子午线。格林威治天文台于1948年迁到苏塞克斯郡（Sussex）的Herstmonceux Castle，但旧址继续被用作0度经线的位置。<BR>1957年国际上以若干天文测时结果长期稳定性较好的天文台数据为参考，求得平均天文台经度原点。1968年国际上把通过地极原点和平均天文台经度原点的子午线称为本初子午线。可见，本初子午线的定义已经不依赖于格林威治天文台旧址。
<P></P>
<H4>1.2 世界时</H4>世界时的制定基准是太阳的周日视运动。视运动就是我们看到的运动。本来是地球绕着地轴由西向东转动。但如果观测者以为自己不动，就可以认为太阳在由东向西转动，这就是太阳的周日视运动。<BR>地球在自转的同时还围绕太阳公转，因为地球公转轨道是椭圆的，所以太阳的周日视运动是不均匀的。天文学家制定了以太阳周日视运动的平均速度为基础的平太阳时，平太阳时的基本单位是平太阳日。国际天文学联合会于1928年决定，将由格林威治平子夜起算的平太阳时称为世界时，简称UT。<BR>UT0是天文台观测到的原始数据。UT1在UT0的基础上，消除了地轴摆动的影响。还有一个修正了地球自转速度季节性变动的UT2，现在已经不用了。其实UT0、UT1、UT2的差异很小，不超过0.03秒。现在提到的世界时一般指UT1。
<P></P>
<H4>1.3 时区</H4>世界时区的划分,是以本初子午线为标准，从西经7度5分到东经7度5分为零时区；从零时区的边界分别向东和向西，每隔经度15度划一个时区。东、西各划出 12个时区，东十二时区与西十二时区相重合。全球共划分成24个时区。各时区都以中央经线的地方时为本区的区时，相邻两时区的区时相差一小时。<BR>在太平洋中靠近180°经线附近有一条国际规定的国际日期变更线(简称日界线)。此线两侧的日期不同。由东向西过日界线，日期要增加一天（即略去一天不算）；由西向东过日界线，日期要减少一天(即日期重复一次)。
<P></P>
<H4>1.4 协调世界时（UTC）和闰秒</H4>为了调和天文学需求和单位时间需求的差异，一种称为协调世界时（UTC）的折衷时标于1972年面世。UTC的秒长与国际原子时（TAI）相同。但在必要时，UTC会增加1秒或去掉1秒，使UTC和世界时(UT1)的时刻之差保持在±0.9秒以内。这一技术措施被称为闰秒（Leap Second）。<BR>因此，UTC与TAI之间会出现若干整数秒的差别。位于巴黎的国际地球自转事务中央局(IERS)负责决定何时加入闰秒。TAI是从1958年1月1日0 时0分0秒开始计时的。在本文写作时（2005年7月），UTC时间比TAI时间小32秒。最近一次闰秒调整是1999年1月1日。下次闰秒调整是 2006年1月1日。<BR>我们提到的地区标准时就是在UTC上加上时差得到的本地时间。
<P></P>
<H4>1.5 格林威治时间（GMT）</H4>格林威治时间（GMT）是一个比较模糊的概念。在1928年，GMT就是世界时。在UTC被广泛采用后，我们提到的GMT实际上是UTC时间，或者说零时区的标准时。
<P></P>
<H4>1.6 GPS时间</H4>GPS时间可以看作没有闰秒调整的UTC时间，并以1980年1月6日0时0分0秒为起点。目前GPS时间比UTC时间大13秒。<BR>协调世界时（UTC）将在2005年底实施一个正闰秒。届时，所有的时钟将拨慢1秒。GPS时间不做闰秒调整，所以将比UTC时间大14秒。从GPS时间计算本地时间，需要减去目前累计的闰秒，再加上本地的时差。
<P></P>
<H4>1.7 小结</H4>在所有时标中，日和秒的关系都是固定的，每日86400秒。确定了秒的长度，就确定了日的长度，反之亦然。原子时标以秒为基准，秒和日的长度都是固定的。世界时以日为基本单位，每日的长度会有毫秒级的差异。UTC既保证了单位时间的精确，又通过闰秒调整与天文观测的时间保持不大于±0.9秒的误差。我们日常生活中使用的时间都以UTC时间为标准。<BR>时标作为时间的刻度，为时间长河建立了一根以秒或日为单位的坐标轴。虽然，“GPS时间280948秒”可以标志一个唯一的时刻，但用于日常生活未免不太方便。在日常生活中，我们需要更方便的标记时间的方法，这就是下面要谈到的历法。
<P></P>
<H3>2、历法</H3>所谓历法，就是通过合理地安排年、月、日这三个基本量的关系，为时间建立标记的方法。
<P></P>
<H4>2.1 回归年和朔望月</H4>前面说过：地球自转可以看作太阳的周日视运动。同理，地球绕太阳的公转，可以被看作太阳的周年视运动。周年视运动的轨道被称作黄道，黄道面和赤道面的夹角是23°27′。随着太阳在黄道上的位置不同，地球上的季节也由春到夏，以至秋冬。<BR>黄道和赤道的两个交点分别被称作春分点和秋分点，这两点在黄道上的两个中点分别被称作夏至点和冬至点。太阳从春分点出发，绕黄道一周，又回到春分点所花的时间被称为回归年。目前测量的回归年长度是365.242189日。<BR>月亮的盈亏变化，产生了月。月亮绕地球旋转，当转到正对着太阳的位置，我们就会观测到满月，这就是望；当转到背对太阳的位置，我们会完全看不到，这就是朔。月亮从朔到朔，或从望到望所花的时间被称作朔望月。目前测量的朔望月长度是29.530588853000001日。
<P></P>
<H4>2.2 历法的分类</H4>仅以太阳运动为依据的历法被称作阳历或太阳历。例如我们现在使用的公历。阳历以回归年为基本周期，与月亮运动没有任何关系。<BR>仅以月亮运动为依据的历法被称作阴历或太阴历。例如伊斯兰教国家和地区使用的回历。阴历以朔望月为基本周期，与太阳运动没有任何关系。<BR>同时考虑太阳和月亮运动的历法被称作阴阳历，例如我国的农历。在我国，农历习惯上也被称作阴历。阴阳历把回归年和朔望月并列为制历的基本周期。<BR>由于回归年、朔望月的长度都不是日的整数倍，所以各种历法都要通过增加闰日或闰月，来调整自己与基本周期的差异。下面介绍几种常用的历法。
<P></P>
<H4>2.3 儒略历</H4>公元前46年，罗马执政官儒略·凯撒颁布了儒略历。儒略历每年12个月，平年365天，闰年366天。除2月外，单数月份31天，偶数月份30天。2月份平年29天，闰年30天。每隔3年置一闰年。<BR>儒略历是纯太阳历，每年的平均长度是365.25天。每400年，儒略历与回归年大约相差3天，即：<BR>(365.25-365.242189)*400 = 3.1244<BR>凯撒为了纪念改历成功，将他出生的7月从Quintilis改成自己的名字Julius。
<P></P>
<H4>2.4 奥古斯都历</H4>奥古斯都是“神圣”的意思，这是当时人们对罗马统治者屋大维的尊称。<BR>从公元前42年到公元前9年，儒略历被错误地执行为“每3年置一闰年”。儒略·凯撒的侄子屋大维纠正了这个错误，同时将自己出生的8月从Sextilis 改成自己的称号Augustus，将8月改成31天，将9、10、11、12月的大小月对换，并从2月份扣去一天，成为平年28天，闰年29天。<BR>奥古斯都历的月份设置和现在的公历已经完全相同了。
<P></P>
<H4>2.5 格里高利历——公历</H4>公元1582年3月1日，罗马教皇格里高利十三世颁布了格里高利历，将不能被4整除的世纪年算作平年，这就是我们现在使用的公历。<BR>在公历中，每400年有97个闰年，平均每年的长度是：<BR>(365*400+97)/400 = 365.2425 天<BR>每400年，公历与回归年大约相差0.1244天，即：<BR>(365.2425-365.242189)*400 = 0.1244
<P></P>
<H4>2.6 儒略日和简化儒略日</H4>在天文学有一种连续纪日的儒略日（JD），它以儒略历公元前4713年1月1日的GMT正午为第0日的开始。还有一种简化儒略日（MJD）：<BR>MJD=JD-2400000.5<BR>MJD的第0日是从公历1858年11月17日的GMT零时开始的。我写完前一个句号时的MJD是53583.22260。小数部分是以UTC时间在当天逝去的秒数除以86400得到的。0.22260约为UTC时间的5:20，加上中国的时区就是13:20。<BR>需要注意：儒略历公元前4713年1月1日相当于公历公元前4713年11月24日。在香港天文台的网页上，将儒略历说成以“公元前4713年1月1日格林尼治平时正午”起算，是错误的。
<P></P>
<H4>2.7 农历</H4>
<H5>2.7.1 月的划分</H5>农历的月是严格按照朔的时刻确定的，朔所在日是初一。由于朔望月的长度约为29.A日（将小数部分记作A），假设朔发生在(30-29.A)日以内的时刻，两个朔之间就只有29天，该月就是小月；否则两个朔之间有30天，该月就是大月。
<P></P>
<H5>2.7.2 设计</H5>我们已经根据月亮的运动规律将时间长轴划分为一个个月，下面要做的就是确定将哪些月组合成年。设计要求是：该设计应使四季在每年的位置相对稳定。<BR>设计思路是这样的：四季变化以回归年为周期，回归年的长度约为365.242189日。12个朔望月的长度约为354.367066236日，13个朔望月的长度约为383.897655089。如果我们让有的年份有12个朔望月，有的年份有13个朔望月，并按照一定周期循环；在一个周期内，年的平均长度接近回归年的长度，就能实现我们的设计目标。例如：我们在19年中，让7年有13个月，其它年为12个月，则在19年的周期里，每年的平均长度是：<BR>(29.530588853000001*(12*19+7))/19 ≈ 365.246756866 天<BR>这个结果与回归年的长度已经比较接近。包含12个朔望月的年份被称作平年，包含13个朔望月的年份被称作闰年，闰年多加的一个月被称作闰月，这就是《尚书·尧典》中所说的“以闰月定四时成岁”。<BR>那么，闰月加在哪里呢？在介绍置闰的规则前，必须先介绍一下节气。
<P></P>
<H5>2.7.3 二十四节气</H5>以春分点为黄经0度，将黄道分成二十四等分，每等分占黄经15度，太阳通过等分点的时刻就是对应节气的时刻。二十四节气只与太阳的运动有关，所以它们在公历中的日期变化不大。<BR>二十四节气从立春（黄经30度）开始，依次为立春、雨水、惊蛰、春分、清明、谷雨、立夏、小满、芒种、夏至、小暑、大暑、立秋、处暑、白露、秋分、寒露、霜降、立冬、小雪、大雪、冬至、小寒、大寒。<BR>将立春作为第1个节气，依次编号。偶数编号的节气被称为“中气”（major solar terms），奇数编号的节气仍称作“节气”（minor solar terms）。我们在日常生活中将节气和中气统称为节气（solar terms）。中气是置闰的重要依据。
<P></P>
<H5>2.7.4 置闰</H5>在农历中，从前一年正月初一到下一年正月初一被称作年。显然，必须先确定了闰月，才能确定年的范围，我们不可能在置闰规则中用到“年”。实际上，我们用到了另一个概念：岁。从前一个冬至到下一个冬至被称作岁。“岁”的长度就是回归年的长度。<BR>冬至所在的月被定义为11月。如果在两个11月间有12个完整的月，那么这两个11月间的岁就被称作闰岁。因为这两个11月间只有11个中气，所以闰岁的12个月中至少有一个月没有中气。<BR>闰岁的第一个不含中气的月，就是闰月。至此，我们已经描述了编制农历的完整规则。
<P></P>
<H5>2.7.5 闰年和Y2033问题</H5>包含闰月的年被称作闰年。如果闰月出现在11月，就可能出现前一年是闰年，但不是闰岁；后一年是闰岁，但不是闰年。一个典型的例子就是Y2033问题。<BR>从2033年的第1个月算起，第8个月没有中气，第11个月有两个中气，第12个月没有中气，第13个月有两个中气，第14个月没有中气。在2032年的 11月和2033年11月间只有11个完整的月，不是闰岁。在2033年的11月和2034年11月间有12个完整的月，是闰岁。<BR>按照置闰规则，第12个月被作为闰月，即闰11月。8月没有中气，又不是闰月，被称作伪闰月（Fake leap month）。2034年是闰岁，但不是闰年。2034岁的闰月已经在2033年加过了。<BR>国内1990年以前的万年历都将2033年设为闰7月，这个错误被称作Y2033问题。以后出版的万年历都改成了闰11月。但网上的一些万年历程序现在还在使用错误的农历数据。
<P></P>
<H4>2.7 回历</H4>作为太阴历的例子，简单介绍一下回历。回历是伊斯兰教国家和地区采用的历法。它以朔望月为基本周期，每年12个月。平年奇数月30天，偶数月29天，共354天。<BR>每30年为一周，加11个闰日。在30年循环周期中，第2、5、7、10、13、16、18、21、24、26、29年为闰年。闰年在12月底增加一天,共355天。<BR>在回历中，月的平均长度是：<BR>(354*30+11)/30/12 ≈ 29.53 天<BR>这和朔望月长度非常接近，很好地符合了月亮的运动规律。年的平均长度是：<BR>(354*30+11)/30 ≈ 354.366667 天<BR>这和回归年约差11天。因此回历的新年在公历中会逐年提早，循环周期为<BR>365.242189/(365.242189-354.366667) ≈ 33.5838766176 年<BR>回历的起始历元被称作伊斯兰教纪元，定在穆罕默德从麦加迁到麦地那的一天，即儒略历公元622年7月16日，在公历中是公元622年7月19日。例如：伊斯兰教纪元1426年1月1日是公元2005年2月10日。伊斯兰教纪元1427年1月1日是公元2006年1月31日。
<P></P>
<H4>2.8 小结</H4>公历和回历的计算都很简单。但公历的月不能符合月亮的运动规律。回历的年不能符合太阳的运动规律。农历较好地符合了太阳和月亮的运动规律，但计算比较复杂。<BR>在网上可以找到计算各国历法的程序。我曾经将其中一个Java程序库的农历部分改写成C/C++程序，以提高运算速度。在我的个人主页上有关于农历计算程序的进一步讨论(<A href="http://fmddlmyy.home4u.china.com/cal.html">http://fmddlmyy.home4u.china.com/cal.html</A>)。不过这些内容已经超出了本文的范围。<BR>在写这篇文章前，我不知道“时标”，对历法的概念也很模糊。通过查资料、写作，我对相关概念的了解越来越清晰。这篇文章的写作目的是将时标、历法的一些基本概念简单、清晰地描述出来，希望有更多的读者像我一样从中受益。 
<P></P><img src ="http://www.blogjava.net/Pudgy/aggbug/11420.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Pudgy/" target="_blank">Pudgy's World</a> 2005-08-29 11:42 <a href="http://www.blogjava.net/Pudgy/archive/2005/08/29/11420.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>谈谈Unicode编码，简要解释UCS、UTF、BMP、BOM等名词</title><link>http://www.blogjava.net/Pudgy/archive/2005/08/29/11419.html</link><dc:creator>Pudgy's World</dc:creator><author>Pudgy's World</author><pubDate>Mon, 29 Aug 2005 03:39:00 GMT</pubDate><guid>http://www.blogjava.net/Pudgy/archive/2005/08/29/11419.html</guid><wfw:comment>http://www.blogjava.net/Pudgy/comments/11419.html</wfw:comment><comments>http://www.blogjava.net/Pudgy/archive/2005/08/29/11419.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/Pudgy/comments/commentRss/11419.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Pudgy/services/trackbacks/11419.html</trackback:ping><description><![CDATA[<!--StartFragment -->&nbsp;转自<A href="http://fmddlmyy.home4u.china.com/text6.html">http://fmddlmyy.home4u.china.com/text6.html</A>
<H2>谈谈Unicode编码，简要解释UCS、UTF、BMP、BOM等名词</H2>
<P>这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念，增进知识，类似于打RPG游戏的升级。整理这篇文章的动机是两个问题：</P>
<DL>
<DT>问题一：</DT>
<DD>
<P>使用Windows记事本的“另存为”，可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件，Windows是怎样识别编码方式的呢？</P>
<P>我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节，分别是FF、FE（Unicode）,FE、FF（Unicode big endian）,EF、BB、BF（UTF-8）。但这些标记是基于什么标准呢？</P></DD>
<DT>问题二：</DT>
<DD>最近在网上看到一个ConvertUTF.c，实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、 GBK、UTF-8这些编码方式，我原来就了解。但这个程序让我有些糊涂，想不起来UTF-16和UCS2有什么关系。</DD></DL>
<P>查了查相关资料，总算将这些问题弄清楚了，顺带也了解了一些Unicode的细节。写成一篇文章，送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂，但要求读者知道什么是字节，什么是十六进制。</P>
<H3>0、big endian和little endian</H3>
<P>big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时，究竟是将6C写在前面，还是将49写在前面？如果将6C写在前面，就是big endian。如果将49写在前面，就是little endian。</P>
<P>“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开，由此曾发生过六次叛乱，一个皇帝送了命，另一个丢了王位。</P>
<P>我们一般将endian翻译成“字节序”，将big endian和little endian称作“大尾”和“小尾”。</P>
<H3>1、字符编码、内码，顺带介绍汉字编码</H3>
<P>字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码，为了处理汉字，程序员设计了用于简体中文的GB2312和用于繁体中文的big5。</P>
<P>GB2312(1980年)一共收录了7445个字符，包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7，低字节从A1-FE，占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。</P>
<P>GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号，它分为汉字区和图形符号区。汉字区包括21003个字符。</P>
<P>从ASCII、GB2312到GBK，这些编码方法是向下兼容的，即同一个字符在这些方案中总是有相同的编码，后面的标准支持更多的字符。在这些编码中，英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼，GB2312、GBK都属于双字节字符集 (DBCS)。</P>
<P>2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字，同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。从汉字字汇上说，GB18030在GB13000.1的20902个汉字的基础上增加了CJK扩展A的6582个汉字（Unicode码 0x3400-0x4db5），一共收录了27484个汉字。</P>
<P>CJK就是中日韩的意思。Unicode为了节省码位，将中日韩三国语言中的文字统一编码。GB13000.1就是ISO/IEC 10646-1的中文版，相当于Unicode 1.1。</P>
<P>GB18030的编码采用单字节、双字节和4字节方案。其中单字节、双字节和GBK是完全兼容的。4字节编码的码位就是收录了CJK扩展A的6582个汉字。 例如：UCS的0x3400在GB18030中的编码应该是8139EF30，UCS的0x3401在GB18030中的编码应该是8139EF31。</P>
<P>微软提供了GB18030的升级包，但这个升级包只是提供了一套支持CJK扩展A的6582个汉字的新字体：新宋体-18030，并不改变内码。Windows 的内码仍然是GBK。</P>
<P>这里还有一些细节：</P>
<UL>
<LI>
<P>GB2312的原文还是区位码，从区位码到内码，需要在高字节和低字节上分别加上A0。</P></LI>
<LI>
<P>对于任何字符编码，编码单元的顺序是由编码方案指定的，与endian无关。例如GBK的编码单元是字节，用两个字节表示一个汉字。 这两个字节的顺序是固定的，不受CPU字节序的影响。UTF-16的编码单元是word（双字节），word之间的顺序是编码方案指定的，word内部的字节排列才会受到endian的影响。后面还会介绍UTF-16。</P></LI>
<LI>
<P>GB2312 的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析：在读取DBCS字符流时，只要遇到高位为1的字节，就可以将下两个字节作为一个双字节编码，而不用管低字节的高位是什么。</P></LI></UL>
<H3>2、Unicode、UCS和UTF</H3>
<P>前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容（更准确地说，是与ISO-8859-1兼容），与GB码不兼容。例如“汉”字的Unicode编码是6C49，而GB码是BABA。</P>
<P>Unicode也是一种字符编码方法，不过它是由国际组织设计，可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set"，简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。</P>
<P>根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载：历史上存在两个试图独立设计Unicode的组织，即国际标准化组织（ISO）和一个软件制造商的协会（unicode.org）。ISO开发了ISO 10646项目，Unicode协会开发了Unicode项目。</P>
<P>在1991年前后，双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果，并为创立一个单一编码表而协同工作。从Unicode2.0开始，Unicode项目采用了与ISO 10646-1相同的字库和字码。</P>
<P>目前两个项目仍都存在，并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是ISO 10646-3:2003。</P>
<P>UCS只是规定如何编码，并没有规定如何传输、保存这个编码。例如“汉”字的UCS编码是6C49，我可以用4个ascii数字来传输、保存这个编码；也可以用utf-8编码:3个连续的字节E6 B1 89来表示它。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO-8859-1完全兼容。UTF是“UCS Transformation Format”的缩写。</P>
<P>IETF的RFC2781和RFC3629以RFC的一贯风格，清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。</P>
<H4>2.1、内码和code page</H4>
<P>目前Windows的内核已经支持Unicode字符集，这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码，例如GBK，Windows不可能不支持现有的编码，而全部改用Unicode。</P>
<P>Windows使用代码页(code page)来适应各个国家和地区。code page可以被理解为前面提到的内码。GBK对应的code page是CP936。</P>
<P>微软也为GB18030定义了code page：CP54936。但是由于GB18030有一部分4字节编码，而Windows的代码页只支持单字节和双字节编码，所以这个code page是无法真正使用的。</P>
<H3>3、UCS-2、UCS-4、BMP</H3>
<P>UCS有两种格式：UCS-2和UCS-4。顾名思义，UCS-2就是用两个字节编码，UCS-4就是用4个字节（实际上只用了31位，最高位必须为0）编码。下面让我们做一些简单的数学游戏：</P>
<P>UCS-2有2^16=65536个码位，UCS-4有2^31=2147483648个码位。</P>
<P>UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows)，每行包含256个cells。当然同一行的cells只是最后一个字节不同，其余都相同。</P>
<P>group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中，高两个字节为0的码位被称作BMP。</P>
<P>将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节，就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。</P>
<H3>4、UTF编码</H3>
<P></P>
<P>UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下：</P>
<TABLE width="75%" border=1>
<TBODY>
<TR>
<TD>UCS-2编码(16进制)</TD>
<TD>UTF-8 字节流(二进制)</TD></TR>
<TR>
<TD>0000 - 007F</TD>
<TD>0xxxxxxx</TD></TR>
<TR>
<TD>0080 - 07FF</TD>
<TD>110xxxxx 10xxxxxx</TD></TR>
<TR>
<TD>0800 - FFFF</TD>
<TD>1110xxxx 10xxxxxx 10xxxxxx</TD></TR></TBODY></TABLE>
<P>例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间，所以肯定要用3字节模板了：<FONT color=#0000ff>1110</FONT>xxxx <FONT color=#0000ff>10</FONT>xxxxxx <FONT color=#0000ff>10</FONT>xxxxxx。将6C49写成二进制是：0110 110001 001001， 用这个比特流依次代替模板中的x，得到：<FONT color=#0000ff>1110</FONT>0110 <FONT color=#0000ff>10</FONT>110001 <FONT color=#0000ff>10</FONT>001001，即E6 B1 89。</P>
<P>读者可以用记事本测试一下我们的编码是否正确。需要注意，UltraEdit在打开utf-8编码的文本文件时会自动转换为UTF-16，可能产生混淆。你可以在设置中关掉这个选项。更好的工具是Hex Workshop。</P>
<P>UTF-16以16位为单元对UCS进行编码。对于小于0x10000的UCS码，UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码，定义了一个算法。不过由于实际使用的UCS2，或者UCS4的BMP必然小于0x10000，所以就目前而言，可以认为 UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案，UTF-16却要用于实际的传输，所以就不得不考虑字节序的问题。</P>
<H3>5、UTF的字节序和BOM</H3>
<P>UTF-8以字节为编码单元，没有字节序的问题。UTF-16以两个字节为编码单元，在解释一个UTF-16文本前，首先要弄清楚每个编码单元的字节序。例如“奎”的Unicode编码是594E，“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”，那么这是“奎” 还是“乙”？</P>
<P>Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表，而是Byte Order Mark。BOM是一个有点小聪明的想法：</P>
<P>在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符，它的编码是FEFF。而FFFE在UCS中是不存在的字符，所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前，先传输字符"ZERO WIDTH NO-BREAK SPACE"。</P>
<P>这样如果接收者收到FEFF，就表明这个字节流是Big-Endian的；如果收到FFFE，就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。</P>
<P>UTF-8不需要BOM来表明字节顺序，但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF（读者可以用我们前面介绍的编码方法验证一下）。所以如果接收者收到以EF BB BF开头的字节流，就知道这是UTF-8编码了。</P>
<P>Windows就是使用BOM来标记文本文件的编码方式的。</P>
<H3>6、进一步的参考资料</H3>
<P>本文主要参考的资料是 "Short overview of ISO-IEC 10646 and Unicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。</P>
<P>我还找了两篇看上去不错的资料，不过因为我开始的疑问都找到了答案，所以就没有看：</P>
<OL>
<LI>"Understanding Unicode A general introduction to the Unicode Standard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter04a)</LI>
<LI>"Character set encoding basics Understanding character set encodings and legacy encodings" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter03)</LI></OL>
<P>我写过UTF-8、UCS-2、GBK相互转换的软件包，包括使用Windows API和不使用Windows API的版本。以后有时间的话，我会整理一下放到我的个人主页上(http://fmddlmyy.home4u.china.com)。</P>
<P>我是想清楚所有问题后才开始写这篇文章的，原以为一会儿就能写好。没想到考虑措辞和查证细节花费了很长时间，竟然从下午1:30写到9:00。希望有读者能从中受益。</P>
<H3>附录1 再说说区位码、GB2312、内码和代码页</H3>
<P>有的朋友对文章中这句话还有疑问：<BR>“GB2312的原文还是区位码，从区位码到内码，需要在高字节和低字节上分别加上A0。”</P>
<P>我再详细解释一下：</P>
<P>“GB2312的原文”是指国家1980年的一个标准《中华人民共和国国家标准 信息交换用汉字编码字符集 基本集 GB 2312-80》。这个标准用两个数来编码汉字和中文符号。第一个数称为“区”，第二个数称为“位”。所以也称为区位码。1-9区是中文符号，16-55 区是一级汉字，56-87区是二级汉字。现在Windows也还有区位输入法，例如输入1601得到“啊”。（这个区位输入法可以自动识别16进制的 GB2312和10进制的区位码，也就是说输入B0A1同样会得到“啊”。）</P>
<P>内码是指操作系统内部的字符编码。早期操作系统的内码是与语言相关的。现在的Windows在系统内部支持Unicode，然后用代码页适应各种语言，“内码”的概念就比较模糊了。微软一般将缺省代码页指定的编码说成是内码。</P>
<P>内码这个词汇，并没有什么官方的定义，代码页也只是微软这个公司的叫法。作为程序员，我们只要知道它们是什么东西，没有必要过多地考证这些名词。</P>
<P>所谓代码页(code page)就是针对一种语言文字的字符编码。例如GBK的code page是CP936，BIG5的code page是CP950，GB2312的code page是CP20936。</P>
<P>Windows中有缺省代码页的概念，即缺省用什么编码来解释字符。例如Windows的记事本打开了一个文本文件，里面的内容是字节流：BA、BA、D7、D6。Windows应该去怎么解释它呢？</P>
<P>是按照Unicode编码解释、还是按照GBK解释、还是按照BIG5解释，还是按照ISO8859-1去解释？如果按GBK去解释，就会得到“汉字”两个字。按照其它编码解释，可能找不到对应的字符，也可能找到错误的字符。所谓“错误”是指与文本作者的本意不符，这时就产生了乱码。</P>
<P>答案是Windows按照当前的缺省代码页去解释文本文件里的字节流。缺省代码页可以通过控制面板的区域选项设置。记事本的另存为中有一项ANSI，其实就是按照缺省代码页的编码方法保存。</P>
<P>Windows的内码是Unicode，它在技术上可以同时支持多个代码页。只要文件能说明自己使用什么编码，用户又安装了对应的代码页，Windows就能正确显示，例如在HTML文件中就可以指定charset。</P>
<P>有的HTML文件作者，特别是英文作者，认为世界上所有人都使用英文，在文件中不指定charset。如果他使用了0x80-0xff之间的字符，中文Windows又按照缺省的GBK去解释，就会出现乱码。这时只要在这个html文件中加上指定charset的语句，例如：<BR>&lt;meta http-equiv="Content-Type" content="text/html; charset=ISO8859-1"&gt;<BR>如果原作者使用的代码页和ISO8859-1兼容，就不会出现乱码了。</P>
<P>再说区位码，啊的区位码是1601，写成16进制是0x10,0x01。这和计算机广泛使用的ASCII编码冲突。为了兼容00-7f的ASCII 编码，我们在区位码的高、低字节上分别加上A0。这样“啊”的编码就成为B0A1。我们将加过两个A0的编码也称为GB2312编码，虽然GB2312的原文根本没提到这一点。 </P><img src ="http://www.blogjava.net/Pudgy/aggbug/11419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Pudgy/" target="_blank">Pudgy's World</a> 2005-08-29 11:39 <a href="http://www.blogjava.net/Pudgy/archive/2005/08/29/11419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DotDashBorder 可以实现点划线的CustomBorder</title><link>http://www.blogjava.net/Pudgy/archive/2005/08/27/11278.html</link><dc:creator>Pudgy's World</dc:creator><author>Pudgy's World</author><pubDate>Sat, 27 Aug 2005 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/Pudgy/archive/2005/08/27/11278.html</guid><wfw:comment>http://www.blogjava.net/Pudgy/comments/11278.html</wfw:comment><comments>http://www.blogjava.net/Pudgy/archive/2005/08/27/11278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Pudgy/comments/commentRss/11278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Pudgy/services/trackbacks/11278.html</trackback:ping><description><![CDATA[<A name=navbar_top></A><A title=跳过导航链接 href="file:///Z:/doc/DotDashBorder.html#skip-navbar_top"></A>一个Custom Border<BR>可以实现点划线的Border.<BR>代码如下：<BR><BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">import&nbsp;java.awt.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR>import&nbsp;javax.swing.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR>import&nbsp;javax.swing.border.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;<BR></SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;*&nbsp;DotDashBorder&nbsp;is&nbsp;a&nbsp;<CODE>java.swing.border.Border</CODE>&nbsp;implementation&nbsp;<BR>&nbsp;*&nbsp;that&nbsp;draws&nbsp;a&nbsp;dotted&nbsp;and/or&nbsp;dashed&nbsp;line&nbsp;border.&nbsp;&nbsp;The&nbsp;dot/dash&nbsp;pattern&nbsp;is&nbsp;<BR>&nbsp;*&nbsp;defined&nbsp;as&nbsp;an&nbsp;array&nbsp;of&nbsp;ints,&nbsp;with&nbsp;every&nbsp;two&nbsp;indices&nbsp;defining&nbsp;the&nbsp;number&nbsp;<BR>&nbsp;*&nbsp;of&nbsp;pixels&nbsp;for&nbsp;each&nbsp;dot/dash&nbsp;and&nbsp;space.&nbsp;&nbsp;E.g.:&nbsp;<BR><BR>&nbsp;*&nbsp;{&nbsp;1,&nbsp;1&nbsp;}&nbsp;==&nbsp;1-pixel-dot,&nbsp;1-pixel-space,&nbsp;1-pixel-dot,&nbsp;1-pixel-space,&nbsp;etc.<BR><BR>&nbsp;*&nbsp;{&nbsp;4,&nbsp;2&nbsp;}&nbsp;==&nbsp;4-pixel-dash,&nbsp;2-pixel-space,&nbsp;4-pixel-dash,&nbsp;2-pixel-space,&nbsp;etc.<BR><BR>&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;DotDashBorder&nbsp;extends&nbsp;AbstractBorder&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defines&nbsp;a&nbsp;dotted&nbsp;line&nbsp;pattern:&nbsp;&nbsp;<PRE>.&nbsp;.&nbsp;.&nbsp;.</PRE><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;final&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;DOT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;{&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&nbsp;};<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defines&nbsp;a&nbsp;dashed&nbsp;line&nbsp;pattern:&nbsp;&nbsp;<PRE>-&nbsp;-&nbsp;-&nbsp;-</PRE><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;final&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;DASH_SHORT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;{&nbsp;</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">&nbsp;};<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defines&nbsp;a&nbsp;long&nbsp;dashed&nbsp;line&nbsp;pattern:&nbsp;&nbsp;<PRE>---&nbsp;&nbsp;&nbsp;---&nbsp;&nbsp;&nbsp;---</PRE><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;final&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;DASH_LONG&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;{&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">&nbsp;};<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defines&nbsp;a&nbsp;long/short&nbsp;dashed&nbsp;line&nbsp;pattern:&nbsp;&nbsp;<PRE>--&nbsp;-&nbsp;--&nbsp;-&nbsp;--&nbsp;-</PRE><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;final&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;DASH_LONG_SHORT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;{&nbsp;</SPAN><SPAN style="COLOR: #000000">6</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&nbsp;};<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defines&nbsp;a&nbsp;long/short/short&nbsp;dashed&nbsp;line&nbsp;pattern:&nbsp;&nbsp;<PRE>--&nbsp;-&nbsp;-&nbsp;--&nbsp;-&nbsp;-&nbsp;--&nbsp;-&nbsp;-</PRE><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;final&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;DASH_LONG_SHORT_SHORT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;{&nbsp;</SPAN><SPAN style="COLOR: #000000">6</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&nbsp;};<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;dot/dash&nbsp;pattern.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;pattern&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;DOT;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;border&nbsp;thickness<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;thickness&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;foreground&nbsp;color.&nbsp;&nbsp;If&nbsp;not&nbsp;specified,&nbsp;the&nbsp;component's&nbsp;foreground&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;color&nbsp;is&nbsp;used.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;Color&nbsp;colorFG&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;background&nbsp;color.&nbsp;&nbsp;If&nbsp;not&nbsp;specified,&nbsp;the&nbsp;component's&nbsp;background&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;color&nbsp;is&nbsp;used.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;Color&nbsp;colorBG&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Thicken&nbsp;border&nbsp;pattern&nbsp;relative&nbsp;to&nbsp;thickness&nbsp;flag.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;boolean&nbsp;thicken&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Create&nbsp;a&nbsp;new&nbsp;1-pixel&nbsp;thick&nbsp;DotDashBorder&nbsp;using&nbsp;the&nbsp;component's&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;background&nbsp;color.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;pattern&nbsp;&nbsp;int[]:&nbsp;the&nbsp;dot/dash-space&nbsp;pattern<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;fg&nbsp;&nbsp;Color:&nbsp;the&nbsp;foreground&nbsp;(dot/dash)&nbsp;color<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;DotDashBorder(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;pattern,&nbsp;Color&nbsp;fg)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">(pattern,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;&nbsp;fg,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Create&nbsp;a&nbsp;new&nbsp;DotDashBorder&nbsp;using&nbsp;the&nbsp;component's&nbsp;foreground&nbsp;and&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;background&nbsp;colors.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;pattern&nbsp;&nbsp;int[]:&nbsp;the&nbsp;dot/dash-space&nbsp;pattern<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;thickness&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;thickness<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;DotDashBorder(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;pattern,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;thickness)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">(pattern,&nbsp;thickness,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Create&nbsp;a&nbsp;new&nbsp;DotDashBorder&nbsp;using&nbsp;the&nbsp;component's&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;background&nbsp;color.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;pattern&nbsp;&nbsp;int[]:&nbsp;the&nbsp;dot/dash-space&nbsp;pattern<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;thickness&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;thickness<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;fg&nbsp;&nbsp;Color:&nbsp;the&nbsp;foreground&nbsp;(dot/dash)&nbsp;color<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;DotDashBorder(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;pattern,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;thickness,&nbsp;Color&nbsp;fg)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">(pattern,&nbsp;thickness,&nbsp;&nbsp;fg,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Create&nbsp;a&nbsp;new&nbsp;DotDashBorder.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;pattern&nbsp;&nbsp;int[]:&nbsp;the&nbsp;dot/dash-space&nbsp;pattern<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;thickness&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;thickness<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;fg&nbsp;&nbsp;Color:&nbsp;the&nbsp;foreground&nbsp;(dot/dash)&nbsp;color<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;bg&nbsp;&nbsp;Color:&nbsp;the&nbsp;background&nbsp;(space)&nbsp;color<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;DotDashBorder(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;pattern,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;thickness,&nbsp;Color&nbsp;fg,&nbsp;Color&nbsp;bg)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;pattern.length;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(pattern[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</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">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;IllegalArgumentException(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Pattern&nbsp;cannot&nbsp;have&nbsp;values&nbsp;&lt;=&nbsp;0.</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.pattern&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;pattern;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(thickness&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;IllegalArgumentException(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Thickness&nbsp;cannot&nbsp;be&nbsp;&lt;=&nbsp;0.</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.thickness&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;thickness;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.colorFG&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;fg;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.colorBG&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;bg;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Get&nbsp;the&nbsp;insets&nbsp;for&nbsp;the&nbsp;border.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;Component&nbsp;c:&nbsp;the&nbsp;component&nbsp;the&nbsp;border&nbsp;is&nbsp;for<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;&nbsp;Insets:&nbsp;the&nbsp;insets&nbsp;for&nbsp;the&nbsp;border<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;&nbsp;#getBorderInsets(Component,&nbsp;Insets)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Insets&nbsp;getBorderInsets(Component&nbsp;c)&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">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Insets(thickness,&nbsp;thickness,&nbsp;thickness,&nbsp;thickness);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Get&nbsp;the&nbsp;insets&nbsp;for&nbsp;the&nbsp;border.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;Component&nbsp;c:&nbsp;the&nbsp;component&nbsp;the&nbsp;border&nbsp;is&nbsp;for<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;insets&nbsp;&nbsp;Insets:&nbsp;the&nbsp;insets<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;&nbsp;Insets:&nbsp;the&nbsp;insets&nbsp;for&nbsp;the&nbsp;border<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;&nbsp;#getBorderInsets(Component)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Insets&nbsp;getBorderInsets(Component&nbsp;c,&nbsp;Insets&nbsp;insets)&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">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Insets(thickness,&nbsp;thickness,&nbsp;thickness,&nbsp;thickness);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Check&nbsp;if&nbsp;the&nbsp;border&nbsp;is&nbsp;opaque.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;&nbsp;boolean:&nbsp;true&nbsp;if&nbsp;the&nbsp;border&nbsp;is&nbsp;opaque<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;boolean&nbsp;isBorderOpaque()&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;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Check&nbsp;if&nbsp;pattern&nbsp;will&nbsp;be&nbsp;thickened&nbsp;by&nbsp;thickness.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;&nbsp;boolean:&nbsp;true&nbsp;if&nbsp;pattern&nbsp;will&nbsp;be&nbsp;thickened&nbsp;by&nbsp;thickness<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;&nbsp;#setThickenPattern(boolean)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;boolean&nbsp;isThickenPattern()&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">this</SPAN><SPAN style="COLOR: #000000">.thicken;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Set&nbsp;if&nbsp;the&nbsp;pattern&nbsp;should&nbsp;be&nbsp;thickened&nbsp;by&nbsp;thickness.&nbsp;&nbsp;If&nbsp;true,&nbsp;a&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;pattern&nbsp;of&nbsp;{&nbsp;1,&nbsp;1&nbsp;}&nbsp;and&nbsp;thickness&nbsp;of&nbsp;5,&nbsp;the&nbsp;pattern&nbsp;would&nbsp;be&nbsp;expanded&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;to&nbsp;{&nbsp;5,&nbsp;5&nbsp;}.&nbsp;&nbsp;This&nbsp;allows&nbsp;setting&nbsp;a&nbsp;pattern&nbsp;based&nbsp;on&nbsp;small&nbsp;pixel&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;measurements&nbsp;that&nbsp;grows&nbsp;proportionally&nbsp;with&nbsp;the&nbsp;thickness.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;boolean&nbsp;t:&nbsp;true&nbsp;if&nbsp;pattern&nbsp;should&nbsp;be&nbsp;thickened&nbsp;by&nbsp;thickness<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;&nbsp;#isThickenPattern()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;setThickenPattern(boolean&nbsp;t)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.thicken&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;t;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Paint&nbsp;the&nbsp;border.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;Component&nbsp;c:&nbsp;the&nbsp;component&nbsp;the&nbsp;border&nbsp;is&nbsp;for<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;Graphics&nbsp;g:&nbsp;the&nbsp;graphics&nbsp;object&nbsp;to&nbsp;draw&nbsp;on<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;x&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;y&nbsp;position<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;y&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;x&nbsp;position<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;width&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;width<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;height&nbsp;&nbsp;int:&nbsp;the&nbsp;border&nbsp;height<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;paintBorder(Component&nbsp;c,&nbsp;Graphics&nbsp;g,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;x,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;y,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;width,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;height)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Color&nbsp;colorFGX&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;c.getBackground();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(colorFG&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;colorFGX&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;colorFG;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Color&nbsp;colorBGX&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;c.getBackground();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(colorBG&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;colorBGX&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;colorBG;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(colorFGX);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(x,&nbsp;x,&nbsp;width,&nbsp;thickness);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;top</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(x,&nbsp;y</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">height</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">thickness,&nbsp;width,&nbsp;thickness);&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;bottom</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(x,&nbsp;y,&nbsp;thickness,&nbsp;height);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;left</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(x</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">width</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">thickness,&nbsp;y,&nbsp;thickness,&nbsp;height);&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;right</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(colorBGX);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;top/bottom</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;cx&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;get&nbsp;real&nbsp;pattern</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;realPattern&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[pattern.length];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;pattern.length;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(thicken)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;realPattern[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;pattern[i]</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">thickness;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;realPattern[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;pattern[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,&nbsp;j&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;width;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">,&nbsp;j</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(j&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;realPattern.length)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</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;&nbsp;&nbsp;&nbsp;&nbsp;cx&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;realPattern[j];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(cx,&nbsp;y,&nbsp;realPattern[j</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">],&nbsp;thickness);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;top</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(cx,&nbsp;y</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">height</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">thickness,&nbsp;realPattern[j</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">],&nbsp;thickness);&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;bottom</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cx&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;realPattern[j</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">1</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: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;left/right</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;cy&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,&nbsp;j&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;height;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">,&nbsp;j</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(j&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;realPattern.length)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</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;&nbsp;&nbsp;&nbsp;&nbsp;cy&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;realPattern[j];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(x,&nbsp;cy,&nbsp;thickness,&nbsp;realPattern[j</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;left</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(x</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">width</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">thickness,&nbsp;cy,&nbsp;thickness,&nbsp;realPattern[j</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">]);&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;right</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cy&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;realPattern[j</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</SPAN></DIV></DIV><img src ="http://www.blogjava.net/Pudgy/aggbug/11278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Pudgy/" target="_blank">Pudgy's World</a> 2005-08-27 10:19 <a href="http://www.blogjava.net/Pudgy/archive/2005/08/27/11278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的SplashScreen</title><link>http://www.blogjava.net/Pudgy/archive/2005/08/22/10734.html</link><dc:creator>Pudgy's World</dc:creator><author>Pudgy's World</author><pubDate>Mon, 22 Aug 2005 13:29:00 GMT</pubDate><guid>http://www.blogjava.net/Pudgy/archive/2005/08/22/10734.html</guid><wfw:comment>http://www.blogjava.net/Pudgy/comments/10734.html</wfw:comment><comments>http://www.blogjava.net/Pudgy/archive/2005/08/22/10734.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/Pudgy/comments/commentRss/10734.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Pudgy/services/trackbacks/10734.html</trackback:ping><description><![CDATA[<FONT face=Verdana size=2>最近编写项目，用到一个Splash Screen。<BR>现奉献给大家。<BR><BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">import&nbsp;java.awt.Dimension;<BR>import&nbsp;java.awt.Toolkit;<BR>import&nbsp;java.net.URL;<BR><BR>import&nbsp;javax.swing.ImageIcon;<BR>import&nbsp;javax.swing.JFrame;<BR>import&nbsp;javax.swing.JLabel;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;SplashScreen&nbsp;extends&nbsp;JFrame&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*Date&nbsp;08.17.2005<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Splash&nbsp;Screen<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Very&nbsp;Simple<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;Pudgy<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@version&nbsp;0.01<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><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;final&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">5124L</SPAN><SPAN style="COLOR: #000000">;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;SplashScreen()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Starting&nbsp;jDicomSee<IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Toolkit&nbsp;toolkit&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Toolkit.getDefaultToolkit();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dimension&nbsp;screenSize&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;toolkit.getScreenSize();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL&nbsp;imageURL&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;searchFile(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">splash.png</SPAN><SPAN style="COLOR: #000000">"</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;(imageURL&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;getContentPane().add(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;JLabel(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ImageIcon(imageURL)));<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setUndecorated(</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pack();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setLocation((screenSize.width&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;getWidth())&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;&nbsp;&nbsp;&nbsp;&nbsp;(screenSize.height&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;getHeight())&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;setVisible(</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</SPAN><SPAN style="COLOR: #000000">1500</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<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;URL&nbsp;searchFile(String&nbsp;fileName)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL&nbsp;url&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;getClass().getClassLoader().getResource(fileName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(url&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;getClass().getClassLoader().getResource(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">images/</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;fileName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;url;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR></SPAN></DIV></DIV></FONT><img src ="http://www.blogjava.net/Pudgy/aggbug/10734.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Pudgy/" target="_blank">Pudgy's World</a> 2005-08-22 21:29 <a href="http://www.blogjava.net/Pudgy/archive/2005/08/22/10734.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Learning Path </title><link>http://www.blogjava.net/Pudgy/archive/2005/08/15/10177.html</link><dc:creator>Pudgy's World</dc:creator><author>Pudgy's World</author><pubDate>Mon, 15 Aug 2005 14:31:00 GMT</pubDate><guid>http://www.blogjava.net/Pudgy/archive/2005/08/15/10177.html</guid><wfw:comment>http://www.blogjava.net/Pudgy/comments/10177.html</wfw:comment><comments>http://www.blogjava.net/Pudgy/archive/2005/08/15/10177.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Pudgy/comments/commentRss/10177.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Pudgy/services/trackbacks/10177.html</trackback:ping><description><![CDATA[<P dir=ltr style="MARGIN-RIGHT: 0px"><BR>Java&nbsp;Learning&nbsp;Path&nbsp;（一）、工具篇&nbsp;<BR>一、&nbsp;JDK&nbsp;(Java&nbsp;Development&nbsp;Kit)&nbsp;<BR><BR>JDK是整个Java的核心，包括了Java运行环境（Java&nbsp;Runtime&nbsp;Envirnment），一堆Java工具和Java基础的类库(rt.jar)。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握JDK是学好Java的第一步。最主流的JDK是Sun公司发布的JDK，除了Sun之外，还有很多公司和组织都开发了自己的JDK，例如IBM公司开发的JDK，BEA公司的Jrocket，还有GNU组织开发的JDK等等。其中IBM的JDK包含的JVM（Java&nbsp;Virtual&nbsp;Machine）运行效率要比Sun&nbsp;JDK包含的JVM高出许多。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun&nbsp;JDK好很多。但不管怎么说，我们还是需要先把Sun&nbsp;JDK掌握好。&nbsp;<BR><BR>1、&nbsp;JDK的下载和安装&nbsp;<BR>JDK又叫做J2SE（Java2&nbsp;SDK&nbsp;Standard&nbsp;Edition），可以从Sun的Java网站上下载到，http://java.sun.com/j2se/downloads.html&nbsp;，JDK当前最新的版本是J2SDK1.4.2，建议下载该版本的JDK，下载页面在这里：http://java.sun.com/j2se/1.4.2/download.html。&nbsp;<BR><BR>下载好的JDK是一个可执行安装程序，默认安装完毕后会在C:\Program&nbsp;Files\Java\目录下安装一套JRE（供浏览器来使用），在C:\j2sdk1.4.2下安装一套JDK（也包括一套JRE）。然后我们需要在环境变量PATH的最前面增加java的路径C:\j2sdk1.4.2\bin。这样JDK就安装好了。&nbsp;<BR><BR>2、&nbsp;JDK的命令工具&nbsp;<BR>JDK的最重要命令行工具：&nbsp;<BR>java：&nbsp;启动JVM执行class&nbsp;<BR>javac：&nbsp;Java编译器&nbsp;<BR>jar：&nbsp;Java打包工具&nbsp;<BR>javadoc：&nbsp;Java文档生成器&nbsp;<BR>这些命令行必须要非常非常熟悉，对于每个参数都要很精通才行。对于这些命令的学习，JDK&nbsp;Documentation上有详细的文档。&nbsp;<BR><BR><BR>二、&nbsp;JDK&nbsp;Documentation&nbsp;<BR><BR>Documentation在JDK的下载页面也有下载连接，建议同时下载Documentation。Documentation是最最重要的编程手册，涵盖了整个Java所有方面的内容的描述。可以这样说，学习Java编程，大部分时间都是花在看这个Documentation上面的。我是随身携带的，写Java代码的时候，随时查看，须臾不离手。&nbsp;<BR><BR><BR>三、&nbsp;应用服务器(App&nbsp;Server)&nbsp;<BR><BR>App&nbsp;Server是运行Java企业组件的平台，构成了应用软件的主要运行环境。当前主流的App&nbsp;Server是BEA公司的Weblogic&nbsp;Server和IBM公司的Websphere以及免费的Jboss，选择其中一个进行学习就可以了，个人推荐Weblogic，因为它的体系结构更加干净，开发和部署更加方便，是Java企业软件开发人员首选的开发平台。下面简要介绍几种常用的App&nbsp;Server：&nbsp;<BR><BR>1、&nbsp;Tomcat&nbsp;<BR>Tomcat严格意义上并不是一个真正的App&nbsp;Server，它只是一个可以支持运行Serlvet/JSP的Web容器，不过Tomcat也扩展了一些App&nbsp;Server的功能，如JNDI，数据库连接池，用户事务处理等等。Tomcat被非常广泛的应用在中小规模的Java&nbsp;Web应用中，因此本文做一点下载、安装和配置Tomcat的介绍：&nbsp;<BR><BR>Tomcat是Apache组织下Jakarta项目下的一个子项目，它的主网站是：http://jakarta.apache.org/tomcat/&nbsp;，Tomcat最新版本是Tomcat4.1.27，软件下载的连接是：http://www.apache.org/dist/jakarta/tomcat-4/binaries/&nbsp;。&nbsp;<BR><BR>下载Tomcat既可以直接下载zip包，也可以下载exe安装包（个人建议zip更干净些），不管哪种情况，下载完毕安装好以后（zip直接解压缩就可以了）。需要设置两个环境变量：&nbsp;<BR><BR>JAVA_HOME=C:\j2sdk1.4.2&nbsp;<BR>CATALINA_HOME=D:\tomcat4&nbsp;(你的Tomcat安装目录)&nbsp;<BR><BR>这样就安装好了，启动Tomcat运行CATALINA_HOME\bin\startup.bat，关闭Tomcat运行shutdown.bat脚本。Tomcat启动以后，默认使用8080端口，因此可以用浏览器访问http://localhost:8080来测试Tomcat是否正常启动。&nbsp;<BR><BR>Tomcat提供了两个Web界面的管理工具，URL分别是：&nbsp;<BR>http://localhost:8080/admin/index.jsp&nbsp;<BR>http://localhost:8080/manager/html&nbsp;<BR>在启用这两个管理工具之前，先需要手工配置一下管理员用户和口令。用一个文本工具打开CATALINA_HOME\conf\tomcat-users.xml这个文件，加入如下几行：&nbsp;<BR><BR>&lt;role&nbsp;rolename="manager"/&gt;&nbsp;<BR>&lt;role&nbsp;rolename="admin"/&gt;&nbsp;<BR>&lt;user&nbsp;username="robbin"&nbsp;password="12345678"&nbsp;roles="admin,manager,tomcat"/&gt;&nbsp;<BR><BR>这样用户“robbin”就具备了超级管理员权限。重新启动Tomcat以后，你就可以使用该用户来登陆如上的两个管理工具，通过Web方式进行Tomcat的配置和管理了。&nbsp;<BR><BR>2、&nbsp;BEA&nbsp;Weblogic&nbsp;<BR>Weblogic可以到BEA的网站上免费注册之后下载到最新的Weblogic8.1企业版，License可以免费使用1年时间，其实这已经完全足够了。Weblogic的下载连接：http://commerce.bea.com/index.jsp，Weblogic的在线文档：http://edocs.bea.com/&nbsp;。&nbsp;<BR><BR>3、&nbsp;IBM&nbsp;Webshpere&nbsp;<BR>Websphere同样可以下载到免费的试用版本，到IBM的developerWorks网站可以看到Websphere试用产品的下载和相关的Websphere的资料，developerWorks中文网站的连接是：http://www-900.ibm.com/developerWorks/cn/wsdd/&nbsp;，Websphere的下载连接：http://www7b.software.ibm.com/wsdd/downloads/WASsupport.html&nbsp;。&nbsp;<BR><BR>4、&nbsp;Jboss&nbsp;<BR>Jboss是免费开源的App&nbsp;Server，可以免费的从Jboss网站下载：http://www.jboss.org/index.html，然而Jboss的文档是不免费，需要花钱购买，所以为我们学习Jboss设置了一定的障碍。在Jdon上有几篇不错的Jboss配置文档，可以用来参考：http://www.jdon.com/idea.html&nbsp;<BR><BR><BR>四、&nbsp;Java应用的运行环境&nbsp;<BR><BR>Java的应用可以简单分为以下几个方面：&nbsp;<BR><BR>1、&nbsp;Java的桌面应用&nbsp;<BR>桌面应用一般仅仅需要JRE的支持就足够了。&nbsp;<BR><BR>2、&nbsp;Java&nbsp;Web应用&nbsp;<BR>Java的Web应用至少需要安装JDK和一个web容器（例如Tomcat），以及一个多用户数据库，Web应用至少分为三层：&nbsp;<BR>Browser层：浏览器显示用户页面&nbsp;<BR>Web层：运行Servlet/JSP&nbsp;<BR>DB层：后端数据库，向Java程序提供数据访问服务&nbsp;<BR><BR>3、&nbsp;Java企业级应用&nbsp;<BR>企业级应用比较复杂，可以扩展到n层，最简单情况会分为4层：&nbsp;<BR>Browser层：浏览器显示用户页面&nbsp;<BR>Client层：Java客户端图形程序（或者嵌入式设备的程序）直接和Web层或者EJB层交互&nbsp;<BR>Web层：运行Servlet/JSP&nbsp;<BR>EJB层：运行EJB，完成业务逻辑运算&nbsp;<BR>DB层：后端数据库，向Java程序提供数据访问服务&nbsp;<BR><BR>4、&nbsp;Java嵌入式应用&nbsp;<BR>Java嵌入式应用是一个方兴未艾的领域，从事嵌入式开发，需要从Sun下载J2ME开发包，J2ME包含了嵌入式设备专用虚拟机KVM，和普通的JDK中包含的JVM有所不同。另外还需要到特定的嵌入式厂商那里下载模拟器。&nbsp;<BR><BR><BR>Java&nbsp;Learning&nbsp;Path（二）、书籍篇&nbsp;<BR><BR>学习一门新的知识，不可能指望只看一本，或者两本书就能够完全掌握。需要有一个循序渐进的阅读过程。我推荐Oreilly出版的Java系列书籍。&nbsp;<BR><BR>在这里我只想补充一点看法，很多人学习Java是从《Thinking&nbsp;in&nbsp;Java》这本书入手的，但是我认为这本书是不适合初学者的。我认为正确的使用这本书的方法应该是作为辅助的读物。《Thinking&nbsp;in&nbsp;Java》并不是在完整的介绍Java的整个体系，而是一种跳跃式的写作方法，是一种类似tips的方法来对Java很多知识点进行了深入的分析和解释。&nbsp;<BR><BR>对于初学者来说，最好是找一本Java入门的书籍，但是比较完整的循序的介绍Java的语法，面向对象的特性，核心类库等等，在看这本书的同时，可以同步来看《Thinking&nbsp;in&nbsp;Java》，来加深对Java的理解和原理的运用，同时又可以完整的了解Java的整个体系。&nbsp;<BR><BR>对于Java的入门书籍，蔡学镛推荐的是Oreilly的《Exploring&nbsp;Java,&nbsp;2nd&nbsp;Edition》&nbsp;或者《Java&nbsp;in&nbsp;a&nbsp;Nutshell,2nd&nbsp;Edition（针对C++背景）》，我并没有看过这两本书。其实我觉得电子工业出版社的《Java&nbsp;2编程详解》或者《Java&nbsp;2从入门到精通》就很不错。&nbsp;<BR><BR>在所有的Java书籍当中，其实最最有用的，并不是O'reilly的&nbsp;Java&nbsp;Serials，真正最最有用处是JDK的Documentation！几乎你想获得的所有的知识在Documentation里面全部都有，其中最主要的部分当然是Java基础类库的API文档，是按照package来组织的，对于每一个class都有详细的解释，它的继承关系，是否实现了某个接口，通常用在哪些场合，还可以查到它所有的public的属性和方法，每个属性的解释，意义，每个方法的用途，调用的参数，参数的意义，返回值的类型，以及方法可能抛出的异常等等。可以这样来说，所有关于Java编程方面的书籍其实都不过是在用比较通俗易懂的语言，和良好的组织方式来介绍Documentation里面的某个package里面包含的一些类的用法而已。所以万变不离其宗，如果你有足够的能力来直接通过Documentation来学习Java的类库，那么基本上就不需要看其他的书籍了。除此之外，Documentation也是编程必备的手册，我的桌面上有三个Documentation的快捷方式，分别是J2SDK1.4.1的Documentation，Servlet2.3的Documentation和J2SDKEE1.3.1的Documentation。有了这个三个Documentation，什么其他的书籍都不需要了。&nbsp;<BR><BR>对于Java&nbsp;Web&nbsp;编程来说，最核心的是要熟悉和掌握HTTP协议，这个就和Java无关了，在熟悉HTTP协议之后，就需要熟悉Java的实现HTTP协议的类库，也就是Servlet&nbsp;API，所以最重要的东西就是Servlet&nbsp;API。当然对于初学者而言，直接通过Servlet&nbsp;API来学习Web编程有很大的难度，我推荐O'reilly的《Java&nbsp;Server&nbsp;Pages&nbsp;》这本书来学习Web&nbsp;编程。&nbsp;<BR><BR>EJB的书籍当中，《Enterprise&nbsp;JavaBeans,&nbsp;2nd&nbsp;Edition》是一本很不错的书，&nbsp;EJB的学习门槛是比较高，入门很难，但是这本书完全降低了学习的难度，特别重要的一点是，EJB的学习需要结合一种App&nbsp;Server的具体实现，所以在学习EJB的同时，必须同步的学习某种App&nbsp;Server，而这本书相关的出了三本书，分别是Weblogic6.1，Websphere4.0和JBoss3.0上面部署书中例子的实做。真是既有理论，又有实践。在学习EJB的同时，可以边看边做，EJB的学习会变得很轻松。&nbsp;<BR><BR>但是这本书也有一个问题，就是版本比较旧，主要讲EJB1.1规范和部分EJB2.0的规范。而Ed&nbsp;Roman写的《Mastering&nbsp;EJB&nbsp;2.0》这本书完全是根据EJB2.0规范写的，深入浅出，覆盖了EJB编程的各个方面，并且还有很多编程经验tips，也是学习EJB非常推荐的书籍之一。&nbsp;<BR><BR>如果是结合Weblogic来学习J2EE的话，《J2EE应用与BEA&nbsp;Weblogic&nbsp;Server》绝对是首选读物，虽然是讲述的Weblogic6.0，仍然值得购买，这本书是BEA官方推荐的教材，作者也是BEA公司的工程师。现在中文版已经随处可见了。这本书结合Weblogic介绍了J2EE各个方面的技术在Weblogic平台上的开发和部署，实践指导意义非常强。&nbsp;<BR><BR>在掌握了Java平台基础知识和J2EE方面的知识以后，更进一步的是学习如何运用OO的方法进行软件的设计，那么就一定要学习“设计模式”。Sun公司出版了一本《J2EE核心模式》，是每个开发Java企业平台软件的架构师必备的书籍。这本书全面的介绍了J2EE体系架构的各种设计模式，是设计师的必读书籍。&nbsp;<BR><BR>Java&nbsp;Learning&nbsp;Path（三）过程篇&nbsp;<BR><BR>每个人的学习方法是不同的，一个人的方法不见得适合另一个人，我只能是谈自己的学习方法。因为我学习Java是完全自学的，从来没有问过别人，所以学习的过程基本上完全是自己摸索出来的。我也不知道这种方法是否是比较好的方法，只能给大家提供一点参考了。&nbsp;<BR><BR>学习Java的第一步是安装好JDK，写一个Hello&nbsp;World，?&nbsp;其实JDK的学习没有那么简单，关于JDK有两个问题是很容易一直困扰Java程序员的地方：一个是CLASSPATH的问题，其实从原理上来说，是要搞清楚JRE的ClassLoader是如何加载Class的；另一个问题是package和import问题，如何来寻找类的路径问题。把这两个问题摸索清楚了，就扫除了学习Java和使用JDK的最大障碍。推荐看一下王森的《Java深度历险》，对这两个问题进行了深入的探讨。&nbsp;<BR><BR>第二步是学习Java的语法。Java的语法是类C++的，基本上主流的编程语言不是类C，就是类C++的，没有什么新东西，所以语法的学习，大概就是半天的时间足够了。唯一需要注意的是有几个不容易搞清楚的关键字的用法，public，protected，private，static，什么时候用，为什么要用，怎么用，这可能需要有人来指点一下，我当初是完全自己琢磨出来的，花了很久的时间。不过后来我看到《Thinking&nbsp;in&nbsp;Java》这本书上面是讲了这些概念的。&nbsp;<BR><BR>第三步是学习Java的面向对象的编程语言的特性的地方。比如继承，构造器，抽象类，接口，方法的多态，重载，覆盖，Java的异常处理机制。对于一个没有面向对象语言背景的人来说，我觉得这个过程需要花很长很长时间，因为学习Java之前没有C++的经验，只有C的经验，我是大概花了一个月左右吧，才彻底把这些概念都搞清楚，把书上面的例子反复的揣摩，修改，尝试，把那几章内容反复的看过来，看过去，看了不下5遍，才彻底领悟了。不过我想如果有C++经验的话，应该一两天时间足够了。那么在这个过程中，可以多看看《Thinking&nbsp;in&nbsp;Java》这本书，对面向对象的讲解非常透彻。可惜的是我学习的时候，并没有看到这本书，所以自己花了大量的时间，通过自己的尝试和揣摩来学会的。&nbsp;<BR><BR>第四步就是开始熟悉Java的类库。Java的基础类库其实就是JDK安装目录下面jre\lib\rt.jar这个包。学习基础类库就是学习rt.jar。基础类库里面的类非常非常多。据说有3000多个，我没有统计过。但是真正对于我们来说最核心的只有4个，分别是&nbsp;<BR>java.lang.*;&nbsp;<BR>java.io.*;&nbsp;<BR>java.util.*;&nbsp;<BR>java.sql.*;&nbsp;<BR><BR>这四个包的学习，每个包的学习都可以写成一本厚厚的教材，而O'reilly也确实是这样做的。我觉得如果时间比较紧，是不可能通过读四本书来学习。我觉得比较好的学习方法是这样的：&nbsp;<BR>首先要通读整个package的框架，了解整个package的class，interface，exception的构成，最好是能够找到介绍整个包框架的文章。这些专门介绍包的书籍的前几章应该就是这些总体的框架内容介绍。&nbsp;<BR><BR>对包整体框架的把握并不是要熟悉每个类的用法，记住它有哪些属性，方法。想记也记不住的。而是要知道包有哪些方面的类构成的，这些类的用途是什么，最核心的几个类分别是完成什么功能的。我在给人培训的时候一般是一次课讲一个包，所以不可能详细的介绍每个类的用法，但是我反复强调，我给你们讲这些包的不是要告诉你们类的方法是怎么调用的，也不要求你们记住类的方法调用，而是要你们了解，Java给我们提供了哪些类，每个类是用在什么场合，当我遇到问题的时候，我知道哪个类，或者哪几个类的组合可以解决我的问题，That'all！，当我们具体写程序的时候，只要你知道该用哪个类来完成你的工作就足够了。编码的时候，具体的方法调用，是边写代码，边查Documentation，所有的东西都在Documentation里面，不要求你一定记住，实际你也记不住3000多个类的总共将近10万个方法调用。所以对每个包的总体框架的把握就变得极为重要。&nbsp;<BR><BR>第五步，通过上面的学习，如果学的比较扎实的话，就打好了Java的基础了，剩下要做的工作是扫清Documentation里面除了上面4个包之外的其他一些比较有用处的类。相信进展到这一步，Java的自学能力已经被培养出来了，可以到了直接学习Documentation的水平了。除了要做GUI编程之外，JDK里面其他会有用处的包是这些：&nbsp;<BR>java.text.*;&nbsp;<BR>java.net.*;&nbsp;<BR>javax.naming.*;&nbsp;<BR>这些包里面真正用的比较多的类其实很少，只有几个，所以不需要花很多时间。&nbsp;<BR><BR>第六步，Java&nbsp;Web&nbsp;编程&nbsp;<BR>Web编程的核心是HTTP协议，HTTP协议和Java无关，如果不熟悉HTTP协议的话，虽然也可以学好Servlet/JSP编程，但是达不到举一反三，一通百通的境界。所以HTTP协议的学习是必备的。如果熟悉了HTTP协议的话，又有了Java编程的良好的基础，学习Servlet/JSP简直易如反掌，我学习Servlet/JSP就用了不到一周的时间，然后就开始用JSP来做项目了。&nbsp;<BR><BR>在Servlet/JSP的学习中，重头仍然是Servlet&nbsp;Documentation。Servlet&nbsp;API最常用的类很少，花比较少的时间就可以掌握了。把这些类都看一遍，多写几个例子试试。Servlet/JSP编程本质就是在反复调用这些类来通过HTTP协议在Web&nbsp;Server和Brower之间交谈。另外对JSP，还需要熟悉几个常用JSP的标记，具体的写法记不住的话，临时查就是了。&nbsp;<BR><BR>此外Java&nbsp;Web编程学习的重点要放在Web&nbsp;Application的设计模式上，如何进行业务逻辑的分析，并且进行合理的设计，按照MVC设计模式的要求，运用Servlet和JSP分别完成不同的逻辑层，掌握如何在Servlet和JSP之间进行流程的控制和数据的共享，以及Web&nbsp;Application应该如何配置和部署。&nbsp;<BR><BR>第七步，J2EE编程&nbsp;<BR>以上的学习过程如果是比较顺利的话，进行到这一步，难度又陡然提高。因为上面的知识内容都是只涉及一个方面，而像EJB，JMS，JTA等核心的J2EE规范往往是几种Java技术的综合运用的结晶，所以掌握起来难度比较大。&nbsp;<BR><BR>首先一定要学习好JNDI，JNDI是App&nbsp;Server定位服务器资源（EJB组件，Datasouce，JMS）查找方法，如果对JNDI不熟悉的话，EJB，JMS这些东西几乎学不下去。JNDI其实就是javax.naming.*这个包，运用起来很简单。难点在于服务器资源文件的配置。对于服务器资源文件的配置，就需要看看专门的文档规范了，比如web.xml的写法，ejb-jar.xml的写法等等。针对每种不同的App&nbsp;Server，还有自己的服务资源配置文件，也是需要熟悉的。&nbsp;<BR><BR>然后可以学习JTA，主要是要理解JTA对于事务的控制的方法，以及该在什么场合使用JTA。这里可以简单的举个例子，我们知道一般情况可以对于一个数据库连接进行事务控制(conn.setAutoCommit(false),....,conn.commit())，做为一个原子操作，但是假设我的业务需求是要把对两个不同数据库的操作做为一个原子操作，你能做的到吗？这时候只能用JTA了。假设操作过程是先往A数据库插一条记录，然后删除B数据库另一个记录，我们自己写代码是控制不了把整个操作做为一个原子操作的。用JTA的话，由App&nbsp;Server来完成控制。&nbsp;<BR><BR>在学习EJB之前要学习对象序列化和RMI，RMI是EJB的基础。接着学习JMS和EJB，对于EJB来说，最关键是要理解EJB是如何通过RMI来实现对远端对象的调用的，以及在什么情况下要用到EJB。&nbsp;<BR><BR>在学习完EJB，JMS这些东西之后，你可能会意识到要急不可待学习两个领域的知识，一个是UML，另一个是Design&nbsp;Pattern。Java企业软件的设计非常重视框架(Framework)的设计，一个好的软件框架是软件开发成功的必要条件。在这个时候，应该开始把学习的重点放在设计模式和框架的学习上，通过学习和实际的编程经验来掌握EJB的设计模式和J2EE的核心模式。&nbsp;<BR><BR>J2EE规范里面，除了EJB，JMS，JTA，Servlet/JSP，JDBC之外还有很多很多的企业技术，这里不一一进行介绍了。&nbsp;<BR><BR>另外还有一个最新领域Web&nbsp;Services。Web&nbsp;Services也完全没有任何新东西，它像是一种黏合剂，可以把不同的服务统一起来提供一个统一的调用接口，作为使用者来说，我只要获得服务提供者给我的WSDL（对服务的描述），就够了，我完全不知道服务器提供者提供的服务究竟是EJB组件，还是.Net组件，还是什么CORBA组件，还是其他的什么实现，我也不需要知道。Web&nbsp;Services最伟大的地方就在于通过统一的服务提供方式和调用方式，实现了整个Internet服务的共享，是一个非常令人激动的技术领域。Web&nbsp;Services好像目前还没有什么很好的书籍，但是可以通过在网络上面查资料的方式来学习。&nbsp;<BR><BR>Java&nbsp;Learning&nbsp;Path（四）&nbsp;方法篇&nbsp;<BR><BR>Java作为一门编程语言，最好的学习方法就是写代码。当你学习一个类以后，你就可以自己写个简单的例子程序来运行一下，看看有什么结果，然后再多调用几个类的方法，看看运行结果，这样非常直观的把类给学会了，而且记忆非常深刻。然后不应该满足把代码调通，你应该想想看如果我不这样写，换个方式，再试试行不行。记得哪个高人说过学习编程就是个破坏的过程，把书上的例子，自己学习Documentation编写的例子在运行通过以后，不断的尝试着用不同的方法实现，不断的尝试破坏代码的结构，看看它会有什么结果。通过这样的方式，你会很彻底的很精通的掌握Java。&nbsp;<BR><BR>举个例子，我们都编过Hello&nbsp;World&nbsp;<BR><BR></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG id=Codehighlighter1_24_108_Open_Image onclick="this.style.display='none'; Codehighlighter1_24_108_Open_Text.style.display='none'; Codehighlighter1_24_108_Closed_Image.style.display='inline'; Codehighlighter1_24_108_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_24_108_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_24_108_Closed_Text.style.display='none'; Codehighlighter1_24_108_Open_Image.style.display='inline'; Codehighlighter1_24_108_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;HelloWorld&nbsp;</SPAN><SPAN id=Codehighlighter1_24_108_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_24_108_Open_Text><SPAN style="COLOR: #000000">{&nbsp;<BR><IMG id=Codehighlighter1_66_105_Open_Image onclick="this.style.display='none'; Codehighlighter1_66_105_Open_Text.style.display='none'; Codehighlighter1_66_105_Closed_Image.style.display='inline'; Codehighlighter1_66_105_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_66_105_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_66_105_Closed_Text.style.display='none'; Codehighlighter1_66_105_Open_Image.style.display='inline'; Codehighlighter1_66_105_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</SPAN><SPAN id=Codehighlighter1_66_105_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_66_105_Open_Text><SPAN style="COLOR: #000000">{&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Hello&nbsp;World</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV></DIV>
<P dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;<BR><BR>很多初学者不是很理解为什么main方法一定要这样来定义public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)，能不能不这样写？包括我刚学习Java的时候也有这样的疑问。想知道答案吗？很简单，你把main改个名字运行一下，看看报什么错误，然后根据出错信息进行分析；把main的public取掉，在试试看，报什么错误；static去掉还能不能运行；不知道main方法是否一定要传一个String[]数组的，把String[]改掉，改成int[]，或者String试试看；不知道是否必须写args参数名称的，也可以把args改成别的名字，看看运行结果如何。&nbsp;<BR><BR>我当初学习Java的时候就是这样做的，把Hello&nbsp;World程序反复改了七八次，不断运行，分析运行结果，最后就彻底明白为什么了main方法是这样定义的了。&nbsp;<BR><BR>此外，我对于staic，public，private，Exception，try{&nbsp;}catch&nbsp;{}finally{}等等等等一开始都不是很懂，都是把参考书上面的例子运行成功，然后就开始破坏它，不断的根据自己心里面的疑问来重新改写程序，看看能不能运行，运行出来是个什么样子，是否可以得到预期的结果。这样虽然比较费时间，不过一个例子程序这样反复破坏几次之后。我就对这个相关的知识彻底学通了。有时候甚至故意写一些错误的代码来运行，看看能否得到预期的运行错误。这样对于编程的掌握是及其深刻的。&nbsp;<BR><BR>其中特别值得一提的是JDK有一个非常棒的调试功能，-verbose&nbsp;<BR>java&nbsp;-verbose&nbsp;<BR>javac&nbsp;-verbose&nbsp;以及其它很多JDK工具都有这个选项&nbsp;<BR>-verbose&nbsp;可以显示在命令执行的过程中，JVM都依次加载哪里Class，通过这些宝贵的调试信息，可以帮助我们分析出JVM在执行的过程中都干了些什么。&nbsp;<BR><BR>另外，自己在学习过程中，写的很多的这种破坏例程，应该有意识的分门别类的保存下来，在工作中积累的典型例程也应该定期整理，日积月累，自己就有了一个代码库了。遇到类似的问题，到代码库里面&nbsp;Copy&nbsp;&amp;&nbsp;Paste&nbsp;，Search&nbsp;&amp;&nbsp;Replace，就好了，极大提高了开发速度。最理想的情况是把一些通用的例程自己再抽象一层，形成一个通用的类库，封装好。那么可复用性就更强了。&nbsp;<BR><BR>所以我觉得其实不是特别需要例程的，自己写的破坏例程就是最好的例子，如果你实在对自己写的代码不放心的话，我强烈推荐你看看JDK基础类库的Java源代码。在JDK安装目录下面会有一个src.zip，解开来就可以完整的看到整个JDK基础类库，也就是rt.jar的Java源代码，你可以参考一下Sun是怎么写Java程序的，规范是什么样子的。我自己在学习Java的类库的时候，当有些地方理解的不是很清楚的时候，或者想更加清晰的理解运作的细节的时候，往往会打开相应的类的源代码，通过看源代码，所有的问题都会一扫而空。&nbsp;<BR><BR>Java&nbsp;Learning&nbsp;Path（五）资源篇&nbsp;<BR><BR>1、&nbsp;http://java.sun.com/&nbsp;(英文)&nbsp;<BR>Sun的Java网站，是一个应该经常去看的地方。不用多说。&nbsp;<BR><BR>2、&nbsp;http://www-900.ibm.com/developerWorks/cn/&nbsp;<BR>IBM的developerWorks网站，英语好的直接去英文主站点看。这里不但是一个极好的面向对象的分析设计网站，也是Web&nbsp;Services，Java，Linux极好的网站。强烈推荐！！！&nbsp;<BR><BR>3、&nbsp;http://www.java-cn.com/&nbsp;(中文)&nbsp;<BR>JAVA中文站，目前国内资料最全、会员最多的JAVA技术网站，人气极高。有《JAVA电子书库》、《JAVA视频库》(国内唯一)、《JAVA技术文摘库》、《JAVA源代码库》、《JAVA工具库》、《招聘求职广场》等主要栏目，还有一些专家栏目。目前会员有5万多，VIP会员近1000人。无论是菜鸟还是老鸟，都能在此网站中找到自己所需要的东东！！　最强烈推荐！！！！！！&nbsp;<BR><BR>4、&nbsp;http://www.javaworld.com/&nbsp;(英文)&nbsp;<BR>关于Java很多新技术的讨论和新闻。想多了解Java的方方面面的应用，这里比较好。&nbsp;<BR><BR>5、&nbsp;http://dev2dev.bea.com.cn/index.jsp&nbsp;<BR>BEA的开发者园地，BEA作为最重要的App&nbsp;Server厂商，有很多独到的技术，在Weblogic上做开发的朋友不容错过。&nbsp;<BR><BR>6、&nbsp;http://www.huihoo.com/&nbsp;<BR>灰狐动力网站，一个专业的中间件网站，虽然不是专业的Java网站，但是在J2EE企业应用技术方面有深厚的造诣。&nbsp;<BR><BR>7、&nbsp;http://www.theserverside.com/home/&nbsp;(英文)&nbsp;<BR>TheServerSide是一个著名的专门面向Java&nbsp;Server端应用的网站。&nbsp;<BR><BR>8、&nbsp;http://www.javaresearch.org/&nbsp;<BR>Java研究组织，有很多优秀的Java方面的文章和教程，特别是在JDO方面的文章比较丰富。&nbsp;<BR><BR>9、&nbsp;http://www.cnjsp.org/&nbsp;<BR>JSP技术网站，有相当多的Java方面的文章和资源。&nbsp;<BR><BR>10、&nbsp;http://www.jdon.com/&nbsp;<BR>Jdon论坛，是一个个人性质的中文J2EE专业技术论坛，在众多的Java的中文论坛中，Jdon一个是技术含量非常高，帖子质量非常好的论坛。&nbsp;<BR><BR>11、&nbsp;http://sourceforge.net/&nbsp;<BR>SourgeForge是一个开放源代码软件的大本营，其中也有非常非常丰富的Java的开放源代码的著名的软件。</P><img src ="http://www.blogjava.net/Pudgy/aggbug/10177.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Pudgy/" target="_blank">Pudgy's World</a> 2005-08-15 22:31 <a href="http://www.blogjava.net/Pudgy/archive/2005/08/15/10177.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>