<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>thomas0988</title>
    <description></description>
    <link>http://thomas0988.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>使用exe4j打包jar生成exe常用设置</title>
        <author>thomas0988</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://thomas0988.javaeye.com">thomas0988</a>&nbsp;
          链接：<a href="http://thomas0988.javaeye.com/blog/199731" style="color:red;">http://thomas0988.javaeye.com/blog/199731</a>&nbsp;
          发表时间: 2008年06月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p dir="ltr">本文首先默认你已经拥有可用的jar文件和exe4j程序。<br />
下面开始详述步骤：<br />
1.welcome－打开exe4j<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<img src="/images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap1.jpg" border="0" alt="" />
<br />
如图，如果你有保存过的项目打包配置文件，那么点&gt;&gt;open打开即可。如果没有点&gt;&gt;next.<br />
<br />
2.Project 
type－选择打包方式<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap2.jpg" border="0" alt="" />
</p>
<p>由于我们讲的是打包jar生成exe，所以选&ldquo;jar in 
exe&rdquo;mode,这种方式可以把一个java应用程序打包成一个exe文件，但是不能将除jar以外的附加文件打包进去。然后&gt;&gt;next<br />
<br />
3. 
Application info－配置生成的应用程序的信息<br />
<img src="http://www.blogjava.net/images/blogjava_net/y6cn/28237/o_Snap3.jpg" border="0" alt="" />
<br />
设置你的应用程序的名称和将要生成的可执行文件的输出文件夹。然后&gt;&gt;next.<br />
<br />
4.Executable 
info －配置可执行文件的参数<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap4.jpg" border="0" alt="" />
<br />
type项根据你的程序的类型确定，本例为GUI程序;接下来是文件名、可执行文件的图标、是否只允许同时刻只能运行一个应用程序、当主线程有误时是否抛出异常、更改工作目录（相对于可执行文件）。然后点&gt;&gt;advanced 
options&gt;&gt;version info<br />
<br />
5.version info-设置版本信息<br />
<img src="http://www.blogjava.net/images/blogjava_net/y6cn/28237/r_Snap6.jpg" border="0" height="475" alt="" width="640" />
<br />
<br />
6.java invocation－配置运行环境<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap7.jpg" border="0" alt="" />
<br />
<br />
先配置class 
path，将此项内原有的配置全部删除，然后点&ldquo;＋&rdquo;找到你生成的jar文件，<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap8.jpg" border="0" alt="" />
<br />
<br />
然后在上边的general中点浏览按钮，exe4j会自动找到你应用程序的入口－main 
class。<br />
在下边的advanced options中选native 
libraries设置，此功能是添加你程序用到的外部jar包文件，这个我一直没用过，因为我做什么事都喜欢集中，所以在程序中用到的所有外部包全整合到jdk/jre里了，这样在给客户安装程序时只要把程序直接给他考过去就可以用了，不用再安装其它东西，他们会很喜欢的哦，毕竟用户不是搞程序设计的嘛。<br />
<br />
7.jre－配置jre<br />
<img src="../../../images/blogjava_net/y6cn/28237/r_Snap12.jpg" border="0" alt="" />
<br />
在这里配置你的jre版本类型,然后再看&gt;&gt;advanced option&gt;&gt;search 
sequence<br />
<br />
<img src="../../../images/blogjava_net/y6cn/28237/r_Snap13.jpg" border="0" alt="" />
<br />
在这里来配置你运行程序所需的jre/jdk的位置,如果你只是打包后本机运行,直接指定到你本机的jre/jdk目录即可,如果你打包后的程序要在别的客户机上运行,而该机又没装jdk,这时我们就要想另一种方法了。从客户的角度讲,拿到手的软件在安装过程中应尽可能少的给客户带来繁琐的安装事项，最好只点一下鼠标就能自动安装。因此，我们要让用户省去安装jdk的麻烦。要解决这个问题，我们可以把安装好的jdk复本放置在最终产品的根目录下，然后在上图中添加这个jdk复本为程序的运行环境<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap19.jpg" border="0" alt="" />
<br />
search 
registty 可以扫描已经安装的jdk/jre，我们选择directory,为程序指定一个jdk目录，只需定位到jdk根目录即可，如上图。 
然后&gt;&gt;next<br />
这里要说明一点，用eclipse开发的程序只要一个jre就行了，jdk不用的，所以我是把jre打包进exe运行环境的，这样的话在java　version下边的那个允许使用jre 
beta版的选项就要选中了。<br />
8.preferred vm-选择虚拟机<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap14.jpg" border="0" alt="" />
<br />
这个根据具体情况选择，本例为client. 然后&gt;&gt;next<br />
<br />
9.splash screen 
-预载窗体<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap15.jpg" border="0" alt="" />
<br />
在这里可以设置你的预载窗体界面，不过好像只认gif类型的图片，status line and&nbsp; version line 
可以在position text lines 
visually预览界面中调整其显示位置。然后&gt;&gt;next，接下来是选择语言界面，根据自己情况选择。然后&gt;&gt;next<br />
<br />
10.compile 
executable-编译生成可执行文件<br />
<img src="http://www.blogjava.net/images/blogjava_net/y6cn/28237/o_Snap17.jpg" border="0" alt="" />
<br />
自动跳转至：<br />
<img src="../../../images/blogjava_net/y6cn/28237/o_Snap18.jpg" border="0" alt="" />
<br />
在这里可以点击运行生成的可执行文件，也可以将本次配置方案保存起来以备后用。<br />
<br />
好，到此整个使用过程告以段落。可能某写操作写得有不当之处，还请各位更正补充。</p>
<p><a href="http://www.blogjava.net/y6cn/archive/2007/12/26/170403.html" target="_blank">http://www.blogjava.net/y6cn/archive/2007/12/26/170403.html</a></p>
          <br/>
          <span style="color:red;">
            <a href="http://thomas0988.javaeye.com/blog/199731#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 03 Jun 2008 14:47:25 +0800</pubDate>
        <link>http://thomas0988.javaeye.com/blog/199731</link>
        <guid>http://thomas0988.javaeye.com/blog/199731</guid>
      </item>
      <item>
        <title>java 生成 ip地址</title>
        <author>thomas0988</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://thomas0988.javaeye.com">thomas0988</a>&nbsp;
          链接：<a href="http://thomas0988.javaeye.com/blog/147314" style="color:red;">http://thomas0988.javaeye.com/blog/147314</a>&nbsp;
          发表时间: 2007年12月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在TCP/IP 互联网时，经常会需要查询自己主机的IP地址和www服务器的IP地址。虽然，我们可以使用IPCONFIG 和PING 进行IP地址查询，但是如果在应用程序或APPLET中使用此命令回破坏我们应用程序界面。 <br /><br />　　为此本人使用Java做了一个简单的程序可以直接查询自己主机的IP地址和www服务器的IP地址。 <br /><br />// 文件名为 NetTool.java （注意：在JAVA 语言中大小写敏感）<br />import java.net.*;<br />public class NetTool{<br />InetAddress myIPaddress=null;<br />InetAddress myServer=null;<br /><br />public static void main( String args[]){<br /><br />　NetTool mytool;<br />　mytool=new NetTool();<br /><br />　System.out.println("Your host IP is: " + mytool.getMyIP());<br />　System.out.println("The Server IP is :" +mytool.getServerIP());<br /><br />}<br /><br />//取得LOCALHOST的IP地址<br />public InetAddress getMyIP() {<br />　try { myIPaddress=InetAddress.getLocalHost();}<br />　catch (UnknownHostException e) {}<br />　　return (myIPaddress);<br />}<br />//取得 www.abc.com 的IP地址<br />public InetAddress getServerIP(){<br />　try {myServer=InetAddress.getByName("www.abc.com");} <br />　catch (UnknownHostException e) {}<br />　return (myServer);<br />}<br /><br />} <br /><br /><br /><br /><br />可以用如下代码:<br /><br />           InetAddress inet = InetAddress.getLocalHost();<br />            System.out.println("本机的ip=" + inet.getHostAddress());<br /><br /><br />在window下面可以工作。在linux下返回127.0.0.1。主要是在linux下返回的是/etc/hosts中配置的localhost的ip地址，而不是网卡的绑定地址。后来改用网卡的绑定地址，可以取到本机的ip地址：）<br /><br />代码如下：<br /><br />//根据网卡取本机配置的IP<br />      Enumeration netInterfaces=NetworkInterface.getNetworkInterfaces();<br />      InetAddress ip = null;<br />   while(netInterfaces.hasMoreElements())<br />   {<br />    NetworkInterface ni=(NetworkInterface)netInterfaces.nextElement();<br />    System.out.println(ni.getName());<br />    ip=(InetAddress) ni.getInetAddresses().nextElement();<br />    if( !ip.isSiteLocalAddress() <br />    && !ip.isLoopbackAddress() <br />    && ip.getHostAddress().indexOf(":")==-1)<br />    {<br />     System.out.println("本机的ip=" + ip.getHostAddress());<br />     break;<br />    }<br />    else<br />    {<br />                   ip=null;<br />       }<br />   }<br /><br /><br /><br /><br /><br />public void getip()<br />{<br />try<br />{<br />InetAddress addr = InetAddress.getLocalHost();<br />ip=addr.getHostAddress().toString;//获得本机IP<br />address=addr.getHostName()toString;//获得本机名称 <br /><br /><br />//System.out.println("addr=:"+String.valueOf(addr));<br />}<br />catch(Exception e)<br />{<br />System.out.println("Bad IP Address!"+e);<br />} <br />} <br /><br />public void showframe()<br />{<br />frame=new JFrame("my ip");<br />label1=new JLabel("this my ip");<br />label1.setText(ip);<br />label2=new JLabel("this my address");<br />label2.setText(address);<br />panel=new JPanel();<br />panel.add(label1);<br />panel.add(label2);<br />frame.getContentPane().add(panel); <br /><br />frame.setSize(400,300);<br />frame.setVisible(true);<br />} <br /><br />public static void main(String agrs[])<br />{<br />iplabel myip=new iplabel();<br />myip.getip();<br />myip.showframe(); <br /><br />}<br />}
          <br/>
          <span style="color:red;">
            <a href="http://thomas0988.javaeye.com/blog/147314#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Dec 2007 16:55:50 +0800</pubDate>
        <link>http://thomas0988.javaeye.com/blog/147314</link>
        <guid>http://thomas0988.javaeye.com/blog/147314</guid>
      </item>
      <item>
        <title>java生成exe</title>
        <author>thomas0988</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://thomas0988.javaeye.com">thomas0988</a>&nbsp;
          链接：<a href="http://thomas0988.javaeye.com/blog/143007" style="color:red;">http://thomas0988.javaeye.com/blog/143007</a>&nbsp;
          发表时间: 2007年11月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp; 这个是borland不公开的使用技巧，能够通过jbuilder来制作exe文件来启动java文件。jbuilder并不支持本地编译机制。但是有一个隐藏的技巧可以让你从可执行文件来启动java程序，可以出现或者不出现console窗口。想做到这些，需要jbuilder的bin目录下的这些文件:&nbsp;
<p>　　jbuilder.exe&nbsp;<br />
　　jbuilderw.exe&nbsp;(可选)&nbsp;<br />
　　jbuilder.config&nbsp;<br />
　　jdk.config&nbsp;<br />
　　javalauncher.dll&nbsp;　　&nbsp; </p>
<p>　　&ldquo;jbuilder.exe&rdquo;是一个通用的可执行外壳文件，用以启动java程序，&rdquo;jbuilderw.exe&ldquo;好像是javaw.exe一样，它把&rdquo;jbuilder.exe&rdquo;包装起来，但是运行时候不显示那个console的窗口。使用这些文件的关键是文件名。&ldquo;jbuilder.exe&rdquo;查找一个文件叫&rdquo;jbuilder.config&rdquo;的配置文件，里面包含了运行java程序的必须信息。同样的&rdquo;jbuilderw.exe&rdquo;查找&rdquo;jbuilder.exe&rdquo;来启动不带console窗口的java程序。如果把jbuilder.exe重命名为&rdquo;foo.exe&rdquo;，那&rdquo;foo.exe&rdquo;将去寻找&rdquo;foo.config&rdquo;配置文件，同样&rdquo;jbuilderw.exe&rdquo;被重命名为&rdquo;foow.exe&rdquo;，它会去寻找&rdquo;foo.exe&rdquo;文件。&nbsp; </p>
<p>　　说到这里，聪明的读者应该猜到怎样利用jbuilder.exe来启动应用程序了。只要把jbuilder.exe,jbuilerw.exe,jbuilder.config改名成相应的文件名，在jbuilder.config里面指定主类和类路径，就能够通过执行jbuilder.exe(或者被改名后的exe文件)来启动java应用程序了。下面是用本机为例。&nbsp; </p>
<p>　　&nbsp;borland&nbsp;jbuilder&nbsp;5被安装在e:\jbuilder5\目录下，在e:\jbuilder5\bin\下建立一个temp目录，然后把jbuilder.exe,jbuilder.config,javalauncher.dll,jdk.config四个文件拷贝到:\jbuilder5\bin\temp\目录下，然后在这个目录下建立一个hello目录，在这个目录下生成一个hello.java文件，即e:\jbuilder5\bin\temp\hello\hello.java文件，file://hello.java/package&nbsp;hello;&nbsp; </p>
<p>　　public&nbsp;class&nbsp;hello{&nbsp;<br />
　　public&nbsp;static&nbsp;void&nbsp;main(string&nbsp;s[]){&nbsp;<br />
　　system.out.println(&quot;hello,&nbsp;exe&nbsp;file!&quot;);&nbsp;<br />
　　}&nbsp;<br />
　　}&nbsp;　&nbsp; </p>
<p>　　然后打开jbuilder.config文件，作相应的修改：&nbsp;<br />
　　在jbuilder.config里面找到下面两行&nbsp; </p>
<p>　　#&nbsp;start&nbsp;jbuilder&nbsp;using&nbsp;the&nbsp;its&nbsp;main&nbsp;class&nbsp;<br />
　　mainclass&nbsp;com.borland.jbuilder.jbuilder&nbsp;　&nbsp; </p>
<p>　　修改为&nbsp; </p>
<p>　　#&nbsp;start&nbsp;jbuilder&nbsp;using&nbsp;the&nbsp;its&nbsp;main&nbsp;class&nbsp;<br />
　　mainclass&nbsp;hello.hello&nbsp;<br />
　　addpath&nbsp;e:/jbuilder5/bin/temp/&nbsp;　　&nbsp; </p>
<p>　addpath命令是把目录加入类路径中，这个命令和其它config里面可以识别的命令可以在jbuilder/bin目录下的config_readme.txt里面找到详细说明。&nbsp; </p>
<p>　　然后将jdk.config里面的javapath修改成相对的路径，例如原来是&nbsp; </p>
<p>　　javapath&nbsp;../jdk1.3/bin/java&nbsp; </p>
<p>　　修改成&nbsp; </p>
<p>　　javapath&nbsp;../../jdk1.3/bin/java&nbsp;　　&nbsp; </p>
<p>　　最后&nbsp; </p>
<p>　　将jbuilder.exe,jbuilder.config修改成所需要的文件名，例如foo.exe和foo.config文件&nbsp;。　　&nbsp; </p>
<p>　　现在执行foo.exe文件&nbsp;　　　&nbsp; </p>
<p>　　至此，通过修改jbuilder来使用exe文件启动自己的java应用程序已经完成了。&nbsp;　&nbsp; </p>
<p>　　但是好玩的地方并不在这个地方，下面的小技巧可能更有趣，将jar文件打包进入exe文件！&nbsp;　&nbsp; </p>
<p>　　假设利用上面的文件，生成hello.jar包，执行过程.&nbsp; </p>
<p>　　jar&nbsp;cvf&nbsp;hello.jar&nbsp;hello\*.class&nbsp;　　&nbsp; </p>
<p>　　将类文件打包成exe文件&nbsp;　&nbsp; </p>
<p>　　然后将jar包附加到jbuilder.exe后面去.&nbsp; </p>
<p>　　copy&nbsp;/b&nbsp;..\jbuilder.exe+hello.jar&nbsp;foo.exe&nbsp;　　&nbsp; </p>
<p>　&nbsp;将jar文件转化成exe文件&nbsp;　&nbsp; </p>
<p>　　在foo.config(jbuilder.config)文件里面把前面加入的类路径去掉，并加入下面的路径：&nbsp; </p>
<p>　　addpath&nbsp;e:/jbuilder5/bin/temp/foo.exe&nbsp; </p>
<p>　　然后执行.&nbsp;<br />
　　&nbsp;<br />
　　看到了么？一个含jar包的exe文件被执行了！&nbsp; </p>
<p>　　这个过程的大致原理是：exe文件的重要信息都在文件头部，所以把乱七八糟的东西放exe文件尾部是不要紧的；而jar/zip文件的重要信息是在文件尾部的，这样它们两不相干，能够容&nbsp;易的被执行。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>1.先生成.jar包，再生成.exe文件<br />
编写manifest.mf文件<br />
manifest.mf中的内容：<br />
Manifest-Version: 1.0 <br />
Main-Class:test.Application1<br />
Created-By:snowpine<br />
只有Main-Class是有用的，&ldquo;Created-By: snowpine&rdquo;是指这个.jar文件的作者<br />
<br />
比如你有个Application1.class文件，在d:\test下，那么把manifest.mf放在d:\就可以了。 <br />
然后在d:\运行，jar cvfm test.jar manifest.mf test，就可以在d:\下生成test.jar<br />
<br />
然后利用exe4j可以生成.exe的可执行文件 <span style="COLOR: red">注: .exe必须在装有jdk机器才能运行</span><br />
<br />
2.jbuider编辑器生成.exe文件<br />
<br />
执行wizards&mdash;native executable builder&mdash;全部next，完成后，在编译一次，就自动生成了.exe文件<br />
<br />
3.在jbuilder中用wizards&mdash;archive builder生成.jar包(自动生成manifest.mf文件),然后在用exe4j生成.exe文件.<br />
<br />
<span style="COLOR: red">注:exe4j中有个main class，要填写manifest.mf中main-class后的名字</span> </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>几种java转exe的工具，进行一下比较，谈谈自己的看法：<br />
<br />
1. 从www.towerj.com获得一个TowerJ编译器，该编译器可以将你的CLASS文件编译成EXE文件。 <br />
注：现在已经找不到，不提供了，被人家收购了。<br />
<br />
<a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=4338&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//www.firefoxtrial.cn&amp;v=0&amp;k=2.&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=370589" title="免费下载使用不中毒的浏览器软件 @Vogate.com" class="vLink1" id="vad_11" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 11,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">2.</a> 利用微软的SDK-Java 4.0所提供的jexegen.exe创建EXE文件，这个<a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=4249&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//www.tompda.com&amp;v=0&amp;k=%u8F6F%u4EF6&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=664587" title="TOMPDA智能手机乐园 @Vogate.com" class="vLink1" id="vad_3" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 3,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">软件</a>可以从微软的<a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=3831&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//noyes.cn/Software_4150.html&amp;v=0&amp;k=%u7F51%u7AD9&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=540775" title="跑跑卡丁车 @Vogate.com" class="vLink1" id="vad_4" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 4,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">网站</a><a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=4595&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//www.kanbw.cn/&amp;v=0&amp;k=%u514D%u8D39&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=167773" title="免费网络电影- 看不完电影网 @Vogate.com" class="vLink1" id="vad_2" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 2,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">免费</a><a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=987&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//www.naoteng.com/china/download-firefox.htm&amp;v=0&amp;k=%u4E0B%u8F7D&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=472754" title="立即下载Firefox2.0浏览器 @Vogate.com" class="vLink1" id="vad_0" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 0,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">下载</a>，<a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=4576&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//www.dy001.com/details.asp%3Fid%3D16%26id2%3D373%7C%u653F%u5E9C%u514D%u8D39%u57F9%u8BAD%uFF1A%u8425%u517B%u6307%u5BFC%u5E08%u4E2D%u7EA7%3Bhttp%3A//www.dycollege.com%7C%u5916%u6765%u52A1%u5DE5%u4EBA%u5458%u514D%u8D39%u57F9%u8BAD%u7CFB%u5217%3Bhttp%3A//www.dy001.com/category.asp%3Fid%3D17%7C%u4F1A%u8BA1%u4E0A%u5C97%u8BC1%u3001%u7535%u7B97%u5316%u3001%u4F1A%u8BA1%u804C%u79F0%3Bhttp%3A//www.dycollege.com%7C%u5916%u8D38%u7C7B%u8003%u8BC1%uFF1A%u5355%u8BC1%u3001%u62A5%u5173%u5458%u3001%u8D27%u4EE3%3Bhttp%3A//www.dy001.com/details.asp%3Fid%3D1%26id2%3D372%7C%u4E1C%u4E9A%u5B66%u9662%u62DB%u8058%u4EBA%u624D&amp;v=0&amp;k=%u5730%u5740&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=555298" title="上海市东亚进修学院培训系列 @Vogate.com" class="vLink1" id="vad_8" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 8,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">地址</a>如下： <br />
<a href="http://www.microsoft.com/java/download/dl_sdk40.htm" target="_blank">http://www.microsoft.com/java/download/dl_sdk40.htm</a>&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
jexegen的语法如下： <br />
<br />
jexegen /OUT:exe_file_name <br />
/MAIN:main_class_name main_class_file_name.class <br />
[and other classes] <br />
<br />
注：没有试过<br />
<br />
3. Visual Cafe提供了一个能够创建EXE文件的本地编译器。你需要安装该光盘上提供的EXE组件。 <br />
注：没有试过<br />
<br />
4. 使用InstallAnywhere创建安装盘。 <br />
注：很不错的工具。<br />
但就是要＞8M（带jre），还有一种是＞1M的（不带jre）。<br />
但是它可以编译成各种平台上可以使用的exe程序。<br />
<br />
5. 使用IBM AlphaWorks提供的一个高性能Java编译器，该编译器可以从下面的地址获得： <br />
<a href="http://www.alphaworks.ibm.com/tech/hpc" target="_blank">http://www.alphaworks.ibm.com/tech/hpc</a>&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
注：没有试过<br />
<br />
6. JET是一个优秀的Java语言本地编译器。该编译器可以从这个网站获得一个<a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=3751&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//noyes.cn&amp;v=0&amp;k=%u6D4B%u8BD5&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=118412" title="NO!YES!游戏王国 @Vogate.com" class="vLink1" id="vad_7" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 7,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">测试</a>版本： <br />
<a href="http://www.excelsior-usa.com/jet.html" target="_blank">http://www.excelsior-usa.com/jet.html</a>&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
注：不喜欢。<br />
编译好的程序还是jre的，听说正版的可以不能jre。安装好还要编译，我用了30分钟。<br />
<br />
7. Instantiations公司的JOVE <br />
<a href="http://www.instantiations.com/jove/...ejovesystem.htm" target="_blank">http://www.instantiations.com/jove/...ejovesystem.htm</a>&nbsp;&nbsp;&nbsp;&nbsp;<br />
JOVE公司合并了以前的SuperCede，一个优秀的本地编译器，现在SuperCede已经不复存在了。 <br />
<br />
注：太烦了，老是出来一个对话框<br />
用过，会出来一个对话框，表示这是jove公司的<a href="http://action.vogate.com/click/click.php?r=http%3A//www.google.cn/search%3Fhl%3Dzh-CN%26q%3Djava%25E7%2594%259F%25E6%2588%2590exe%25E6%2596%2587%25E4%25BB%25B6%26btnG%3DGoogle+%25E6%2590%259C%25E7%25B4%25A2%26meta%3D&amp;ads_id=2110&amp;site_id=6235007045041189&amp;click=1&amp;url=http%3A//www.moqie.com&amp;v=0&amp;k=%u4EA7%u54C1&amp;s=http%3A//www.programfan.com/article/showarticle.asp%3Fid%3D2413&amp;rn=443733" title="中国模切网 @Vogate.com" class="vLink1" id="vad_10" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 10,'');}" onclick="" target="_blank" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" style="FONT-SIZE: 1em">产品</a>。<br />
<br />
8. JToEXE <br />
Bravo Zulu Consulting, Inc开发的一款本地编译器，本来可以从该公司的网页上免费下载的，不过目前在该公司的主页上找不到了。 <br />
公司主页：http://www.bravozulu.com/&nbsp;&nbsp;&nbsp;&nbsp;<br />
下面这个FTP上曾经有过这个软件，不知道现在是不是还在： <br />
ftp://race.dlut.edu.cn/pub/java/tools/jet <br />
<br />
注：很烦了，老是出来一个对话框，但是没有想到我找到了crack,在google上找到。<br />
现在去掉了那个对话框后，我很喜欢这个工具，虽然它需要jre，但是文件只有100多K，很好哦。<br />
<br />
9.Exe4j<br />
很不错<br />
<br />
10.jbuilder <br />
这个工具不用多讲了，在jbuilder6.0以前的（包括6.0），是不能生成exe文件的，所以可以用如下的方法实现。这可以人家高手想出来的，我只是帮着宣传一下。<br />
还有jbuilder7.0开始都可以生成exe文件。<br />
<br />
这个是Borland不公开的使用技巧，能够通过JBuilder来制作exe文件来启动Java文件。 <br />
JBuilder并不支持本地编译机制。但是有一个隐藏的技巧可以让你从可执行文件来启动Java程序，可以出现或者不出现console窗口。想做到这些，需要JBuilder的bin目录下的这些文件: <br />
JBuilder.exe <br />
JBuilderW.exe (可选) <br />
JBuilder.config <br />
jdk.config <br />
JavaLauncher.dll <br />
&ldquo;JBuilder.exe&rdquo;是一个通用的可执行外壳文件，用以启动Java程序，&rdquo;JBuilderW.exe&ldquo;好像是javaw.exe一样，它把&rdquo;JBuilder.exe&rdquo;包装起来，但是运行时候不显示那个console的窗口。使用这些文件的关键是文件名。&ldquo;JBuilder.exe&rdquo;查找一个文件叫&rdquo;JBuilder.config&rdquo;的配置文件，里面包含了运行Java程序的必须信息。同样的&rdquo;JBuilderW.exe&rdquo;查找&rdquo;JBuilder.exe&rdquo;来启动不带Console窗口的Java程序。如果把JBuilder.exe重命名为&rdquo;foo <br />
.exe&rdquo;，那&rdquo;foo.exe&rdquo;将去寻找&rdquo;foo.config&rdquo;配置文件，同样&rdquo;JBuilderW.exe&rdquo;被重命名为&rdquo;fooW.exe&rdquo;，它会去寻找&rdquo;foo.exe&rdquo;文件。 <br />
说到这里，聪明的读者应该猜到怎样利用JBuilder.exe来启动应用程序了。只要把JBuilder.exe,JBuilerW.exe,JBuilder.config改名成相应的文件名，在JBuilder.config里面指定主类和类路径，就能够通过执行JBuilder.exe(或者被改名后的exe文件)来启动Java应用程序了。下面是用本机为例。 <br />
Borland JBuilder 5被安装在E:\jbuilder5\目录下，在E:\jbuilder5\bin\下建立一个temp目录，然后把JBuilder.exe,JBuilder.config,JavaLauncher.dll,jdk.config四个文件拷贝到E:\jbuilder5\bin\temp\目录下，然后在这个目录下建立一个hello目录，在这个目录下生成一个hello.java文件，即E:\jbuilder5\bin\temp\hello\hello.java文件， <br />
//hello.java/ <br />
package hello; <br />
public class hello{ <br />
public static void main(String s[]){ <br />
&nbsp;&nbsp;&nbsp;System.out.println(&quot;Hello, Exe file!&quot;); <br />
} <br />
} <br />
编译成class文件，然后打开Jbuilder.config文件，作相应的修改： <br />
在JBuilder.config里面找到下面两行 <br />
# Start JBuilder using the its main class <br />
mainclass com.borland.jbuilder.JBuilder <br />
修改为 <br />
# Start JBuilder using the its main class <br />
mainclass hello.hello <br />
addpath E:/jbuilder5/bin/temp/ <br />
addpath命令是把目录加入类路径中，这个命令和其它config里面可以识别的命令可以在JBuilder/bin目录下的config_readme.txt里面找到详细说明。 <br />
然后将jdk.config里面的javapath修改成相对的路径，例如原来是 <br />
javapath ../jdk1.3/bin/java <br />
修改成 <br />
javapath ../../jdk1.3/bin/java <br />
最后 <br />
将JBuilder.exe,JBuilder.config修改成所需要的文件名，例如foo.exe和foo.config文件。 <br />
现在执行foo.exe文件 <br />
至此，通过修改JBuilder来使用exe文件启动自己的Java应用程序已经完成了。 <br />
但是好玩的地方并不在这个地方，下面的小技巧可能更有趣，将Jar文件打包进入exe文件！ <br />
假设利用上面的文件，生成hello.jar包， <br />
jar cvf hello.jar hello\*.class <br />
然后将jar包附加到JBuilder.exe后面去， <br />
copy /b ..\JBuilder.exe+hello.jar foo.exe <br />
在foo.config(JBuilder.config)文件里面把前面加入的类路径去掉，并加入下面的路径： <br />
addpath E:/jbuilder5/bin/temp/foo.exe <br />
然后执行，foo.exe <br />
看到了么？一个含jar包的exe文件被执行了！ <br />
这个过程的大致原理是：exe文件的重要信息都在文件头部，所以把乱七八糟的东西放exe文件尾部是不要紧的；而jar/zip文件的重要信息是在文件尾部的，这样它们两不相干，能够容易的被执行。 <br />
请注意：读者如果使用这个功能，得自己承担可能带来的风险，因为Borland对这个功能不提供官方的支持！&nbsp; </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="tpc_content">一般来说使用JSmooth可以把纯Java程序封装成windows的可执行文件。<br />
<br />
如果你做的是SWT应用程序，那得需要写个Lancher来加载一些本地文件然后启动程序，下面是我在具体<nobr><strong class="kgb" onmouseover="isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer=&quot;_u9879_u76EE&quot;;KeyGate_ads.ShowGgAds(this,&quot;_u9879_u76EE&quot;,event)" onclick="javascript:window.open(&quot;http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BqyKQU_FbR8XOA5PG6APlu8y4B8GtzjSV1tLYA8CNtwGA8QQQERgRIIL2kgsoFDgAUMKdsxVgnbnZgcgFoAGH58n8A6oBCjIwMDAwMTY4NTWyARR3d3cuZWNsaXBzZXdvcmxkLm9yZ8gBAdoBLmh0dHA6Ly93d3cuZWNsaXBzZXdvcmxkLm9yZy9iYnMvcmVhZC5waHA_dGlkPTipAlkhoOLDIYI-yAL9kp4BqAMB6AMf6APXAvUDAAEAAA&amp;num=17&amp;adurl=http://28.com/%3Fcomeid%3D20286&amp;client=ca-pub-7244513001137299&quot;);GgKwClickStat(&quot;项目&quot;,&quot;28.com&quot;,&quot;afc&quot;,&quot;2000016855&quot;);" onmouseout="isShowGg = false;InTextAds_GgLayer=&quot;_u9879_u76EE&quot;" style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; CURSOR: hand; COLOR: #0000ff; PADDING-TOP: 0px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline">项目</strong></nobr>中写的样例<nobr><strong class="kgb" onmouseover="isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer=&quot;_u4EE3_u7801&quot;;KeyGate_ads.ShowGgAds(this,&quot;_u4EE3_u7801&quot;,event)" onclick="javascript:window.open(&quot;http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BjJ0yU_FbR8XOA5PG6APlu8y4B5OC3wiL3qH4AcCNtwGwzAsQAhgCIIL2kgsoFDgAUNGTsZj9_____wFgnbnZgcgFqgEKMjAwMDAxNjg1NbIBFHd3dy5lY2xpcHNld29ybGQub3JnyAEB2gEuaHR0cDovL3d3dy5lY2xpcHNld29ybGQub3JnL2Jicy9yZWFkLnBocD90aWQ9OKgDAegDH-gD1wL1AwABAAA&amp;num=2&amp;adurl=http://reportmill.com/index/index_goog.html&amp;client=ca-pub-7244513001137299&quot;);GgKwClickStat(&quot;代码&quot;,&quot;www.reportmill.com&quot;,&quot;afc&quot;,&quot;2000016855&quot;);" onmouseout="isShowGg = false;InTextAds_GgLayer=&quot;_u4EE3_u7801&quot;" style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; CURSOR: hand; COLOR: #0000ff; PADDING-TOP: 0px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline">代码</strong></nobr>，你可以参考一下：<br />
<h6 class="quote"><a href="javascript:" onclick="CopyCode(document.getElementById('code1'));">Copy code</a></h6>
<blockquote id="code1">
<p>public class Lanucher {<br />
<br />
public static void main(String[] args) {<br />
&nbsp; Runtime runtime = Runtime.getRuntime();<br />
&nbsp; String homePath = null;<br />
&nbsp; if (args.length &gt; 0) {<br />
&nbsp; &nbsp; homePath = args[0];<br />
&nbsp; }<br />
<br />
&nbsp; if (homePath == null) {<br />
&nbsp; &nbsp; homePath = System.getProperty(&quot;user.dir&quot;);<br />
&nbsp; }<br />
<br />
&nbsp; if (homePath == null) {<br />
&nbsp; &nbsp; //如果主目录信息不存在, 则抛出错误, 然后关闭程序.<br />
&nbsp; &nbsp; System.err.println(&quot;错误:系统没有指定主目录路径, 请<nobr><strong class="kgb" onmouseover="isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer=&quot;_u8054_u7CFB&quot;;KeyGate_ads.ShowGgAds(this,&quot;_u8054_u7CFB&quot;,event)" onclick="javascript:window.open(&quot;http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=Boi8DU_FbR8XOA5PG6APlu8y4B9CPvjGQma6_BcCNtwGA0w4QAxgDIIL2kgsoFDgAUKqWn7n9_____wFgnbnZgcgFqgEKMjAwMDAxNjg1NbIBFHd3dy5lY2xpcHNld29ybGQub3JnyAEB2gEuaHR0cDovL3d3dy5lY2xpcHNld29ybGQub3JnL2Jicy9yZWFkLnBocD90aWQ9OKkCWSGg4sMhgj7IArDXxQOoAwHoAx_oA9cC9QMAAQAA&amp;num=3&amp;adurl=http://motorolaafa7.allyes.com/main/adfclick%3Fdb%3Dmotorolaafa7%26bid%3D21653,10715,74%26cid%3D11796,384,1%26sid%3D21499%26show%3Dignore%26url%3Dhttp://q.motorola.com.cn/&amp;client=ca-pub-7244513001137299&quot;);GgKwClickStat(&quot;联系&quot;,&quot;Q.motorola.com.cn&quot;,&quot;afc&quot;,&quot;2000016855&quot;);" onmouseout="isShowGg = false;InTextAds_GgLayer=&quot;_u8054_u7CFB&quot;" style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; CURSOR: hand; COLOR: #0000ff; PADDING-TOP: 0px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline">联系</strong></nobr>系统管理员.&quot;);<br />
&nbsp; &nbsp; execute(runtime, &quot;pause&quot;);<br />
&nbsp; } else {<br />
<br />
&nbsp; &nbsp; System.out.println(&quot;1.使用主目录:&quot; + homePath);<br />
<br />
&nbsp; &nbsp; //启动应用程序.<br />
&nbsp; &nbsp; String libPath = homePath + &quot;/lib&quot;;<br />
&nbsp; &nbsp; File libFile = new File(libPath);<br />
&nbsp; &nbsp; File[] jarFiles = libFile.listFiles(new FilenameFilter() {<br />
&nbsp; &nbsp; public boolean accept(File dir, String name) {<br />
&nbsp; &nbsp; &nbsp; return name.endsWith(&quot;.jar&quot;) || name.endsWith(&quot;.JAR&quot;);<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; });<br />
&nbsp; &nbsp; String classpath = libPath;<br />
&nbsp; &nbsp; if (jarFiles != null) {<br />
&nbsp; &nbsp; for (int i = 0; i &lt; jarFiles.length; i++) {<br />
&nbsp; &nbsp; &nbsp; String jarFilePath = jarFiles[i].getPath();<br />
&nbsp; &nbsp; &nbsp; System.out.println(&quot;2.添加库文件:&quot; + jarFilePath);<br />
&nbsp; &nbsp; &nbsp; classpath += &quot;;&quot; + jarFilePath;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; String execute = (&quot;\&quot;&quot; + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; homePath + &quot;/jre/bin/java\&quot; -classpath \&quot;&quot; + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; classpath + &quot;\&quot; -Djava.library.path=\&quot;&quot; + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libPath + &quot;\&quot; com.yipsilon.lifestyle.Application &quot; + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; homePath).replace('\\', '/');<br />
<br />
&nbsp; &nbsp; System.out.println(&quot;3.执行程序:&quot; + execute);<br />
<br />
&nbsp; &nbsp; execute(runtime, execute);<br />
&nbsp; }<br />
}<br />
<br />
private static void execute(Runtime runtime, String command) {<br />
&nbsp; try {<br />
&nbsp; &nbsp; runtime.exec(command);<br />
&nbsp; } catch (IOException ioe) {<br />
&nbsp; &nbsp; //如果主目录信息不存在, 则抛出错误, 然后关闭程序.<br />
&nbsp; &nbsp; System.err.println(&quot;错误:执行主程序时出现错误.\n\n&quot; + ioe.getMessage());<br />
&nbsp; &nbsp; try {<br />
&nbsp; &nbsp; runtime.exec(&quot;pause&quot;);<br />
&nbsp; &nbsp; } catch (IOException ignore) {<br />
&nbsp; &nbsp; }<br />
&nbsp; }<br />
}<br />
}<br />
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div style="MARGIN-TOP: 1px; MARGIN-LEFT: 15px">
<h2><a href="http://laies.javaeye.com/blog/137373" title="永久链接: java生成exe打包工具exe4j">java生成exe打包工具exe4j</a> </h2>
</div>
<div style="MARGIN-TOP: 5px; MARGIN-LEFT: 15px"><strong>关键字:</strong> &nbsp; java生成exe&nbsp;&nbsp;&nbsp;&nbsp; </div>
<div style="MARGIN-TOP: 10px; MARGIN-LEFT: 15px; OVERFLOW: auto">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p align="left"><span><span style="FONT-SIZE: 9pt; COLOR: #333333"><font size="3">exe4j.exe下载地址: </font><a href="http://download.ej-technologies.com/exe4j/exe4j_windows_4_0_1.exe" target="_blank"><font size="3">http://download.ej-technologies.com/exe4j/exe4j_windows_4_0_1.exe</font></a><br />
            </span></span></p>
            <p align="center"><span><font size="3" color="#0000ff"></font></span></p>
            <p align="center"><span><font size="3">第一次安装时会出现下面的对话框：<br />
            </font></span></p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s6.album.sina.com.cn/pic/4412ae2502000f7h" target="_blank"><font size="3"></font></a></center>
            <p forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/25d506ede0788ad2b31cb110.jpg" border="0" alt="" /></p>
            <p><br />
            它要求系统有1.5版本以上的JDK，点Download在线下载，如果你的机器上有JDK，点Locate找到你机器上已安装的JDK目录下/bin/java.exe就可以进行安装了。<br />
            下面就安装过程详细说明一下：<br />
            第1步，默认即可。<br />
            第2步，如果已经有制作好的jar文件，则下面一个&quot;JAR in EXE&quot;。<br />
            对于打包jar文件，在eclipse中右击项目选导出即可，不会制作jar文件可以给我留言<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s11.album.sina.com.cn/pic/4412ae2502000f8a" target="_blank"></a></center>
            <p forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/cecc87ef44054a30acafd510.jpg" border="0" alt="" /></p>
            <p><br />
            第3步，上面是项目名称，可随便填写，下面一个写出你想要将打包后的exe文件输出的目录：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s12.album.sina.com.cn/pic/4412ae2502000f8b" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/aa9afefbb61a6c244f4aea11.jpg" border="0" alt="" /></div>
            <p><br />
            第4步，由于我的演示程序是图形的，所以选第一个，如果你的程序是控制台的，则选择第二个，Executable name写你将要生成的exe文件的名字，Icon File可以选择生成文件的图标<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s1.album.sina.com.cn/pic/4412ae2502000f8c" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/63e39d58abb26d87800a1811.jpg" border="0" alt="" /></div>
            <p><br />
            第5步，首先，单击绿色的&quot;+&quot;号，在弹出的窗口中点Archive，然后找到起初已经做好的jar文件，&quot;OK&quot;后返回，在下面的Class Path里就出现jar文件路径后，再在上面Main Class栏内点击找到main所在的类，这一步即算完成：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s2.album.sina.com.cn/pic/4412ae2502000f8d" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/25d506ede07e8ad2b31cb112.jpg" border="0" alt="" /></div>
            <p><br />
            第6步，你系统的JRE版本，上面填个1.3，下面填1.6：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s3.album.sina.com.cn/pic/4412ae2502000f8e" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/348e3a097838ada92eddd412.jpg" border="0" alt="" /></div>
            <p><br />
            当然，这样配置的程序只能在安装有JRE的机器上执行，发布时总要考虑的问题就是用户是否有能力在自己机器上安装JRE，总不能发布一个程序还要用户自己安装个JRE吧，下面我就介绍如何将JDK环境变量动态打包到exe中，在这里单击advanced options，选择search sequence。如图：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s4.album.sina.com.cn/pic/4412ae2502000f7r" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/29e9983f099aa5c47d1e7112.jpg" border="0" alt="" /></div>
            <p><br />
            首先把JRE复制到exe文件输出的目录里，我用的是c:\xaocker\，在弹出的窗口中，删除列表中所有项，然后单击绿+，选择directory并选择JRE的根目录(注意是拷贝后的目录)即可,如图：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s4.album.sina.com.cn/pic/4412ae2502000f8f" target="_blank"><img title="点击在新窗口打开图片" src="http://s4.album.sina.com.cn/pic/4412ae2502000f8f" border="0" alt="" /></a>
            <div forimg="1" align="center"><img class="blogimg" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/cbfa4f3b4fa5c8ec15cecb1c.jpg" border="0" alt="" /></div>
            </center>
            <p><br />
            单击ok后，再从图中单击advanced options，并选择preferred VM，在弹出的窗口中选择client hostspot VM，单击next按钮继续：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s6.album.sina.com.cn/pic/4412ae2502000f7t" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/2e68ffdef992d05eccbf1a1c.jpg" border="0" alt="" /></div>
            <p><br />
            第7、8步是一些基本配置，默认即可，第9步编译，第10步你就可以点这个看到效果了：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s12.album.sina.com.cn/pic/4412ae2502000f7n" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/a5cee80ffbebfaebab64571c.jpg" border="0" alt="" /></div>
            <p><br />
            exe4j未注册的版本会出现下面的对话框：<br />
            </p>
            <center><a href="http://blog.sina.com.cn/main/html/showpic.html#url=http://s1.album.sina.com.cn/pic/4412ae2502000f7o" target="_blank"></a></center>
            <div forimg="1" align="center"><img class="blogimg" title="点击在新窗口打开图片" small="0" src="http://hiphotos.baidu.com/%D2%B2%CE%AA/pic/item/a68f716da6ebb3fd4316941d.jpg" border="0" alt="" /></div>
            <p><br />
            点击确定之后就可以看到你程序的运行结果了！<br />
            <br />
            java.exe依照一套逻辑来寻找可以用的JRE，首先查找自己所在的目录下有没有JRE，其次查找自己的父目录下有没有JRE；最后才是查询Windows的注册表。<br />
            <br />
            现在我们的程序可以在任意的计算机上执行了，可是缺点是致命的，比方说我的程序才160K，可是不论走到哪里都要背着70多M的JRE，未免有点小题大做吧，其实作为我们的私有的JRE，好多内容都是可以抛弃的。Jre目录下的license都可以不要，bin下的执行文件只需要保留java.exe或者javaw.exe，lib下只要保留rt，jsse，jce，charsets几个库就可以了。除了i386和zi两个子目录外，其余的子目录都可以不要。Zi下只需要保留自己地区的子目录和其下的一些文件就可以。Lib下除了库之外的属性文件等等都要保留。这样清理一番，JRE仍然有接近50MB。还可以继续清理几个库文件里面不需要的内容，这需要仔细的整理，会很费功夫。最好能写出一个自动工具帮助我们整理它们。从Sun公司上下到的JMF里面附带的用Java写的媒体播放器就自带了JRE，只有几个MB。<br />
            清理过后需要运行几遍我们的应用程序，以确保我们的JRE不缺少东西。<br />
            <br />
            OK，仔细清理之后，文件变小了不少，可以发布了&hellip;&hellip;</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</blockquote></div>
          <br/>
          <span style="color:red;">
            <a href="http://thomas0988.javaeye.com/blog/143007#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 Nov 2007 11:51:00 +0800</pubDate>
        <link>http://thomas0988.javaeye.com/blog/143007</link>
        <guid>http://thomas0988.javaeye.com/blog/143007</guid>
      </item>
      <item>
        <title>javabean知识了解</title>
        <author>thomas0988</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://thomas0988.javaeye.com">thomas0988</a>&nbsp;
          链接：<a href="http://thomas0988.javaeye.com/blog/140060" style="color:red;">http://thomas0988.javaeye.com/blog/140060</a>&nbsp;
          发表时间: 2007年11月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="box2"><span class="Tit">javaBean</span></div>
<table class="htb wr" cellspacing="0" border="0" width="100%" cellpadding="0">
    <tbody>
        <tr>
            <td>
            <div class="box2 p14"><strong>JavaBean(Java豆)</strong><br />
            <br />
            JavaBean 概述<br />
            JavaBean 是一种<a href="http://baike.baidu.com/view/29.htm" target="_blank">JAVA</a><a href="http://baike.baidu.com/view/9793.htm" target="_blank">语言</a>写成的可重用组件。为写成JavaBean，类必须是具体的和公共的，并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露称为属性。众所周知，属性名称符合这种模式，其他Java 类可以通过自省机制发现和操作这些JavaBean 属性。<br />
            <br />
            用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用java代码创造的对象进行打包，并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能，而不用关心任何改变。<br />
            <br />
            JavaBean 的发展<br />
            <br />
            最初，JavaBean的目的是为了将可以重复使用的软件代码打包标准。特别是用与帮助厂家开发在综合开发环境（IDE）下使用的java软件部件。这些包括如Grid控件，用户可以将该部件拖放到开发环境中。从此，JavaBean就可以扩展为一个java web 应用的标准部件，并且JavaBean部件框架已经扩展为企业版的 Bean（EJB）。<br />
            <br />
            JavaBean需求<br />
            <br />
            JavaBean是java<a href="http://baike.baidu.com/view/2390.htm" target="_blank">类</a>，属于某些特定的译码知道方针，并且扩展了适应性和范围，允许用户访问内部的属性和方法。通过这些，JavaBean类可以用于下列方法：<br />
            <br />
            1． 在<a href="http://baike.baidu.com/view/5775.htm" target="_blank">IDE</a>中，JavaBean的功能允许应用开发者浏览其中的方法，即使JavaBean是被编译的，并且无法利用原始的源文件。<br />
            <br />
            2． 在 Remote Method Invocation(RMI) 的分布式风格中，这项功能听起来并不让人兴奋，但是在未来的包含企业版的JavaBean后，将改变这种情况。<br />
            <br />
            3． 为了JavaBean的属性值和状态可以保存到磁盘上。<br />
            <br />
            这里说的有些简单，如果想了解更多的东西，可以查阅一些资料。<br />
            <br />
            JavaBean设计注意事项<br />
            <br />
            实际应用中，在表现对象或者处理前扩展JavaBean的设计非常有用。通常认为如果提供信息，web开发者将在功能上满足拥护对JavaBean的需求。例如： HTML中显示敏感的数据时，用户可以屏蔽的条目，如<a href="http://baike.baidu.com/view/7411.htm" target="_blank">密码</a>、<a href="http://baike.baidu.com/view/3248.htm" target="_blank">电话</a>号码等。<br />
            <br />
            良好规划设计的JavaBean是值得信赖的。<br />
            <br />
            Java 中的 null 不同于 SQL 中的 null<br />
            <br />
            看这样一道测试程序：<br />
            <br />
            public class NullTest<br />
            <br />
            {<br />
            <br />
            public static void main(String[] args)<br />
            <br />
            {<br />
            <br />
            int I = 0;<br />
            <br />
            // int&nbsp;&nbsp;I = null； // not a valid initialization <br />
            <br />
            String str = null;<br />
            <br />
            String strZeroOutValue = &ldquo;&rdquo;;<br />
            <br />
            StringBuffer sb = new StringBuffer(&ldquo;Null test: String initialized as null = &ldquo;);<br />
            <br />
            sb.append(str);<br />
            <br />
            sb.append(&ldquo;\n String representing a Zero Out Value:&rdquo;);<br />
            <br />
            sb.append(strZeroOutValue);<br />
            <br />
            System.out.println(sb.toString());<br />
            <br />
            }<br />
            <br />
            }<br />
            <br />
            这个程序将产生下面的结果：<br />
            <br />
            Null test: String initialized as null = null<br />
            <br />
            String representing a Zero Out Value:<br />
            <br />
            在JavaBean中， 我们将 I 变量声明为一个 int， 我们必须处理与该变量相关的值，因为I 默认的没有值，int 类型无法初始化为 null， 如果int 值没有进行明确的初始化，编译器将提示错误。 <br />
            <br />
            执行 NullTest 程序，将验证在文本中空字符串是空值的替代，用于显示 SQL 的插入和更新。如果我们需要删除一些信息，通过删除表单区域的文本，需要将数据库发送长度为0的字符串。<br />
            <br />
            尽管大多数数据库将空字符串作为空值进行操作，如果我们使用的<a href="http://baike.baidu.com/view/1088.htm" target="_blank">数据库</a>不支持处理空字符串的话，我们必须写入附加的java代码，来创建自己的SQL插入声明。<br />
            <br />
            例如：<br />
            <br />
            if(test.length==0)<br />
            <br />
            {<br />
            <br />
            sb.append(&ldquo;null&rdquo;);<br />
            <br />
            }<br />
            <br />
            else<br />
            <br />
            {<br />
            <br />
            sb.append(test);<br />
            <br />
            }<br />
            <br />
            JavaBean 的范围：<br />
            <br />
            JavaBean 的范围。 Scope 是一个具有生命时间的变量。JavaBean的范围在<br />
            <br />
            &lt;jsp:useBean scope=&rdquo;&hellip;.&gt;标志中右边进行表示。将产生一个JavaBean的快捷参考。<br />
            <br />
            说明：jsp服务器引擎将剥离&lt;jsp。。。。标记。并且在最终用户的浏览器上无法显示实际代码。<br />
            <br />
            存在下面四种范围： 页面、 请求、 对话、 应用。<br />
            <br />
            对话范围：<br />
            <br />
            对话范围的JavaBean 主要应用与跨多个页面和时间段： 例如填充 用户信息。 添加信息并且接受回馈，保存用户最近执行页面的轨迹。对话范围JavaBean保留一些和用户对话 ID 相关的信息。这些信息来自临时的对话cookie，并在当用户关闭浏览器时，这个cookie将从客户端和服务器删除。<br />
            <br />
            页面/请求范围：<br />
            <br />
            页面和请求范围的JavaBean有时类似表单 的bean ， 这是因为 他们大豆用与处理表单。表单需要很长的时间来处理用户的输入，通常情况下用于页面接受HTTP/POST或者GET请求。另外页面和请求范围的bean可以用于减少大型站点服务器上的负载，如果使用对话bean，耽搁的处理就可能会消耗掉很多资源。<br />
            <br />
            应用： <br />
            <br />
            应用范围通常应用于服务器的部件，例如 JDBC 连接池、应用监视、拥护计数和其他参与用户行为的类。<br />
            <br />
            在Bean中限制HTML的产生：<br />
            <br />
            理论上，JavaBean 将不会产生任何HTML，因为这是jsp层负责的工作；然而，为了动态消息提供一些预先准备的格式是非常有用的。产生的HTML将被标注的 JavaBean方法返回。<br />
            <br />
            这里有一些非常重要的事情：<br />
            <br />
            1. 不要试图在JavaBean返回的HTML中放置任何字体尺寸。<br />
            <br />
            并不是所有的浏览器都相同。很多浏览器无法处理完整的字体尺寸。 <br />
            <br />
            2. 不要试图在JavaBean返回的HTML中放置任何脚本或者DHTML。<br />
            <br />
            向页面直接输出脚本或者DHTML相当于自我毁灭，因为某些浏览器版本在处理不正确的脚本时会崩溃（非常少但是有）。如果用户的JavaBean在运行时是动态的推出复杂的HTML语言，用户将陷入调试的噩梦。另外，复杂的HTML将限制JavaBean的寿命和灵活性。<br />
            <br />
            3. 不要提供任何的选择。<br />
            <br />
            如果用户使用不同的系统浏览页面，可以提供一种可以替换的方法。<br />
            <br />
            按着Sun公司的定义，JavaBean是一个可重复使用的软件组件。实际上JavaBean是一种Java类，通过封装属性和方法成为具有某种功能或者处理某个业务的对象，简称bean。由于javabean是基于java语言的，因此javabean不依赖平台，具有以下特点： <br />
            1． 可以实现代码的重复利用 <br />
            2． 易编写、易维护、易使用 <br />
            3． 可以在任何安装了Java运行环境的平台上的使用，而不需要重新编译。 <br />
            编写javabean就是编写一个java的类，所以你只要会写类就能编写一个bean，这个类创建的一个对象称做一个bean。为了能让使用这个bean的应用程序构建工具（比如JSP引擎）知道这个bean的属性和方法，只需在类的方法命名上遵守以下规则： <br />
            1． 如果类的成员变量的名字是xxx，那么为了更改或获取成员变量的值，即更改或获取属性，在类中可以使用两个方法： <br />
            getXxx()，用来获取属性xxx。 <br />
            setXxx()，用来修改属性xxx.。 <br />
            2． 对于boolean类型的成员变量，即布尔逻辑类型的属性，允许使用&quot;is&quot;代替上面的&quot;get&quot;和&quot;set&quot;。 <br />
            3． 类中方法的访问属性都必须是public的。 <br />
            4． 类中如果有构造方法，那么这个构造方法也是public的并且是无参数的。</div>
            </td>
        </tr>
    </tbody>
</table>
<p>虽然你可以把大段的代码放在脚本片段（scriptlet）内，但是绝大多数的Java代码属于可重复使用的名为JavaBea的组件。JavaBean类似于ActiveX控件：他们都能提供常用功能并且可以重复使用。 <br />
　<br />
<br />
JavaBean的值是通过一些属性获得的，你可通过这些属性访问JavaBean设置。以一个人来打比方，这个人就是一个JavaBean，这个人的名字、身份证号码以及住址就是其属性。在JSP网站，你基本上就是通过玩&ldquo;Connect the beans）&rdquo;来使你的网站动态化。<br />
<br />
假设JavaBean先于网站被创建出来，你需要做的第一件事就是告诉JSP页面它将要用到一个&ldquo;Bean&rdquo;。你可以用&ldquo;&lt;jsp:useBean&gt;&rdquo;标记来做到这一点：<br />
&lt;jsp:useBean id=&quot;localName&quot; class=&quot;com.jguru.Person&quot; scope=&quot;application&quot; /&gt;。<br />
<br />
&ldquo;&lt;jsp:useBean&gt;&rdquo;标记要求你用&ldquo;id&rdquo;属性来识鉴别Bean。这里你提供一个名字来JSP页面其余部分的Bean。除了&ldquo;id&rdquo;属性，你还须告诉网页面从何处查找Bean，或者它的Java类别名是什么。这种类别属性提供确 认Bean的功能，其他一些方法也可以做到这一点。最后一个必需的元素是&ldquo;scope&rdquo;属性。有了&ldquo;scope&rdquo;属性的帮助，你就能告诉Bean为单一页面（默认情况）[scope=&quot;page&quot;]、为[scope=&quot;request&quot;]请求为会话[scope=&quot;session&quot;]，或者为整个应用程序[scope=&quot;application&quot;]保持留信息。有了会话范围，你就能非常容易地在JSP网页面上维护购物车等项目。<br />
<br />
一旦你声名了一个JavaBean，你就可以访问它的属性来定制它。要获得属性值，请用&ldquo;&lt;jsp:getProperty&gt;&rdquo;标记。有了这个标记，你就能指定将要用到的Bean名称（从useBean的&quot;id&quot;字段得到）以及你想得到其值的属性。实际的值被放在输出中：<br />
&lt;jsp:getProperty id=&quot;localName&quot; property=&quot;name&quot; /&gt;。<br />
<br />
要改变JavaBean属性，你必须使用&ldquo;&lt;jsp:setProperty&gt;&rdquo;标记。对这个标记，你需要再次识别Bean和属性，以修改并额外提供新值。如果命名正确，这些值可以从一个已提交的表中直接获得：参数获得：<br />
&lt;jsp:setProperty id=&quot;localName&quot; property=&quot;*&quot; /&gt;;<br />
<br />
可以从一个参数获得，但你必须直接命名属性和参数：<br />
&lt;jsp:setProperty id=&quot;localName&quot; property=&quot;serialNumber&quot; value=&quot;string&quot; /&gt;<br />
<br />
或者直接用一个名字称和值来设置： &lt;jsp:setProperty id=&quot;localName&quot; property=&quot;serialNumber&quot; value= &lt;%= expression %&gt; /&gt;.<br />
<br />
关于JavaBean 的最后一件事： 为了Web服务器能找到JavaBean，你需要将其类别文件放在一个特殊位置。用JSWDK，最 方便的位置是安装目录下的类别目录，如jswdk-1.0.1classes。 <br />
JavaBeans的属性&nbsp;<br />
<br />
JavaBeans的属性与一般Java程序中所指的属性，或者说与所有面向对象的程序设计语言中对象的属性是一个概念，在程序中的具体体现就是类中的变量。在JavaBeans设计中，按照属性的不同作用又细分为四类：Simple,&nbsp;Index,&nbsp;Bound与Constrained属性。&nbsp;<br />
<br />
1.&nbsp;Simple属性&nbsp;<br />
<br />
一个简单属性表示一个伴随有一对get/set方法（C语言的过程或函数在Java程序中称为&quot;方法&quot;）的变量。属性名与和该属性相关的get/set方法名对应。例如：如果有setX和getX方法，则暗指有一个名为&quot;X&quot;的属性。如果有一个方法名为isX，则通常暗指&quot;X&quot;是一个布尔属性（即X的值为true或false）。例如在下面这个程序中：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;alden1&nbsp;extends&nbsp;Canvas&nbsp;{&nbsp;<br />
string&nbsp;ourString=&nbsp;&quot;Hello&quot;;&nbsp;//属性名为ourString，类型为字符串&nbsp;<br />
public&nbsp;alden1(){&nbsp;　　　　//alden1()是alden1的构造函数，&nbsp;<br />
与C++中构造函数的意义相同&nbsp;<br />
setBackground(Color.red);&nbsp;<br />
setForeground(Color.blue);&nbsp;<br />
}&nbsp;<br />
/*&nbsp;&quot;set&quot;属性*/&nbsp;<br />
public&nbsp;void&nbsp;setString(String&nbsp;newString)&nbsp;{&nbsp;<br />
ourString=newString;&nbsp;<br />
}&nbsp;<br />
/*&nbsp;&quot;get&quot;属性&nbsp;*/&nbsp;<br />
public&nbsp;String&nbsp;getString()&nbsp;{&nbsp;<br />
return&nbsp;ourString;&nbsp;<br />
}&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
2.&nbsp;Indexed属性&nbsp;<br />
<br />
一个Indexed属性表示一个数组值。使用与该属性对应的set/get方法可取得数组中的数值。该属性也可一次设置或取得整个数组的值。例：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;alden2&nbsp;extends&nbsp;Canvas&nbsp;{&nbsp;<br />
int[]&nbsp;dataSet={1,2,3,4,5,6};&nbsp;//&nbsp;dataSet是一个indexed属性&nbsp;<br />
public&nbsp;alden2()&nbsp;{&nbsp;<br />
setBackground(Color.red);&nbsp;<br />
setForeground(Color.blue);&nbsp;<br />
}&nbsp;<br />
/*&nbsp;设置整个数组　*/&nbsp;<br />
public&nbsp;void&nbsp;setDataSet(int[]&nbsp;x){&nbsp;<br />
dataSet=x;&nbsp;<br />
}&nbsp;<br />
/*&nbsp;设置数组中的单个元素值&nbsp;*/&nbsp;<br />
public&nbsp;void&nbsp;setDataSet(int&nbsp;index,&nbsp;int&nbsp;x){&nbsp;<br />
dataSet[index]=x;&nbsp;<br />
}&nbsp;<br />
/*&nbsp;取得整个数组值&nbsp;*/&nbsp;<br />
public&nbsp;int[]&nbsp;getDataSet(){&nbsp;<br />
return&nbsp;dataSet;&nbsp;<br />
}&nbsp;<br />
/*&nbsp;取得数组中的指定元素值&nbsp;*/&nbsp;<br />
public&nbsp;int&nbsp;getDataSet(int&nbsp;x){&nbsp;<br />
return&nbsp;dataSet[x];&nbsp;<br />
}&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
3.&nbsp;Bound属性&nbsp;<br />
<br />
一个Bound属性是指当该种属性的值发生变化时，要通知其它的对象。每次属性值改变时，这种属性就点火一个PropertyChange事件(在Java程序中，事件也是一个对象)。事件中封装了属性名、属性的原值、属性变化后的新值。这种事件是传递到其它的Beans，至于接收事件的Beans应做什么动作由其自己定义。当PushButton的background属性与Dialog的background属性bind时，若PushButton的background属性发生变化时，Dialog的background属性也发生同样的变化。&nbsp;例：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;alden3&nbsp;extends&nbsp;Canvas{&nbsp;<br />
String&nbsp;ourString=&nbsp;&quot;Hello&quot;;&nbsp;<br />
//ourString是一个bound属性&nbsp;<br />
private&nbsp;PropertyChangeSupport&nbsp;changes&nbsp;=&nbsp;new&nbsp;PropertyChangeSupport(this);&nbsp;<br />
/**&nbsp;注：Java是纯面向对象的语言，&nbsp;<br />
如果要使用某种方法则必须指明是要使用哪个对象的方法，&nbsp;<br />
在下面的程序中要进行点火事件的操作，&nbsp;<br />
这种操作所使用的方法是在PropertyChangeSupport类中的。&nbsp;<br />
所以上面声明并实例化了一个changes对象，&nbsp;<br />
在下面将使用changes的firePropertyChange方法来点火ourString的属性改变事件。*/&nbsp;<br />
<br />
public&nbsp;void&nbsp;setString(string&nbsp;newString){&nbsp;<br />
String&nbsp;oldString&nbsp;=&nbsp;ourString;&nbsp;<br />
ourString&nbsp;=&nbsp;newString;&nbsp;<br />
/*&nbsp;ourString的属性值已发生变化，于是接着点火属性改变事件&nbsp;*/&nbsp;<br />
changes.firePropertyChange(&quot;ourString&quot;,oldString,newString);&nbsp;<br />
}&nbsp;<br />
public&nbsp;String&nbsp;getString(){&nbsp;<br />
return&nbsp;ourString;&nbsp;<br />
}&nbsp;<br />
/**&nbsp;以下代码是为开发工具所使用的。&nbsp;<br />
我们不能预知alden3将与哪些其它的Beans组合成为一个应用，&nbsp;<br />
无法预知若alden3的ourString属性发生变化时有哪些其它的组件与此变化有关，&nbsp;<br />
因而alden3这个Beans要预留出一些接口给开发工具，&nbsp;<br />
开发工具使用这些接口，&nbsp;<br />
把其它的JavaBeans对象与alden3挂接。*/&nbsp;<br />
<br />
public&nbsp;void&nbsp;addPropertyChangeListener(PropertyChangeLisener&nbsp;l){&nbsp;<br />
changes.addPropertyChangeListener(l);&nbsp;<br />
}&nbsp;<br />
public&nbsp;void&nbsp;removePropertyChangeListener(PropertyChangeListener&nbsp;l){&nbsp;<br />
changes.removePropertyChangeListener(l);&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
通过上面的代码，&nbsp;<br />
<br />
开发工具调用changes的addPropertyChangeListener方法&nbsp;<br />
<br />
把其它JavaBeans注册入ourString属性的监听者队列l中，&nbsp;<br />
<br />
l是一个Vector数组，可存储任何Java对象。&nbsp;<br />
<br />
开发工具也可使用changes的removePropertyChangeListener方法，&nbsp;<br />
<br />
从l中注销指定的对象，&nbsp;<br />
<br />
使alden3的ourString属性的改变不再与这个对象有关。&nbsp;<br />
<br />
当然，当程序员手写代码编制程序时，&nbsp;<br />
<br />
也可直接调用这两个方法，&nbsp;<br />
<br />
把其它Java对象与alden3挂接。&nbsp;<br />
<br />
4.&nbsp;Constrained属性&nbsp;<br />
<br />
一个JavaBeans的constrained属性，是指当这个属性的值要发生变化时，与这个属性已建立了某种连接的其它Java对象可否决属性值的改变。constrained属性的监听者通过抛出PropertyVetoException来阻止该属性值的改变。例：下面程序中的constrained属性是PriceInCents。&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;JellyBeans&nbsp;extends&nbsp;Canvas{&nbsp;<br />
private&nbsp;PropertyChangeSupport&nbsp;changes=new&nbsp;PropertyChangeSupport(this);&nbsp;<br />
private&nbsp;VetoableChangeSupport&nbsp;Vetos=new&nbsp;VetoableChangeSupport(this);&nbsp;<br />
/*与前述changes相同，&nbsp;<br />
可使用VetoableChangeSupport对象的实例Vetos中的方法，&nbsp;<br />
在特定条件下来阻止PriceInCents值的改变。*/&nbsp;<br />
<br />
<br />
......&nbsp;<br />
public&nbsp;void&nbsp;setPriceInCents(int&nbsp;newPriceInCents)&nbsp;throws&nbsp;PropertyVetoException&nbsp;{&nbsp;<br />
/*方法名中throws&nbsp;PropertyVetoException的作用是当有&nbsp;<br />
其它Java对象否决PriceInCents的改变时，&nbsp;<br />
要抛出例外。*/&nbsp;<br />
/*&nbsp;先保存原来的属性值*/&nbsp;<br />
<br />
int&nbsp;oldPriceInCents=ourPriceInCents;&nbsp;<br />
/**点火属性改变否决事件*/&nbsp;<br />
vetos.fireVetoableChange(&quot;priceInCents&quot;,new&nbsp;Integer(OldPriceInCents),&nbsp;<br />
new&nbsp;Integer(newPriceInCents));&nbsp;<br />
<br />
/**若有其它对象否决priceInCents的改变，&nbsp;<br />
则程序抛出例外，不再继续执行下面的两条语句，&nbsp;<br />
方法结束。若无其它对象否决priceInCents的改变，&nbsp;<br />
则在下面的代码中把ourPriceIncents赋予新值，&nbsp;<br />
并点火属性改变事件*/&nbsp;<br />
<br />
ourPriceInCents=newPriceInCents;&nbsp;<br />
changes.firePropertyChange(&quot;priceInCents&quot;,&nbsp;<br />
new&nbsp;Integer(oldPriceInCents),&nbsp;<br />
new&nbsp;Integer(newPriceInCents));&nbsp;<br />
}&nbsp;<br />
<br />
/**与前述changes相同，&nbsp;<br />
也要为PriceInCents属性预留接口，&nbsp;<br />
使其它对象可注册入PriceInCents否决改变监听者队列中，&nbsp;<br />
或把该对象从中注销&nbsp;<br />
<br />
public&nbsp;void&nbsp;addVetoableChangeListener(VetoableChangeListener&nbsp;l)&nbsp;<br />
{&nbsp;vetos.addVetoableChangeListener(l);&nbsp;<br />
}&nbsp;<br />
public&nbsp;void&nbsp;removeVetoableChangeListener(VetoableChangeListener&nbsp;l){&nbsp;<br />
vetos.removeVetoableChangeListener(l);&nbsp;<br />
}&nbsp;<br />
......&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
从上面的例子中可看到，一个constrained属性有两种监听者：属性变化监听者和否决属性改变的监听者。否决属性改变的监听者在自己的对象代码中有相应的控制语句，在监听到有constrained属性要发生变化时，在控制语句中判断是否应否决这个属性值的改变。&nbsp;<br />
<br />
总之，某个Beans的constrained属性值可否改变取决于其它的Beans或者是Java对象是否允许这种改变。允许与否的条件由其它的Beans或Java对象在自己的类中进行定义。&nbsp;<br />
<br />
JavaBeans的事件&nbsp;<br />
<br />
事件处理是JavaBeans体系结构的核心之一。通过事件处理机制，可让一些组件作为事件源，发出可被描述环境或其它组件接收的事件。这样，不同的组件就可在构造工具内组合在一起，组件之间通过事件的传递进行通信，构成一个应用。从概念上讲，事件是一种在&quot;源对象&quot;和&quot;监听者对象&quot;之间，某种状态发生变化的传递机制。事件有许多不同的用途，例如在Windows系统中常要处理的鼠标事件、窗口边界改变事件、键盘事件等。在Java和JavaBeans中则是定义了一个一般的、可扩充的事件机制，这种机制能够：&nbsp;<br />
<br />
对事件类型和传递的模型的定义和扩充提供一个公共框架，并适合于广泛的应用。&nbsp;<br />
<br />
与Java语言和环境有较高的集成度。&nbsp;<br />
<br />
事件能被描述环境捕获和点火。&nbsp;<br />
<br />
能使其它构造工具采取某种技术在设计时直接控制事件，以及事件源和事件监听者之间的联系。&nbsp;<br />
<br />
事件机制本身不依赖于复杂的开发工具。特别地，还应当：&nbsp;<br />
<br />
能够发现指定的对象类可以生成的事件。&nbsp;<br />
<br />
能够发现指定的对象类可以观察（监听）到的事件。&nbsp;<br />
<br />
提供一个常规的注册机制，允许动态操纵事件源与事件监听者之间的关系。&nbsp;<br />
<br />
不需要其它的虚拟机和语言即可实现。&nbsp;<br />
<br />
事件源与监听者之间可进行高效的事件传递。&nbsp;<br />
<br />
能完成JavaBeans事件模型与相关的其它组件体系结构事件模型的中立映射。&nbsp;<br />
<br />
JavaBeans事件模型的主要构成有：&nbsp;事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。对每个明确的事件的发生，都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者（EventListener）接口中，这个接口要继承java.util.EventListener。实现了事件监听者接口中一些或全部方法的类就是事件监听者。&nbsp;伴随着事件的发生，相应的状态通常都封装在事件状态对象中，该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响应该事件的监听者方法中。&nbsp;发出某种特定事件的事件源的标识是：遵从规定的设计格式为事件监听者定义注册方法，并接受对指定事件监听者接口实例的引用。&nbsp;有时，事件监听者不能直接实现事件监听者接口，或者还有其它的额外动作时，就要在一个源与其它一个或多个监听者之间插入一个事件适配器类的实例，来建立它们之间的联系。&nbsp;<br />
<br />
事件状态对象（Event&nbsp;State&nbsp;Object）&nbsp;<br />
<br />
与事件发生有关的状态信息一般都封装在一个事件状态对象中，这种对象是java.util.EventObject的子类。按设计习惯，这种事件状态对象类的名应以Event结尾。例如：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;MouseMovedExampleEvent&nbsp;extends&nbsp;java.util.EventObject&nbsp;<br />
<br />
{&nbsp;protected&nbsp;int&nbsp;x,&nbsp;y；&nbsp;<br />
/*　创建一个鼠标移动事件MouseMovedExampleEvent&nbsp;*/&nbsp;<br />
　&nbsp;MouseMovedExampleEvent(java.awt.Component&nbsp;source,&nbsp;Point&nbsp;location)&nbsp;{&nbsp;<br />
super(source);&nbsp;<br />
x&nbsp;=&nbsp;location.x;&nbsp;<br />
y&nbsp;=&nbsp;location.y;&nbsp;<br />
}&nbsp;<br />
/*&nbsp;获取鼠标位置*/&nbsp;<br />
public&nbsp;Point&nbsp;getLocation()&nbsp;{&nbsp;<br />
return&nbsp;new&nbsp;Point(x,&nbsp;y);&nbsp;<br />
}}&nbsp;<br />
<br />
<br />
<br />
<br />
事件监听者接口（EventListener&nbsp;Interface）与事件监听者&nbsp;<br />
<br />
由于Java事件模型是基于方法调用，因而需要一个定义并组织事件操纵方法的方式。JavaBeans中，事件操纵方法都被定义在继承了java.util.EventListener类的EventListener接口中，按规定，EventListener接口的命名要以Listener结尾。任何一个类如果想操纵在EventListener接口中定义的方法都必须以实现这个接口方式进行。这个类也就是事件监听者。例如：&nbsp;<br />
<br />
<br />
/*先定义了一个鼠标移动事件对象*/&nbsp;<br />
　　&nbsp;public&nbsp;class&nbsp;MouseMovedExampleEvent&nbsp;<br />
extends&nbsp;java.util.EventObject&nbsp;{&nbsp;<br />
//&nbsp;在此类中包含了与鼠标移动事件有关的状态信息&nbsp;<br />
　　　　&nbsp;...&nbsp;<br />
　　&nbsp;}&nbsp;<br />
　　&nbsp;/*定义了鼠标移动事件的监听者接口*/&nbsp;<br />
　　&nbsp;interface&nbsp;MouseMovedExampleListener&nbsp;<br />
extends&nbsp;java.util.EventListener&nbsp;{&nbsp;<br />
/*在这个接口中定义了鼠标移动事件监听者所应支持的方法*/&nbsp;<br />
void&nbsp;mouseMoved(MouseMovedExampleEvent&nbsp;mme);&nbsp;<br />
}&nbsp;<br />
<br />
在接口中只定义方法名，&nbsp;<br />
方法的参数和返回值类型。&nbsp;<br />
如：上面接口中的mouseMoved方法的&nbsp;<br />
具体实现是在下面的ArbitraryObject类中定义的。&nbsp;<br />
<br />
class&nbsp;ArbitraryObject&nbsp;implements&nbsp;MouseMovedExampleListener&nbsp;{&nbsp;<br />
　　　&nbsp;public&nbsp;void&nbsp;mouseMoved(MouseMovedExampleEvent&nbsp;mme)&nbsp;<br />
　&nbsp;{&nbsp;...&nbsp;}&nbsp;<br />
｝&nbsp;<br />
ArbitraryObject就是MouseMovedExampleEvent事件的监听者。&nbsp;<br />
<br />
<br />
<br />
<br />
事件监听者的注册与注销&nbsp;<br />
<br />
为了各种可能的事件监听者把自己注册入合适的事件源中，建立源与事件监听者间的事件流，事件源必须为事件监听者提供注册和注销的方法。在前面的bound属性介绍中已看到了这种使用过程，在实际中，事件监听者的注册和注销要使用标准的设计格式：&nbsp;<br />
<br />
<br />
public&nbsp;void&nbsp;add&lt;&nbsp;ListenerType&gt;(&lt;&nbsp;ListenerType&gt;&nbsp;listener)；&nbsp;<br />
public&nbsp;void&nbsp;remove&lt;&nbsp;ListenerType&gt;(&lt;&nbsp;ListenerType&gt;&nbsp;listener)；&nbsp;<br />
<br />
<br />
<br />
<br />
例如：&nbsp;<br />
<br />
首先定义了一个事件监听者接口：&nbsp;<br />
<br />
<br />
public&nbsp;interface&nbsp;<br />
ModelChangedListener&nbsp;extends&nbsp;java.util.EventListener&nbsp;{&nbsp;<br />
void&nbsp;modelChanged(EventObject&nbsp;e);&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
接着定义事件源类：&nbsp;<br />
<br />
<br />
public&nbsp;abstract&nbsp;class&nbsp;Model&nbsp;{&nbsp;<br />
private&nbsp;Vector&nbsp;listeners&nbsp;=&nbsp;new&nbsp;Vector();&nbsp;//&nbsp;定义了一个储存事件监听者的数组&nbsp;<br />
<br />
/*上面设计格式中的&lt;&nbsp;ListenerType&gt;在此处即是下面的ModelChangedListener*/&nbsp;<br />
<br />
public&nbsp;synchronized&nbsp;void&nbsp;addModelChangedListener(ModelChangedListener&nbsp;mcl)&nbsp;<br />
　　&nbsp;{&nbsp;listeners.addElement(mcl);&nbsp;}//把监听者注册入listeners数组中&nbsp;<br />
public&nbsp;synchronized&nbsp;void&nbsp;removeModelChangedListener(ModelChangedListener&nbsp;mcl)&nbsp;<br />
　　　　&nbsp;{&nbsp;listeners.removeElement(mcl);&nbsp;//把监听者从listeners中注销&nbsp;<br />
　　　　&nbsp;｝&nbsp;<br />
　　&nbsp;/*以上两个方法的前面均冠以synchronized，&nbsp;<br />
是因为运行在多线程环境时，&nbsp;<br />
可能同时有几个对象同时要进行注册和注销操作，&nbsp;<br />
使用synchronized来确保它们之间的同步。&nbsp;<br />
开发工具或程序员使用这两个方法建立源与监听者之间的事件流*/&nbsp;<br />
<br />
protected&nbsp;void&nbsp;notifyModelChanged()&nbsp;{&nbsp;<br />
/**事件源使用本方法通知监听者发生了modelChanged事件*/&nbsp;<br />
　　　&nbsp;Vector&nbsp;l;&nbsp;<br />
　　　　&nbsp;EventObject&nbsp;e&nbsp;=&nbsp;new&nbsp;EventObject(this);&nbsp;<br />
/*&nbsp;首先要把监听者拷贝到l数组中，&nbsp;<br />
冻结EventListeners的状态以传递事件。&nbsp;<br />
这样来确保在事件传递到所有监听者之前，&nbsp;<br />
已接收了事件的目标监听者的对应方法暂不生效。*/&nbsp;<br />
　　　　&nbsp;synchronized(this)&nbsp;{&nbsp;<br />
　　　　　　&nbsp;l&nbsp;=&nbsp;(Vector)listeners.clone();&nbsp;<br />
　　　　&nbsp;}&nbsp;<br />
　　　　&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;l.size();&nbsp;i++)&nbsp;{&nbsp;<br />
　　　　&nbsp;/*&nbsp;依次通知注册在监听者队列中的每个监听者发生了modelChanged事件，&nbsp;<br />
　　　　&nbsp;并把事件状态对象e作为参数传递给监听者队列中的每个监听者*/&nbsp;<br />
((ModelChangedListener)l.elementAt(i)).modelChanged(e);&nbsp;<br />
　　　　&nbsp;}&nbsp;<br />
　　　&nbsp;}&nbsp;<br />
　　　&nbsp;}&nbsp;<br />
<br />
<br />
<br />
<br />
在程序中可见事件源Model类显式地调用了接口中的modelChanged方法，实际是把事件状态对象e作为参数，传递给了监听者类中的modelChanged方法。&nbsp;<br />
<br />
适配类&nbsp;<br />
<br />
适配类是Java事件模型中极其重要的一部分。在一些应用场合，事件从源到监听者之间的传递要通过适配类来&quot;转发&quot;。例如：当事件源发出一个事件，而有几个事件监听者对象都可接收该事件，但只有指定对象做出反应时，就要在事件源与事件监听者之间插入一个事件适配器类，由适配器类来指定事件应该是由哪些监听者来响应。&nbsp;<br />
<br />
适配类成为了事件监听者，事件源实际是把适配类作为监听者注册入监听者队列中，而真正的事件响应者并未在监听者队列中，事件响应者应做的动作由适配类决定。目前绝大多数的开发工具在生成代码时，事件处理都是通过适配类来进行的。&nbsp;<br />
<br />
JavaBeans用户化&nbsp;<br />
<br />
JavaBeans开发者可以给一个Beans添加用户化器（Customizer）、属性编辑器（PropertyEditor）和BeansInfo接口来描述一个Beans的内容，Beans的使用者可在构造环境中通过与Beans附带在一起的这些信息来用户化Beans的外观和应做的动作。一个Beans不必都有BeansCustomizer、PrpertyEditor和BeansInfo，根据实际情况，这些是可选的，当有些Beans较复杂时，就要提供这些信息，以Wizard的方式使Beans的使用者能够用户化一个Beans。有些简单的Beans可能这些信息都没有，则构造工具可使用自带的透视装置，透视出Beans的内容，并把信息显示到标准的属性表或事件表中供使用者用户化Beans，前几节提到的Beans的属性、方法和事件名要以一定的格式命名，主要的作用就是供开发工具对Beans进行透视。当然也是给程序员在手写程序中使用Beans提供方便，使他能观其名、知其意。&nbsp;<br />
<br />
用户化器接口（Customizer&nbsp;Interface）&nbsp;<br />
<br />
当一个Beans有了自己的用户化器时，在构造工具内就可展现出自己的属性表。在定义用户化器时必须要实现java.Beanss.Customizer接口。例如，下面是一个&quot;按钮&quot;Beans的用户化一器：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;OurButtonCustomizer&nbsp;<br />
extends&nbsp;Panel&nbsp;implements&nbsp;Customizer&nbsp;{&nbsp;<br />
...&nbsp;...&nbsp;<br />
/*当实现象OurButtonCustomizer这样的常规属性表时，&nbsp;<br />
一定要在其中实现addProperChangeListener&nbsp;<br />
和removePropertyChangeListener,这样，&nbsp;<br />
构造工具可用这些功能代码为属性事件添加监听者。*/&nbsp;<br />
...&nbsp;...&nbsp;<br />
private&nbsp;PropertyChangeSupport&nbsp;changes=new&nbsp;PropertyChangeSupport(this);&nbsp;<br />
public&nbsp;void&nbsp;addPropertyChangeListener(PropertyChangeListener&nbsp;l)&nbsp;{&nbsp;<br />
changes.addPropertyChangeListener(l);&nbsp;<br />
public&nbsp;void&nbsp;removePropertyChangeListener(PropertyChangeListener&nbsp;l)&nbsp;{&nbsp;<br />
changes.removePropertyChangeListener(l);&nbsp;<br />
}&nbsp;<br />
...&nbsp;...&nbsp;<br />
<br />
<br />
<br />
<br />
属性编辑器接口（PropertyEditor&nbsp;Interface）&nbsp;<br />
<br />
一个JavaBeans可提供PropertyEditor类，为指定的属性创建一个编辑器。这个类必须继承自java.Beanss.PropertyEditorSupport类。构造工具与手写代码的程序员不直接使用这个类，而是在下一小节的BeansInfo中实例化并调用这个类。例：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;MoleculeNameEditor&nbsp;extends&nbsp;java.Beanss.PropertyEditorSupport&nbsp;{&nbsp;<br />
public&nbsp;String[]&nbsp;getTags()&nbsp;{&nbsp;<br />
String&nbsp;resule[]={&nbsp;<br />
&quot;HyaluronicAcid&quot;,&quot;Benzene&quot;,&quot;buckmisterfullerine&quot;,&nbsp;<br />
&quot;cyclohexane&quot;,&quot;ethane&quot;,&quot;water&quot;};&nbsp;<br />
return&nbsp;resule;}&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
上例中是为Tags属性创建了属性编辑器，在构造工具内，可从下拉表格中选择MoleculeName的属性应是&quot;HyaluronicAid&quot;或是&quot;water&quot;。&nbsp;<br />
<br />
BeansInfo接口&nbsp;<br />
<br />
每个Beans类也可能有与之相关的BeansInfo类，在其中描述了这个Beans在构造工具内出现时的外观。BeansInfo中可定义属性、方法、事件，显示它们的名称，提供简单的帮助说明。&nbsp;例如：&nbsp;<br />
<br />
<br />
public&nbsp;class&nbsp;MoleculeBeansInfo&nbsp;extends&nbsp;SimpleBeansInfo&nbsp;{&nbsp;<br />
public&nbsp;PropertyDescriptor[]&nbsp;getPropertyDescriptors()&nbsp;{&nbsp;<br />
try&nbsp;{&nbsp;<br />
PropertyDescriptor&nbsp;pd=new&nbsp;PropertyDescriptor(&quot;moleculeName&quot;,Molecule.class);&nbsp;<br />
/*通过pd引用了上一节的MoleculeNameEditor类,取得并返回moleculeName属性*/&nbsp;<br />
pd.setPropertyEditorClass(MoleculeNameEditor.class);&nbsp;<br />
PropertyDescriptor&nbsp;result[]={pd};&nbsp;<br />
return&nbsp;result;&nbsp;<br />
}&nbsp;catch(Exception&nbsp;ex)&nbsp;{&nbsp;<br />
System.err.println(&quot;MoleculeBeansInfo:&nbsp;unexpected&nbsp;exeption:&nbsp;&quot;+ex);&nbsp;<br />
return&nbsp;null;&nbsp;<br />
}&nbsp;<br />
}&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
<br />
JavaBeans持久化&nbsp;<br />
<br />
当一个JavaBeans在构造工具内被用户化，并与其它Beans建立连接之后，它的所有状态都应当可被保存，下一次被load进构造工具内或在运行时，就应当是上一次修改完的信息。为了能做到这一点，要把Beans的某些字段的信息保存下来，在定义Beans时要使它实现java.io.Serializable接口。例如：&nbsp;<br />
<br />
public&nbsp;class&nbsp;Button&nbsp;<br />
implements&nbsp;java.io.Serializable&nbsp;{&nbsp;<br />
}&nbsp;<br />
<br />
<br />
<br />
实现了序列化接口的Beans中字段的信息将被自动保存。若不想保存某些字段的信息则可在这些字段前冠以transient或static关键字，transient和static变量的信息是不可被保存的。通常，一个Beans所有公开出来的属性都应当是被保存的，也可有选择地保存内部状态。&nbsp;Beans开发者在修改软件时，可以添加字段，移走对其它类的引用，改变一个字段的private/protected/public状态，这些都不影响类的存储结构关系。然而，当从类中删除一个字段，改变一个变量在类体系中的位置，把某个字段改成transient/static，或原来是transient/static，现改为别的特性时，都将引起存储关系的变化。&nbsp;<br />
<br />
JavaBeans的存储格式&nbsp;<br />
<br />
JavaBeans组件被设计出来后，一般是以扩展名为jar的Zip格式文件存储，在jar中包含与JavaBeans有关的信息，并以MANIFEST文件指定其中的哪些类是JavaBeans。以jar文件存储的JavaBeans在网络中传送时极大地减少了数据的传输数量，并把JavaBeans运行时所需要的一些资源捆绑在一起，本章主要论述了JavaBeans的一些内部特性及其常规设计方法，参考的是JavaBeans规范1.0A版本。随着世界各大ISV对JavaBeans越来越多的支持，规范在一些细节上还在不断演化，但基本框架不会再有大的变动。&nbsp;<br />
一个donewuser.jsp文件用来实现记录添加操作，另一个文件listuser.jsp文件 <br />
用来显示所有的已经注册的用户信息。这两个页面都涉及到了JavaBean的具体调用，还是来看看文件吧， <br />
对于文件中关键代码，都会添加上注释，以方便大家理解。 <br />
<br />
　　donewuser.jsp文件 <br />
<br />
　　说明：用户注册操作页面，并根据用户注册成功否显示相应的反馈信息，这个页面主要的特点就是使用了 <br />
lyf.adduser这个JavaBean的addNewUser()方法来进行记录的添加。 <br />
<br />
&lt; %@ page contentType=&quot;text/html;charset=gb2312&quot;%&gt; <br />
&lt; % response.setHeader(&quot;Expires&quot;,&quot;0&quot;); %&gt; <br />
&lt; !--生成一个JavaBean:lyf.adduser的实例，id为adduser，生存范围为page--&gt; <br />
&lt; jsp:useBean id=&quot;adduser&quot; class=&quot;lyf.adduser&quot; scope=&quot;page&quot;/&gt; <br />
<br />
　　&lt; !--设置JavaBean中各个属性的值，这会调用JavaBean中各个属性的set方法，以便JavaBean得到 <br />
正确的属性值，&rdquo;*&rdquo;代表进行所有属性的匹配--&gt; <br />
<br />
&lt; jsp:setProperty name=&quot;adduser&quot; property=&quot;*&quot;/&gt; <br />
&lt; html&gt; <br />
&lt; head&gt; <br />
&lt; meta http-equiv=&quot;Content-Language&quot; content=&quot;zh-cn&quot;&gt; <br />
&lt; meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=gb2312&quot;&gt; <br />
&lt; meta name=&quot;GENERATOR&quot; content=&quot;Microsoft FrontPage 3.0&quot;&gt; <br />
&lt; meta name=&quot;ProgId&quot; content=&quot;FrontPage.Editor.Document&quot;&gt; <br />
&lt; title&gt;用户添加&lt; /title&gt; <br />
&lt; /head&gt; <br />
&lt; body bgcolor=&quot;#FFEBBD&quot;&gt; <br />
&lt; div align=&quot;center&quot;&gt;&lt; center&gt; <br />
&lt; % <br />
<br />
　　//调用lyf.adduser的checkUser()方法检查是否有重复的用户名 <br />
<br />
　　//如果有重复就显示对应的信息 <br />
<br />
if(!adduser.checkUser()) <br />
{ <br />
<br />
　　//页面文字输出信息，使用jsp内置对象out的println方法，相当于asp中的response.write方法 <br />
<br />
out.println(&quot;对不起，这个用户名&quot;+adduser.getUsername()+&quot;已经被申请了，请重新选择！&quot;); <br />
<br />
　　//return代表返回，运行时候碰到return就不会进行下面的处理了，功能相当于asp中的response.end <br />
<br />
return; <br />
} <br />
%&gt; <br />
&lt; % <br />
//如果没有用户名重复的问题，调用lyf.adduser的addNewUser()方法来将用户数据添加到数据库中，并 <br />
根据数据添加成功否来显示对应的信息 <br />
<br />
if(adduser.addNewUser()){ <br />
%&gt; <br />
&lt; H2&gt;添加用户成功！ <br />
<br />
&lt; H2&gt;添加用户失败，请和管理员联系！ <br />
<br />
&lt; /BODY&gt; <br />
&lt; /HTML&gt; <br />
<br />
　　listuser.jsp文件 <br />
<br />
　　说明：用户信息列表页面，用于显示注册的所有用户信息，对数据进行了分页显示。 <br />
<br />
　　为了方便大家使用，采用了通用的分页代码，如果是JDBC2.0以上或者其他支持 <br />
TYPE_SCROLL_INSENSITIVE游标的数据库驱动程序，可以有更简洁的分页方法。 <br />
<br />
　　和前面jsp页面类似的语句就不讲解了，代表在 <br />
这个页面中导入java.sql.ResultSet的这个类库，因为Jsp页面中间要声明ResultSet； <br />
oracle.jdbc.driver.*类库是Oracle专用的Jdbc驱动程序，让Jsp页面可以用来进行Oracle的数据库操作。 <br />
<br />
&lt; %@ page contentType=&quot;text/html;charset=gb2312&quot;%&gt; <br />
&lt; % response.setHeader(&quot;Expires&quot;,&quot;0&quot;); %&gt; <br />
&lt; %@ page import=&quot;java.sql.ResultSet&quot; %&gt; <br />
&lt; %@ page import=&quot;oracle.jdbc.driver.*&quot; %&gt; <br />
&lt; !--生成一个JavaBean:lyf.db的实例--&gt; <br />
&lt; jsp:useBean id=&quot;db&quot; class=&quot;lyf.db&quot; scope=&quot;request&quot;/&gt; <br />
&lt; jsp:setProperty name=&quot;db&quot; property=&quot;*&quot;/&gt; <br />
&lt; % <br />
<br />
java.lang.String strSQL; //SQL语句 <br />
<br />
int intPageSize; //一页显示的记录数 <br />
int intRowCount; //记录总数 <br />
int intPageCount; //总页数 <br />
int intPage; //待显示页码 <br />
java.lang.String strPage; <br />
int i,j,k; <br />
　　//设置一页显示的记录数 <br />
intPageSize = 15; <br />
　　//取得待显示页码 <br />
strPage = request.getParameter(&quot;page&quot;); <br />
if(strPage==null){//表明在QueryString中没有page这一个参数，此时显示第一页数据 <br />
intPage = 1; <br />
} <br />
else{//将字符串转换成整型 <br />
intPage = java.lang.Integer.parseInt(strPage); <br />
if(intPage&lt;1) intPage = 1; <br />
} <br />
//获取记录总数 <br />
strSQL = &quot;select count(*) from user&quot;; <br />
ResultSet result = db.executeQuery(strSQL); //执行SQL语句并取得结果集 <br />
result.next(); //记录集刚打开的时候，指针位于第一条记录之前 <br />
intRowCount = result.getInt(1); <br />
result.close(); //关闭结果集 <br />
　　//记算总页数 <br />
intPageCount = (intRowCount+intPageSize-1) / intPageSize; <br />
　　//调整待显示的页码 <br />
if(intPage&gt;intPageCount) intPage = intPageCount; <br />
strSQL=&quot;select * from user order by id desc&quot;; <br />
　　//执行SQL语句并取得结果集 <br />
result = db.executeQuery(strSQL); <br />
　　//将记录指针定位到待显示页的第一条记录上 <br />
i = (intPage-1) * intPageSize; <br />
for(j=0;j <br />
&lt; html&gt; <br />
&lt; head&gt; <br />
&lt; meta http-equiv=&quot;Content-Language&quot; content=&quot;zh-cn&quot;&gt; <br />
&lt; meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=gb2312&quot;&gt; <br />
&lt; meta name=&quot;GENERATOR&quot; content=&quot;Microsoft FrontPage 3.0&quot;&gt; <br />
&lt; meta name=&quot;ProgId&quot; content=&quot;FrontPage.Editor.Document&quot;&gt; <br />
&lt; title&gt;用户列表&lt; /title&gt; <br />
&lt; /head&gt; <br />
&lt; body bgcolor=&quot;#FFEBBD&quot;&gt; <br />
&lt; div align=&quot;center&quot;&gt;&lt; center&gt; <br />
&lt; table border=&quot;1&quot; <br />
borderColorDark=&quot;#FFFFFF&quot; borderColorLight=&quot;#000000&quot; cellspacing=&quot;0&quot; height=&quot;22&quot; <br />
width=&quot;100%&quot;&gt; <br />
&lt; tr bgcolor=&quot;#FFEBAD&quot;&gt; <br />
&lt; td height=&quot;1&quot; width=&quot;691&quot; class=&quot;main&quot;&gt; <br />
第页 共页 <br />
&lt; a href=&quot;listuser.jsp?page=0&quot;&gt;首页 <br />
&lt; a href=&quot;listuser.jsp?page=&quot;&gt;上一页 <br />
上一页 <br />
&lt; a href=&quot;listuser.jsp?page=&quot;&gt;下一页 <br />
下一页 <br />
&lt; a href=&quot;listuser.jsp?page=&quot;&gt;尾页 <br />
第&lt; input type=&quot;text&quot; class=&quot;main&quot; name=&quot;page&quot; size=&quot;3&quot; value=&quot;&quot; <br />
tabindex=&quot;1&quot;&gt;页&lt; input type=&quot;submit&quot; class=&quot;main&quot; value=&quot;go&quot; name=&quot;B1&quot; tabindex=&quot;2&quot;&gt; <br />
<br />
<br />
&lt; table border=&quot;1&quot; width=&quot;100%&quot; cellspacing=&quot;0&quot; bordercolorlight=&quot;#000000&quot; <br />
bordercolordark=&quot;#FFFFFF&quot; class=&quot;main&quot;&gt; <br />
&lt; tr bgcolor=&quot;#FFEBAD&quot;&gt; <br />
&lt; td &gt; <br />
&lt; div align=&quot;left&quot;&gt;用户名 <br />
<br />
&lt; td &gt; <br />
&lt; p align=&quot;center&quot;&gt;Email <br />
<br />
&lt; td &gt; <br />
&lt; p align=&quot;center&quot;&gt;主页 <br />
<br />
&lt; td&gt; <br />
&lt; p align=&quot;center&quot;&gt;登记时间 <br />
<br />
&lt; td&gt; <br />
&lt; p align=&quot;center&quot;&gt;说明 <br />
<br />
<br />
&lt; tr bgcolor=&quot;#FFEBAD&quot;&gt; <br />
&lt; td&gt; <br />
&lt; div align=&quot;left&quot;&gt; <br />
&lt; td&gt;&lt; div align=&quot;center&quot;&gt; <br />
&lt; td&gt;&lt; div align=&quot;center&quot;&gt;&lt; font color=&quot;#0000CC&quot;&gt; <br />
<br />
&lt; td&gt;&lt; div align=&quot;center&quot;&gt;&lt; font color=&quot;#FF6666&quot;&gt; <br />
<br />
&lt; td&gt;&lt; div align=&quot;center&quot;&gt;&lt; font color=&quot;#0000FF&quot;&gt; <br />
<br />
<br />
&lt; /table&gt; <br />
<br />
&lt; /body&gt; <br />
&lt; /html&gt; <br />
　　 <br />
　　先运行程序newuser.jsp文件，进行用户注册操作，然后运行listuser.jsp文件，看看是否已经 <br />
添加到数据库中。对于具体jsp文件和class文件放在什么目录下的问题，请看具体jsp服务器软件的参考， <br />
一个最简单的方法就是用Jbuilder4.0直接运行，因为它自带了Tomcat服务器软件。 <br />
<br />
　　好了，到这里Jsp+JavaBean的介绍就基本上结束了。</p>
<p>jsp文件：pagedata.jsp //显示数据<br />
<br />
javabean：DataConn.java //连接数据库<br />
<br />
javabean:GetCount.java //获得数据记录数<br />
<br />
DataConn.java文件内容：<br />
<br />
package aliang_org;<br />
import java.sql.*;<br />
public class DataConn{<br />
<br />
public static Connection getDataConn() {<br />
Connection conn = null;<br />
try {<br />
Class.forName(&quot;com.microsoft.jdbc.sqlserver.SQLServerDriver&quot;).newInstance();<br />
conn = DriverManager.getConnection(&quot;jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=your&quot;,&quot;your&quot;,&quot;your&quot;);<br />
}<br />
catch(Exception ex) {<br />
ex.printStackTrace();<br />
}<br />
return conn;<br />
}<br />
}<br />
<br />
GetCount .java文件内容:<br />
<br />
package aliang_org;<br />
import java.sql.*;<br />
import java.util.*;<br />
import java.io.*;<br />
<br />
public class GetCount {<br />
private Connection conn;<br />
public GetCount()throws Exception{<br />
conn = DataConn.getDataConn();<br />
}<br />
public int getCounter()throws Exception{<br />
int ret = 0;<br />
Statement stmt = conn.createStatement();<br />
ResultSet rset = stmt.executeQuery(&quot;select count(*) from UserInfos&quot;);<br />
while(rset.next()){<br />
ret = rset.getInt(1);<br />
}<br />
return ret;<br />
}<br />
}<br />
<br />
pagedata.jsp 文件内容:<br />
<br />
&lt;％@ page contentType=&quot;text/html; charset=gb2312&quot; language=&quot;java&quot;％&gt;<br />
&lt;％@ page import = &quot;aliang_org.*&quot;％&gt;<br />
&lt;％@ page import = &quot;java.util.*&quot;％&gt;<br />
&lt;％@ page import = &quot;java.io.*&quot;％&gt;<br />
&lt;％@ page import = &quot;java.sql.*&quot;％&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;<br />
jsp/JavaBean分页列出数据<br />
&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body bgcolor=&quot;#ffffff&quot;&gt;<br />
&lt;h1&gt;jsp/JavaBean分页列出数据&lt;/h1&gt;<br />
&lt;hr /&gt;<br />
&lt;jsp:useBean id=&quot;dataConnection&quot; class=&quot;aliang_org.DataConn&quot; scope=&quot;page&quot; /&gt;<br />
&lt;jsp:useBean id=&quot;getcounter&quot; class=&quot;aliang_org.GetCount&quot; scope=&quot;page&quot; /&gt;<br />
&lt;table width=&quot;100％&quot; border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;<br />
&lt;tr align=&quot;center&quot; bgcolor=&quot;#00FFFF&quot;&gt;<br />
&lt;td&gt;ID序号&lt;/td&gt;<br />
&lt;td&gt;用户名&lt;/td&gt;<br />
&lt;td&gt;密码&lt;/td&gt;<br />
&lt;td&gt;电子信箱&lt;/td&gt;<br />
&lt;td colspan=&quot;2&quot;&gt;操作选项&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;％<br />
int nowPages;//当前页<br />
int pages;//请求页数<br />
int countPerPage = 10 ; //每页显示条数<br />
int pageCount;//总页数<br />
int recordCount = getcounter.getCounter(); //recordCount为总记录数<br />
pageCount = (int)Math.ceil((recordCount + countPerPage-1) / countPerPage);//算出总页数<br />
<br />
//得到请求页<br />
if(request.getParameter(&quot;pages&quot;) == null){<br />
pages = 1;<br />
}else{<br />
pages = new Integer(request.getParameter(&quot;pages&quot;)).intValue();<br />
}<br />
//得到当前实际页面<br />
if(pages &gt; pageCount){<br />
nowPages = 1;<br />
}else{<br />
nowPages = pages;<br />
}<br />
//获取记录集<br />
Connection conn = dataConnection.getDataConn();<br />
ResultSet rs = conn.createStatement().executeQuery(&quot;Select top &quot;+ countPerPage +&quot; * from UserInfos where ID not in (select top &quot;+ (nowPages-1)*countPerPage +&quot; ID from UserInfos order by id desc) order by ID desc&quot;);<br />
while(rs.next()){<br />
int ID = rs.getInt(&quot;ID&quot;);<br />
String username = rs.getString(&quot;username&quot;);<br />
String password = rs.getString(&quot;password&quot;);<br />
String email = rs.getString(&quot;email&quot;);<br />
％&gt;<br />
&lt;tr&gt;<br />
&lt;td align=&quot;center&quot;&gt;&lt;％= ID ％&gt;&lt;/td&gt;<br />
&lt;td&gt;&lt;％= username ％&gt;&lt;/td&gt;<br />
&lt;td&gt;&lt;％= password ％&gt;&lt;/td&gt;<br />
&lt;td&gt;&lt;％= email ％&gt;&lt;/td&gt;<br />
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;modify.jsp?ID=&lt;％= ID ％&gt;&quot;&gt;修改&lt;/a&gt;&lt;/td&gt;<br />
&lt;td align=&quot;center&quot;&gt;&lt;a href=&quot;delete.jspID=&lt;％= ID ％&gt;&quot;&gt;删除&lt;/a&gt;&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;％<br />
}<br />
//关闭连接<br />
rs.close();<br />
conn.close();<br />
％&gt;<br />
&lt;form method=&quot;get&quot;&gt;<br />
&lt;tr align=&quot;right&quot;&gt;<br />
&lt;td colspan=&quot;6&quot;&gt;共有&lt;font color=red&gt;&lt;％= recordCount ％&gt;&lt;/font&gt;条记录&nbsp;当前&lt;font color=red&gt;&lt;％= nowPages ％&gt;/&lt;％= pageCount ％&gt;&lt;/font&gt;页&nbsp;<br />
&lt;％ if(pageCount &gt; 1){ ％&gt;<br />
&lt;％ if(pages &gt; 1){％&gt;<br />
&lt;a href=&quot;&quot;&gt;首页&lt;/a&gt;<br />
&lt;％}if(pages &lt; pageCount){％&gt;<br />
&lt;a href=&quot;?pages=&lt;％= nowPages+1 ％&gt;&quot;&gt;下一页&lt;/a&gt;<br />
&lt;％}if(pages != 1){％&gt;<br />
&lt;a href=&quot;?pages=&lt;％= nowPages - 1 ％&gt;&quot;&gt;上一页&lt;/a&gt;<br />
&lt;％}％&gt;<br />
&lt;a href=&quot;?pages=&lt;％= pageCount ％&gt;&quot;&gt;尾页&lt;/a&gt;<br />
&lt;％ } ％&gt;跳转到<br />
&lt;select name=&quot;pages&quot; onChange=&quot;javascript:this.form.submit();&quot;&gt;<br />
&lt;％ for(int i=1;i&lt;=pageCount;i++){％&gt;<br />
&lt;option value=&quot;&lt;％= i ％&gt;&quot; &lt;％ if(nowPages == i){％&gt;selected&lt;％ } ％&gt;&gt;&lt;％= i ％&gt;&lt;/option&gt;<br />
&lt;％ } ％&gt;<br />
&lt;/select&gt;页&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;/form&gt;<br />
&lt;/table&gt;<br />
&lt;hr /&gt;<br />
&copy; 2004 Aliang.org StartJAVA<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
<br />
<br />
还有不要忘了把sql-jdbc驱动安装了，并拷贝C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib文件夹到web目录下的WEB-INF下面。 <br />
</p>
<div>一个Oracle数据库链接的JavaBean实例考试大全<br />
<span id="ArticleContentArea">
<p>public class OracleConnectionManager {<br />
<br />
private DBConnectionManager connMgr;<br />
private final String poolName=&quot;Oracle&quot;;<br />
private Connection conn;<br />
<br />
public OracleConnectionManager() {<br />
<br />
String userID = &quot;system&quot;; <br />
String password = &quot;manager&quot;;<br />
String JDBCDriver = &quot;oracle.jdbc.driver.OracleDriver&quot;;<br />
String JDBCDriverType = &quot;jdbc:oracle:thin&quot;;<br />
String DBHost = &quot;127.0.0.1&quot;;<br />
String Port = &quot;1521&quot;;<br />
String SID=&quot;sid&quot;;<br />
String url = JDBCDriverType+&quot;:@&quot;+DBHost + &quot;:&quot; + Port + &quot;:&quot; +SID;<br />
<br />
<br />
connMgr = DBConnectionManager.getInstance();<br />
if (DBConnectionManager.clients == 1){<br />
connMgr.init(poolName, JDBCDriver, url, userID, password);<br />
connMgr.init(&quot;egongOracle&quot;, JDBCDriver, JDBCDriverType+&quot;:@110.7.6.22:1521:egong&quot;, &quot;abcusername&quot;, &quot;abcpasswd&quot;); <br />
<br />
<br />
} <br />
}<br />
<br />
public Connection getConnection() {<br />
return (conn=connMgr.getConnection(poolName));<br />
}<br />
<br />
public Connection getConnection(String newOracle) {<br />
return (conn=connMgr.getConnection(newOracle));<br />
}<br />
<br />
<br />
public void freeConnection() {<br />
connMgr.freeConnection(poolName,conn);<br />
}<br />
<br />
public void freeConnection(String newOracle) {<br />
connMgr.freeConnection(newOracle,conn);<br />
}<br />
<br />
}<br />
<br />
<br />
public class DBConnectionManager {<br />
static private DBConnectionManager instance=null; // The single instance<br />
static public int clients=0;<br />
<br />
private Vector drivers = new Vector();<br />
private PrintWriter log;<br />
private Hashtable pools = new Hashtable();<br />
private final int MAX_CONN = 1000;<br />
<br />
/**<br />
* Returns the single instance, creating one if it&acute;s the<br />
* first time this method is called.<br />
*<br />
* @return DBConnectionManager The single instance.<br />
*/<br />
static synchronized public DBConnectionManager getInstance() {<br />
if (instance == null) {<br />
instance = new DBConnectionManager();<br />
}<br />
clients++;<br />
return instance;<br />
}<br />
<br />
/**<br />
* A private constructor since this is a Singleton<br />
*/<br />
private DBConnectionManager() {<br />
// init();<br />
}<br />
<br />
/**<br />
* Returns a connection to the named pool.<br />
*<br />
* @param name The pool name as defined in the properties file<br />
* @param con The Connection<br />
*/<br />
public void freeConnection(String name, Connection con) {<br />
DBConnectionPool pool = (DBConnectionPool) pools.get(name);<br />
if (pool != null) {<br />
pool.freeConnection(con);<br />
}<br />
}<br />
<br />
/**<br />
* Returns an open connection. If no one is available, and the max<br />
* number of connections has not been reached, a new connection is<br />
* created.<br />
*<br />
* @param name The pool name as defined in the properties file<br />
* @return Connection The connection or null<br />
*/<br />
public Connection getConnection(String name) {<br />
DBConnectionPool pool = (DBConnectionPool) pools.get(name);<br />
if (pool != null) {<br />
return pool.getConnection();<br />
}<br />
return null;<br />
}[Page]<br />
<br />
/**<br />
* Returns an open connection. If no one is available, and the max<br />
* number of connections has not been reached, a new connection is<br />
* created. If the max number has been reached, waits until one<br />
* is available or the specified time has elapsed.<br />
*<br />
* @param name The pool name as defined in the properties file<br />
* @param time The number of milliseconds to wait<br />
* @return Connection The connection or null<br />
*/<br />
public Connection getConnection(String name, long time) {<br />
DBConnectionPool pool = (DBConnectionPool) pools.get(name);<br />
if (pool != null) {<br />
return pool.getConnection(time);<br />
}<br />
return null;<br />
}<br />
<br />
/**<br />
* Closes all open connections and deregisters all drivers.<br />
*/<br />
public synchronized void release() {<br />
// Wait until called by the last client<br />
if (--clients != 0) {<br />
return;<br />
}<br />
<br />
Enumeration allPools = pools.elements();<br />
while (allPools.hasMoreElements()) {<br />
DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();<br />
pool.release();<br />
}<br />
Enumeration allDrivers = drivers.elements();<br />
while (allDrivers.hasMoreElements()) {<br />
Driver driver = (Driver) allDrivers.nextElement();<br />
try {<br />
DriverManager.deregisterDriver(driver);<br />
log(&quot;Deregistered JDBC driver &quot; + driver.getClass().getName());<br />
}<br />
catch (SQLException e) {<br />
log(e, &quot;Can&acute;t deregister JDBC driver: &quot; + driver.getClass().getName());<br />
}<br />
}<br />
log.close();<br />
}<br />
<br />
/**<br />
* Creates instances of DBConnectionPool based on the properties.<br />
* A DBConnectionPool can be defined with the following properties:<br />
* &lt;PRE&gt;<br />
* &lt;poolname&gt;.url The JDBC URL for the database<br />
* &lt;poolname&gt;.user A database user (optional)<br />
* &lt;poolname&gt;.password A database user password (if user specified)<br />
* &lt;poolname&gt;.maxconn The maximal number of connections (optional)<br />
* &lt;/PRE&gt;<br />
*<br />
* @param props The connection pool properties<br />
*/<br />
private void createPools(String poolName, String url, String user, String password, int max) {<br />
/* <br />
Enumeration propNames = props.propertyNames();<br />
while (propNames.hasMoreElements()) {<br />
String name = (String) propNames.nextElement();<br />
if (name.endsWith(&quot;.url&quot;)) {<br />
String poolName = name.substring(0, name.lastIndexOf(&quot;.&quot;));<br />
String url = props.getProperty(poolName + &quot;.url&quot;);<br />
if (url == null) {<br />
log(&quot;No URL specified for &quot; + poolName);<br />
continue;<br />
}<br />
String user = props.getProperty(poolName + &quot;.user&quot;);<br />
String password = props.getProperty(poolName + &quot;.password&quot;);<br />
String maxconn = props.getProperty(poolName + &quot;.maxconn&quot;, &quot;0&quot;);<br />
int max;<br />
try {<br />
max = Integer.valueOf(maxconn).intValue();<br />
}<br />
catch (NumberFormatException e) {<br />
log(&quot;Invalid maxconn value &quot; + maxconn + &quot; for &quot; + poolName);<br />
max = 0;<br />
}<br />
DBConnectionPool pool = <br />
new DBConnectionPool(poolName, url, user, password, max);<br />
pools.put(poolName, pool);<br />
log(&quot;Initialized pool &quot; + poolName);<br />
}<br />
}<br />
*/ <br />
DBConnectionPool pool = <br />
new DBConnectionPool(poolName, url, user, password, max);<br />
pools.put(poolName, pool);<br />
log(&quot;Initialized pool &quot; + poolName);<br />
}<br />
<br />
public void init(String poolName, String driver, String url, String user, String passwd) {<br />
init(poolName, driver, url, user, passwd, MAX_CONN);<br />
}<br />
</p>
[Page]/**<br />
* Loads properties and initializes the instance with its values.<br />
*/<br />
public void init(String poolName, String driver, String url, String user, String passwd, int maxconn) {<br />
/* <br />
InputStream is = getClass().getResourceAsStream(&quot;/db.properties&quot;);<br />
Properties dbProps = new Properties();<br />
try {<br />
dbProps.load(is);<br />
}<br />
catch (Exception e) {<br />
System.err.println(&quot;Can&acute;t read the properties file. &quot; +<br />
&quot;Make sure db.properties is in the CLASSPATH&quot;);<br />
return;<br />
}<br />
String logFile = dbProps.getProperty(&quot;logfile&quot;, &quot;DBConnectionManager.log&quot;);<br />
<br />
String logFile = &quot;.&quot; + File.separator + &quot;logs&quot; + File.separator + &quot;dbpool&quot;; <br />
try {<br />
log = new PrintWriter(new FileWriter(logFile, true), true);<br />
}<br />
catch (IOException e) {<br />
System.err.println(&quot;Can&acute;t open the log file: &quot; + logFile);<br />
log = new PrintWriter(System.err);<br />
}<br />
*/ <br />
log = new PrintWriter(System.err);<br />
loadDrivers(driver);<br />
createPools(poolName, url, user, passwd, maxconn);<br />
}<br />
<br />
/**<br />
* Loads and registers all JDBC drivers. This is done by the<br />
* DBConnectionManager, as opposed to the DBConnectionPool,<br />
* since many pools may share the same driver.<br />
*<br />
* @param props The connection pool properties<br />
*/<br />
private void loadDrivers(String driverClassName) {<br />
/* <br />
String driverClasses = props.getProperty(&quot;drivers&quot;);<br />
StringTokenizer st = new StringTokenizer(driverClasses);<br />
while (st.hasMoreElements()) {<br />
String driverClassName = st.nextToken().trim();<br />
try {<br />
Driver driver = (Driver) <br />
Class.forName(driverClassName).newInstance();<br />
DriverManager.registerDriver(driver);<br />
drivers.addElement(driver);<br />
log(&quot;Registered JDBC driver &quot; + driverClassName);<br />
}<br />
catch (Exception e) {<br />
log(&quot;Can&acute;t register JDBC driver: &quot; +<br />
driverClassName + &quot;, Exception: &quot; + e);<br />
}<br />
}<br />
</span></div>
          <br/>
          <span style="color:red;">
            <a href="http://thomas0988.javaeye.com/blog/140060#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 12 Nov 2007 23:47:30 +0800</pubDate>
        <link>http://thomas0988.javaeye.com/blog/140060</link>
        <guid>http://thomas0988.javaeye.com/blog/140060</guid>
      </item>
      <item>
        <title>java map 介绍</title>
        <author>thomas0988</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://thomas0988.javaeye.com">thomas0988</a>&nbsp;
          链接：<a href="http://thomas0988.javaeye.com/blog/137789" style="color:red;">http://thomas0988.javaeye.com/blog/137789</a>&nbsp;
          发表时间: 2007年11月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h2><font size="1"><span class="topstoryhead">Java Map 集合类简介</span><br />
<span class="italicbodycopy">作者：Jack Shirazi</span> </font></h2>
<p><span class="boldbodycopy"><font size="1">了解最常用的集合类型之一 Map 的基础知识以及如何针对您应用程序特有的数据优化 Map。</font></span></p>
<h2>
<table border="0" bgcolor="#dddddd" width="25%" cellpadding="5">
    <tbody>
        <tr>
            <td>
            <p><font size="1"><span class="boldbodycopy">本文相关下载：</span><br />
            <span class="boldbodycopy">&middot;</span> </font><a href="http://www.oracle.com/technology/pub/files/hashmaps_part1.zip" target="_blank"><span class="bodylink"><font size="1">Jack 的 HashMap 测试</font></span></a><br />
            <font size="1"><span class="boldbodycopy">&middot;</span> </font><a href="http://www.oracle.com/go/?&amp;Src=1952635&amp;Act=33" target="_blank"><span class="bodylink"><font size="1">Oracle JDeveloper 10<em>g</em></font></span></a><font size="1"> </font></p>
            </td>
        </tr>
    </tbody>
</table>
</h2>
<p><font size="1"><br clear="all" />
</font></p>
<p><font size="1">&nbsp;</font></p>
<p><font size="1"><span class="bodycopy">java.util 中的集合类包含 Java 中某些最常用的类。 最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector，它们是可变大小的列表，比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。</span> </font></p>
<p><font size="1"><span class="bodycopy">Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对（称作&ldquo;键&rdquo;和&ldquo;值&rdquo;），其中每个键映射到一个值。 从概念上而言，您可以将 List 看作是具有数值键的 Map。 而实际上，除了 List 和 Map 都在定义 java.util 中外，两者并没有直接的联系。本文将着重介绍核心 Java 发行套件中附带的 Map，同时还将介绍如何采用或实现更适用于您应用程序特定数据的专用 Map。</span> </font></p>
<p><font size="1"><span class="parahead1">了解 Map 接口和方法</span> </font></p>
<p><span class="bodycopy"><font size="1">Java 核心类中有很多预定义的 Map 类。 在介绍具体实现之前，我们先介绍一下 Map 接口本身，以便了解所有实现的共同点。 Map 接口定义了四种类型的方法，每个 Map 都包含这些方法。 下面，我们从两个普通的方法（</font><a href="http://www.oracle.com/technology/global/cn/pub/articles/maps1.html#T1"><span class="bodylink"><font size="1">表 1</font></span></a><font size="1">）开始对这些方法加以介绍。</font></span><font size="1"> </font></p>
<p><font size="1"><span class="italicbodycopy"><a name="T1"></a>表 1： 覆盖的方法。 我们将这 Object 的这两个方法覆盖，以正确比较 Map 对象的等价性。</span> </font></p>
<h2>
<table border="1" vspace="5" align="center" hspace="5" bgcolor="#dddddd" width="100%" cellpadding="5">
    <tbody>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">equals(Object o)</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">比较指定对象与此 Map 的等价性</font></span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">hashCode()</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">返回此 Map 的哈希码</font></span></p>
            </td>
        </tr>
    </tbody>
</table>
</h2>
<p><font size="1">&nbsp;</font></p>
<p><font size="1"><span class="boldbodycopy">Map 构建</span> </font></p>
<p><span class="bodycopy"><font size="1">Map 定义了几个用于插入和删除元素的变换方法（</font><a href="http://www.oracle.com/technology/global/cn/pub/articles/maps1.html#T2"><span class="bodylink"><font size="1">表 2</font></span></a><font size="1">）。</font></span><font size="1"> </font></p>
<p><font size="1"><span class="italicbodycopy"><a name="T2"></a>表 2： Map 更新方法： 可以更改 Map 内容。</span> </font></p>
<h2>
<table border="1" vspace="5" align="center" hspace="5" bgcolor="#dddddd" width="100%" cellpadding="5">
    <tbody>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">clear()</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">从 Map 中删除所有映射</font></span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">remove(Object key)</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">从 Map 中删除键和关联的值</font></span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">put(Object key, Object value)</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">将指定值与指定键相关联</font></span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">clear()</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">从 Map 中删除所有映射</font></span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p><span class="bodycopy"><font size="1">putAll(Map t)</font></span></p>
            </td>
            <td>
            <p><span class="bodycopy"><font size="1">将指定 Map 中的所有映射复制到此 map</font></span></p>
            </td>
        </tr>
    </tbody>
</table>
</h2>
<p><font size="1">&nbsp;</font></p>
<p><font size="1"><span class="bodycopy">尽管您可能注意到，纵然假设忽略构建一个需要传递给 putAll() 的 Map 的开销，使用 putAll() 通常也并不比使用大量的 put() 调用更有效率，但 putAll() 的存在一点也不稀奇。 这是因为，putAll() 除了迭代 put() 所执行的将每个键值对添加到 Map 的算法以外，还需要迭代所传递的 Map 的元素。 但应注意，putAll() 在添加所有元素之前可以正确调整 Map 的大小，因此如果您未亲自调整 Map 的大小（我们将对此进行简单介绍），则 putAll() 可能比预期的更有效。</span> </font></p>
<p><font size="1"><span class="boldbodycopy">查看 Map</span> </font></p>
<p><span class="bodycopy"><font size="1">迭代 Map 中的元素不存在直接了当的方法。 如果要查询某个 Map 以了解其哪些元素满足特定查询，或如果要迭代其所有元素（无论原因如何），则您首先需要获取该 Map 的&ldquo;视图&rdquo;。 有三种可能的视图（参见</font><a href="http://www.oracle.com/technology/global/cn/pub/articles/maps1.html#T3"><span class="bodylink"><font size="1">表 3</font></span></a><font size="1">）</font></span><font size="1"> </font></p>
<ul>
    <li><font size="1"><span class="bodycopy">所有键值对 &mdash; 参见 entrySet()</span> </font></li>
    <li><font size="1"><span class="bodycopy">所有键 &mdash; 参见 keySet()</span> </font></li>
    <li><font size="1"><span class="bodycopy">所有值 &mdash; 参见 values()</span> </font></li>
</ul>
<p><font size="1">&nbsp;</font></p>
<p><font size="1"><span class="bodycopy">前两个视图均返回 Set 对象，第三个视图返回 Collection 对象。 就这两种情况而言，问题到这里并没有结束，这是因为您无法直接迭代 Collection 对象或 Set 对象。要进行迭代，您必须获得一个 Iterator 对象。 因此，要迭代 Map 的元素，必须进行比较烦琐的编码</span> </font></p>
<p><font size="1">&nbsp;</font></p>
<p>