﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Sealyu-随笔分类-Eclipse SWT/JFace RCP</title><link>http://www.blogjava.net/sealyu/category/30672.html</link><description>--- The devil's in the Details</description><language>zh-cn</language><lastBuildDate>Fri, 11 Jun 2010 18:18:23 GMT</lastBuildDate><pubDate>Fri, 11 Jun 2010 18:18:23 GMT</pubDate><ttl>60</ttl><item><title>Eclipse 中 将Java Project 转换为Dynamic Web Project（转）</title><link>http://www.blogjava.net/sealyu/archive/2009/10/15/298346.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 15 Oct 2009 03:17:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/10/15/298346.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/298346.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/10/15/298346.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/298346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/298346.html</trackback:ping><description><![CDATA[接手一个前期的Web项目，当时是用MyEclipse建立的，用MyEclipse发布运行没有任何问题。<br />
现在因为没有购买MyEclipse的年费，决定用EclipsE+WPT继续开发，没想到在WPT的Server中发现不了该项目，于是使用下面的方法将其转换为WPT能识别的项目。<br />
1. 修改项目的.project文件，保存，不记得是否需要重启Eclipse了。<br />
&nbsp;&nbsp;&nbsp; 在&lt;natures&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/natures&gt;
<p>之间添加下列三行配置  </p>
<p>&lt;nature&gt;org.eclipse.wst.common.project.facet.core.nature&lt;/nature&gt;<br />
&lt;nature&gt;org.eclipse.wst.common.modulecore.ModuleCoreNature&lt;/nature&gt;<br />
&lt;nature&gt;org.eclipse.jem.workbench.JavaEMFNature&lt;/nature&gt;  </p>
<p>2. 在Eclipse中打开&#8220;project properties"，会看到新增了很多选择项，点中"Project Facets",按下图配置：</p>
<p><img alt="" src="../../images/blogjava_net/vcok/convert2Web.jpg" height="651" width="814" /></p>
3. 项目即可成为一个被WPT识别的项目。
<img src ="http://www.blogjava.net/sealyu/aggbug/298346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-10-15 11:17 <a href="http://www.blogjava.net/sealyu/archive/2009/10/15/298346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ubuntu 8.04下的eclipse与scim输入法冲突解决办法(转)</title><link>http://www.blogjava.net/sealyu/archive/2009/04/20/266500.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Mon, 20 Apr 2009 02:20:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/04/20/266500.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/266500.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/04/20/266500.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/266500.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/266500.html</trackback:ping><description><![CDATA[<div>
<pre>
<p>最近把系统升级到8.04，整个安装配置过程越来越简单，一切都比较顺利，最后在eclipse与scim之间卡住了。我安装的是英文环境，locale是en_US.UTF-8，同样的方法在8.04之前版本是正常的，Linux就是Linux。下面是本人scim输入法的安装配置过程，根据个人经验，不一定能够完全解决所有人遇到的同样问题，仅供参考。</p>
<br />
<br />
<p>1、安装scim智能拼音输入法<br />
sudo apt-get install scim-pinyin im-switch</p>
<br />
<br />
<p>2、接着把系统默认的输入法设置为scim<br />
sudo im-switch -s scim</p>
<br />
<p>结果设置失败，系统反馈：</p>
<br />
<p>update-alternatives: Cannot find alternative `/etc/X11/xinit/xinput.d/scim'.</p>
<br />
<br />
<p>3、然后以普通用户身份设置（新手朋友注意没有sudo了）</p>
<br />
<p>im-switch -s scim</p>
<br />
<p>设置成功，Firefox,GEdit都默认使用了scim作为首选输入法，但是在eclise中则不是，在默认情况下，在eclipse编辑器里面不能输入任何字符（包括中文或英文）。只有鼠标右键选择Input Methods -&gt; SCIM input Method之后，才可以正常输入，虽然这样也能解决问题，但是太多人性了，Google一把，找到解决办法。</p>
<br />
<br />
<p>4、修改scim配置</p>
<br />
<p>sudo /etc/X11/xinit/xinput.d/scim</p>
<br />
<p>将GTK_IM_MODULE=scim中的xim修改为scim，保存并退出。</p>
<br />
<br />
<p>5、再次设置系统默认的输入法为scim</p>
<br />
<p>sudo update-alternatives --install /etc/X11/xinit/xinput.d/all_ALL xinput-all_ALL /etc/X11/xinit/xinput.d/scim 30 <br />
sudo im-switch -s scim</p>
<br />
<br />
<p>重启eclipse，一切正常，大功告成。</p>
</pre>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/266500.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-04-20 10:20 <a href="http://www.blogjava.net/sealyu/archive/2009/04/20/266500.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse自动生成注释（转）</title><link>http://www.blogjava.net/sealyu/archive/2009/03/26/262238.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 26 Mar 2009 13:28:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/03/26/262238.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/262238.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/03/26/262238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/262238.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/262238.html</trackback:ping><description><![CDATA[windows--&gt;preference<br />
Java--&gt;Code Style--&gt;Code Templates<br />
code--&gt;new Java files
<p>编辑它</p>
${filecomment}<br />
${package_declaration}<br />
/**<br />
* @author 作者 E-mail:<br />
* @version 创建时间：${date} ${time}<br />
* 类说明<br />
*/<br />
${typecomment}<br />
${type_declaration}
<img src ="http://www.blogjava.net/sealyu/aggbug/262238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-03-26 21:28 <a href="http://www.blogjava.net/sealyu/archive/2009/03/26/262238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse中jboss启动时提示 50 seconds. 超时 (转)</title><link>http://www.blogjava.net/sealyu/archive/2009/03/26/262024.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 26 Mar 2009 01:51:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/03/26/262024.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/262024.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/03/26/262024.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/262024.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/262024.html</trackback:ping><description><![CDATA[<div>
<p>eclipse中jboss启动时提示</p>
<p>Server JBoss v4.2 at localhost was unable to start within 50 seconds.<br />
If the server requires more time, try increasing the timeout in the server editor.</p>
<p>解决办法</p>
<p>修改 </p>
<p>workspace".metadata".plugins"org.eclipse.wst.server.core"servers.xml<br />
<br />
&lt;server auto-publish-setting="1" hostname="localhost" id="JBoss v4.2
at localhost" name="JBoss v4.2 at localhost" runtime-id="JBoss v4.2"
server-type="org.eclipse.jst.server.generic.jboss42"
server-type-id="org.eclipse.jst.server.generic.jboss42"
start-timeout="50" stop-timeout="15" timestamp="7"&gt;<br />
<br />
把 start-timeout="50" 改为&nbsp; start-timeout="500000"<br />
<br />
重启eclipse就可以了</p>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/262024.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-03-26 09:51 <a href="http://www.blogjava.net/sealyu/archive/2009/03/26/262024.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse 中boolean型变量自动生成Setter、Getter方法的问题</title><link>http://www.blogjava.net/sealyu/archive/2009/02/17/255042.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Tue, 17 Feb 2009 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/02/17/255042.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/255042.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/02/17/255042.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/255042.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/255042.html</trackback:ping><description><![CDATA[今天在使用eclipse自动生成Setter/Getter方法时发现， 如果一个布尔型变量命名以&#8220;is&#8221;开头的话，自动生成的Setter/Getter方法中会将&#8220;is&#8221;自动去掉，例如：<br />
变量：isRequestable，<br />
生成的变量就会为：<br />
&nbsp;&nbsp;&nbsp; public boolean isRequestable() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return isRequestable;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void setRequestable(boolean isRequestable) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;this.isRequestable = isRequestable;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
结果我在使用seam的时候，上下文绑定就出了问题。提示找不到isRequestable这个property.<br />
在代码中自动生成之后，手动将之改写为：<br />
&nbsp;&nbsp;&nbsp; public boolean isIsRequestable() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return isRequestable;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void setIsRequestable(boolean isRequestable) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;this.isRequestable = isRequestable;<br />
&nbsp;&nbsp; &nbsp;}<br />
问题就解决了<br />
<br />
另外，还有一个问题，就是变量名如果是第一个为小写字母，第二个为大写字母，也会出错，例如：eOrder,<br />
这样在生成Setter/Getter方法时也会提示找不到变量。所以将变量改名，然后JPA注释的时候映射一下就可以了。<br />
<img src ="http://www.blogjava.net/sealyu/aggbug/255042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-02-17 11:08 <a href="http://www.blogjava.net/sealyu/archive/2009/02/17/255042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse中设置tab size</title><link>http://www.blogjava.net/sealyu/archive/2009/02/17/255028.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Tue, 17 Feb 2009 01:52:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/02/17/255028.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/255028.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/02/17/255028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/255028.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/255028.html</trackback:ping><description><![CDATA[<div>
<p><font face="Verdana">1：window——preference——General——Editor——Text Editor设置页面：Display Tab Width </font></p>
<p><font face="Verdana">2：window——preference——Java——Code Style——Formatter设置页面，Edit，在弹出的Editor profile窗口中，Indentation卡片，设置Indentation Size和Tab Size。 </font></p>
<p><font face="Verdana">3：如果安装了Myeclipse，那么在window——preference——Myeclipse——Editor——Common Editor Preference中Apperance卡片，设置Tab Size。 </font></p>
<p><font face="Verdana">对Java文件，第2中是可行的。设置1、3没有用</font></p>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/255028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-02-17 09:52 <a href="http://www.blogjava.net/sealyu/archive/2009/02/17/255028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclicpse3.1.1下配置SWT，打包发布SWT程序，转EXE（转载）</title><link>http://www.blogjava.net/sealyu/archive/2008/04/10/192003.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 10 Apr 2008 14:43:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/04/10/192003.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/192003.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/04/10/192003.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/192003.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/192003.html</trackback:ping><description><![CDATA[<h4 id="subjcns!ee52cc79737cf30e!346" style="margin-bottom: 0px;">Eclicpse3.1.1下配置SWT，打包发布SWT程序，转EXE一条龙过程记录</h4>
<div id="msgcns!ee52cc79737cf30e!346">
<div>一<strong>Eclipse</strong>下安装<strong>SWT</strong></div>
<div>1.到<a href="http://www.eclipse.xn--orgswt-dp7iia0091m./">www.eclipse.org上下载SWT.</a></div>
<div>我这里用的是1.1.0.1，并且页面上就有推荐的Eclipse3.1.1，EMF,GEF。都下载了！</div>
<div>2.按照<strong>Eclipse</strong>安装插件的方法，安装<strong>SWT</strong>,EMF,GEF。</div>
<div>3.如果不出意外，就可以正常使用了！</div>
<div>这里有一个建议：最好使用纯的Eclipse，我开始用WTP版的，怎么配置也不行。</div>
<div>可以建立Visual Class，但是不能可视化添加控件，或者看不到控件的属性，或者Text,TextArea控件无法添加。后来按照以上方法，重新来了一次，OK了!</div>
<div>二打包发布<strong>SWT</strong>程序</div>
<div>1.因为需要<strong>SWT</strong>的<strong>jar</strong>.但是Eclipse3.1.1配合的的SWT不是通过<strong>SWT.jar</strong>发布的！是org.eclipse.swt.win32.win32.x86_3.1.0.jar。里面包括了JINI的DLL和<strong>SWT</strong>类文件。</div>
<div>需要下载</div>
<div><a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.1.1-200509290840/swt-3.1.1-win32-win32-x86.zip">http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.1.1-200509290840/swt-3.1.1-win32-win32-x86.zip</a></div>
<div>这里有<strong>SWT.jar</strong>，和3个DLL,把他们解压缩出来，备用！</div>
<div>2.通过<strong>Eclipse</strong>的导出功能，生成一个<strong>可执行的jar</strong>，MANIFEST.MF文件选择由<strong>Eclipse</strong>生成，并且保存到项目中。</div>
<div>3.上面2的步骤，只是为了得到<strong>MANIFEST.MF</strong>文件。下面修改一下这个文件。</div>
<div>加上 Class-Path SWT.jar</div>
<div>如果还有其他的jar,用空格分开，加到后面</div>
<div>4.再生成一次jar,<strong>MANIFEST.MF</strong>选择修改后的。</div>
<div>5.将打包的jar,<strong>SWT.jar</strong>,3个DLL放到一个文件夹下，双击可执行的jar，程序运行！</div>
<div>三jar转EXE</div>
<div>1.打开<strong>JSmooth</strong>0.9.7。</div>
<div>2.选择skeleton,在skeleton properties中先把Launch java app in the exe process,Debug console选中。可以查看生成EXE文件执行过程信息。</div>
<div>3.选择Executable.</div>
<div>选择生成的EXE文件存放位置。</div>
<div>选择EXE文件图标</div>
<div>设置当前路径，选择要转换的jar文件所在文件夹</div>
<div>4.选择Application</div>
<div>设置Main Class,可执行jar中的Main Class注意写类全名</div>
<div>设置Application Argument,如果需要传入参数，写到这里</div>
<div>设置Embedded jar: 可执行的jar</div>
<div>设置Classpath：SWT.jar 如果有其他的继续添加</div>
<div>5.选择JVM Selection。默认吧。</div>
<div>6.JVM Configuration:</div>
<div>可以设置java properties,内存使用</div>
<div>7.点齿轮。生成！看是否有错误。</div>
<div>8.EXE执行需要的文件：EXE,3个DLL，SWT.jar</div>
<div>把他们考到其他目录，一样可以执行！</div>
<div>9.去掉skeleton properties中的Launch java app in the exe process,Debug console选项。</div>
<div>重新生成。应该OK了！</div>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/192003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-04-10 22:43 <a href="http://www.blogjava.net/sealyu/archive/2008/04/10/192003.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用SWT模拟鼠标键盘事件</title><link>http://www.blogjava.net/sealyu/archive/2008/04/10/192001.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 10 Apr 2008 14:42:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/04/10/192001.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/192001.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/04/10/192001.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/192001.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/192001.html</trackback:ping><description><![CDATA[<h3>最近在学习SWT/JFace，在做一个小东西的时候需要模拟鼠标键盘事件，在网上搜了一下，在java中模拟这些事件，主要有两种方法：</h3>
<h4>一、使用AWT中的Robot类</h4>
<h2>Robot</h2>
<pre><a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Object.html">java.lang.Object</a>
<img alt="继承者 " src="file:///C:/Documents%20and%20Settings/yuhaibo/My%20Documents/Robot%20%28Java%202%20Platform%20SE%205_0%29.files/inherit.gif" /><strong>java.awt.Robot</strong>
</pre>
<h5>
<hr />
</h5>
<dl><dt>
<pre>public class <strong>Robot</strong><dt>extends <a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Object.html">Object</a></dt></pre>
</dt></dl>
<h5>此类用于为测试自动化、自运行演示程序和其他需要控制鼠标和键盘的应用程序生成本机系统输入事件。Robot 的主要目的是便于 Java 平台实现自动测试。类中几个主要的模拟函数如下：</h5>
<div>
<table summary="" border="1" cellpadding="3" cellspacing="0" width="100%">
    <tbody>
        <tr bgcolor="white">
            <td align="right" valign="top" width="1%"><font size="-1"><code>void</code></font></td>
            <td><code><strong><a href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/awt/Robot.html#keyPress%28int%29">keyPress</a></strong>(int&nbsp;keycode)</code> <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;按下给定的键。</td>
        </tr>
        <tr bgcolor="white">
            <td align="right" valign="top" width="1%"><font size="-1"><code>&nbsp;void</code></font></td>
            <td><code><strong><a href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/awt/Robot.html#keyRelease%28int%29">keyRelease</a></strong>(int&nbsp;keycode)</code> <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;释放给定的键。</td>
        </tr>
        <tr bgcolor="white">
            <td align="right" valign="top" width="1%"><font size="-1"><code>&nbsp;void</code></font></td>
            <td><code><strong><a href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/awt/Robot.html#mouseMove%28int,%20int%29">mouseMove</a></strong>(int&nbsp;x, int&nbsp;y)</code> <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将鼠标指针移动到给定屏幕坐标。</td>
        </tr>
        <tr bgcolor="white">
            <td align="right" valign="top" width="1%"><font size="-1"><code>&nbsp;void</code></font></td>
            <td><code><strong><a href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/awt/Robot.html#mousePress%28int%29">mousePress</a></strong>(int&nbsp;buttons)</code> <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;按下一个或多个鼠标按钮。</td>
        </tr>
        <tr bgcolor="white">
            <td align="right" valign="top" width="1%"><font size="-1"><code>&nbsp;void</code></font></td>
            <td><code><strong><a href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/awt/Robot.html#mouseRelease%28int%29">mouseRelease</a></strong>(int&nbsp;buttons)</code> <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;释放一个或多个鼠标按钮。</td>
        </tr>
        <tr bgcolor="white">
            <td align="right" valign="top" width="1%"><font size="-1"><code>&nbsp;void</code></font></td>
            <td><code><strong><a href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/awt/Robot.html#mouseWheel%28int%29">mouseWheel</a></strong>(int&nbsp;wheelAmt)</code> <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在配有滚轮的鼠标上旋转滚轮。</td>
        </tr>
    </tbody>
</table>
</div>
<div><strong>二、使用SWT中的鼠标键盘事件</strong>
<div>&nbsp;&nbsp;&nbsp; 在SWT的snippets中有两个例子用来介绍这两个方法的使用，如下：</div>
<div><br />
(1)、模拟鼠标事件<br />
&nbsp;* UI Automation (for testing tools) snippet: post mouse events<br />
import org.eclipse.swt.*;</div>
<div>public class Snippet142 {</div>
<div>public static void main(String[] args) {<br />
&nbsp;final Display display = new Display();<br />
&nbsp;final Shell shell = new Shell(display);<br />
&nbsp;final Button button = new Button(shell,SWT.NONE);<br />
&nbsp;button.setSize(100,100);<br />
&nbsp;button.setText("Click");<br />
&nbsp;shell.pack();<br />
&nbsp;shell.open();<br />
&nbsp;button.addListener(SWT.MouseDown, new Listener() {<br />
&nbsp;&nbsp;public void handleEvent(Event e){<br />
&nbsp;&nbsp;&nbsp;System.out.println("Mouse Down (button: " + e.button + " x: " + e.x + " y: " + e.y + ")");<br />
&nbsp;&nbsp;}<br />
&nbsp;});<br />
&nbsp;final Point pt = display.map(shell, null, 50, 50);<br />
&nbsp;new Thread(){<br />
&nbsp;&nbsp;Event event;<br />
&nbsp;&nbsp;public void run(){<br />
&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(300);<br />
&nbsp;&nbsp;&nbsp;} catch (InterruptedException e) {}<br />
&nbsp;&nbsp;&nbsp;event = new Event();<br />
&nbsp;&nbsp;&nbsp;event.type = SWT.MouseMove;<br />
&nbsp;&nbsp;&nbsp;event.x = pt.x;<br />
&nbsp;&nbsp;&nbsp;event.y = pt.y;<br />
&nbsp;&nbsp;&nbsp;display.post(event);<br />
&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(300);<br />
&nbsp;&nbsp;&nbsp;} catch (InterruptedException e) {}<br />
&nbsp;&nbsp;&nbsp;event.type = SWT.MouseDown;<br />
&nbsp;&nbsp;&nbsp;event.button = 1;<br />
&nbsp;&nbsp;&nbsp;display.post(event);<br />
&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(300);<br />
&nbsp;&nbsp;&nbsp;} catch (InterruptedException e) {}<br />
&nbsp;&nbsp;&nbsp;event.type = SWT.MouseUp;<br />
&nbsp;&nbsp;&nbsp;display.post(event);<br />
&nbsp;&nbsp;}&nbsp;<br />
&nbsp;}.start();<br />
&nbsp;while (!shell.isDisposed()) {<br />
&nbsp;&nbsp;if (!display.readAndDispatch()) display.sleep();<br />
&nbsp;}<br />
&nbsp;display.dispose();<br />
}<br />
}<br />
(2)、模拟键盘事件</div>
<div><br />
&nbsp;* UI Automation (for testing tools) snippet: post key events<br />
import org.eclipse.swt.*;</div>
<div>public class Snippet146 {</div>
<div>public static void main(String[] args) {<br />
&nbsp;final Display display = new Display();<br />
&nbsp;final Shell shell = new Shell(display);<br />
&nbsp;final Text text = new Text(shell, SWT.BORDER);<br />
&nbsp;text.setSize(text.computeSize(150, SWT.DEFAULT));<br />
&nbsp;shell.pack();<br />
&nbsp;shell.open();<br />
&nbsp;new Thread(){<br />
&nbsp;&nbsp;public void run(){<br />
&nbsp;&nbsp;&nbsp;String string = "Love the method.";<br />
&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; string.length(); i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;char ch = string.charAt(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;boolean shift = Character.isUpperCase(ch);<br />
&nbsp;&nbsp;&nbsp;&nbsp;ch = Character.toLowerCase(ch);<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (shift) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Event event = new Event();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.type = SWT.KeyDown;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.keyCode = SWT.SHIFT;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display.post(event);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;Event event = new Event();<br />
&nbsp;&nbsp;&nbsp;&nbsp;event.type = SWT.KeyDown;<br />
&nbsp;&nbsp;&nbsp;&nbsp;event.character = ch;<br />
&nbsp;&nbsp;&nbsp;&nbsp;display.post(event);<br />
&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(10);<br />
&nbsp;&nbsp;&nbsp;&nbsp;} catch (InterruptedException e) {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;event.type = SWT.KeyUp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;display.post(event);<br />
&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(100);<br />
&nbsp;&nbsp;&nbsp;&nbsp;} catch (InterruptedException e) {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (shift) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event = new Event();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.type = SWT.KeyUp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.keyCode = SWT.SHIFT;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display.post(event);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}&nbsp;<br />
&nbsp;}.start();<br />
&nbsp;while (!shell.isDisposed()) {<br />
&nbsp;&nbsp;if (!display.readAndDispatch()) display.sleep();<br />
&nbsp;}<br />
&nbsp;display.dispose();<br />
}<br />
}<br />
</div>
<div>两种方法中都是先声明一个Event，然后将该Event的type类型设置为对应的
SWT.KeyUp/KeyDown/MouseUp/MouseDown，最后通过Display类的post（Event）方法来模拟对应的事件。注
意：如果有多个控件，需要得到对应控件的display属性，然后post该事件。例如，在一个窗口中有一个Browser，则需要使用
thisClass.browser.getDisplay().post(event)。</div>
</div>
<table>
    <tbody>
        <tr>
            <td><br />
            </td>
        </tr>
    </tbody>
</table>
<script type="text/javascript"><!--
google_ad_client = "pub-6625678643128649";
google_alternate_color = "FFFFFF";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
google_ad_channel ="";
//--></script>
<img src ="http://www.blogjava.net/sealyu/aggbug/192001.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-04-10 22:42 <a href="http://www.blogjava.net/sealyu/archive/2008/04/10/192001.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SWT：实现自我绘制的Button组件（转载）</title><link>http://www.blogjava.net/sealyu/archive/2008/04/10/192000.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 10 Apr 2008 14:41:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/04/10/192000.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/192000.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/04/10/192000.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/192000.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/192000.html</trackback:ping><description><![CDATA[在所有SWT组件中，Button几乎是最常用的，其功能在对于一般的情况来说也足够丰富了。你可以为Button组件设置要显示在其中的文本或者图像、设定ToolTip，甚至只要修改一个风格样式就能得到一个看上去相当不错的方向箭头按钮。 <br />
<br />
然而，我对Button组件还是不能感到满意。最大的遗憾就是：对它的外观，所能做的工作也就仅限于此了。如果你想让按钮拥有一个漂亮的、渐变色的背景和一些特殊的文字效果，怎么办呢？答案是没有办法。Button类里面似乎没有任何方法提供我想要的功能。<br />
<br />
我曾尝试过的第一个想法是用Button.addPaintListener来修改按钮的外观。但是，结果令人失望——虽然它显示出来的时候的确按照预
想进行绘制了，但是当你用鼠标去按它的时候，马上又变回了原本灰头土脸的样子。显然，在按下按钮的时候，它并不是触发paint事件，而是按照自己的想法
画出原本的按钮，于是我的工作全部白费了。<br />
<br />
如果尝试为按钮设定图像会怎么样呢？这也不是一个好主意。首先，不管你选择什么样的图像，
都没办法去掉按钮四周的边框，而正是这些边框严重破坏了图像的和谐感；其次，如果你的程序有几十甚至上百个按钮，为每个按钮都维护一幅图像（甚至更多——
理论上每个按钮在普通状态和被按下、禁用的状态下，甚至当鼠标移进移出按钮的时候，都应当显示不同的图像）明显是在浪费系统资源；如果你们的美工听说需要
做几百个图片，大概也不会给你好脸色看。此外，图像有一个严重的缺点是：它所拥有的像素数目是固定的，难以随着界面的放大和缩小同时变化。如果强制进行缩
放的话，会出现明显的锯齿和失真，最终让你精心设计的窗口变得惨不忍睹。最好还是放弃这个想法。<br />
<br />
如果以Canvas为基础，设计一个
伪装的按钮组件又如何呢？听起来好像很不错，因为采用这种办法的话，我们对如何绘制组件的表面就有了完整的控制权。不过这也意味着你必须对按钮的状态进行
手工维护。虽然Button本身是一个很简单的组件，但是重复去做标准按钮已经作好的工作似乎还是有点无谓。还有一件事情是应当考虑的：我们知道，
JFace中的Action机制可以将标准按钮、菜单项和工具栏按钮这三种界面组件纳入一个统一的事件处理体系。然而，如果我们从Canvas派生去模拟
一个按钮的话，不论你模拟到多么相似的地步，它毕竟不是一个真正的Button，Action也不会给它同等的待遇。也就是说手工制作的按钮无法和
JFace Action体系协同工作——除非你去修改Action的处理方法，让它去接纳新的按钮对象。这可不是一件轻松的工作。<br />
<br />
如果上面的方法都行不通的话，应当怎么办呢？我们知道，和Swing这样的框架不同，SWT中的按钮其实就是操作系统底层所实现的按钮（这一点也可以用
SPY++或者Winsight32之类的工具证实）。同时我们也知道，操作系统——至少是Windows系统，对按钮已经提供了自我绘制的机制，这就是
所谓的Owner
Draw（称为所有者绘制的原因是因为默认情况下绘制消息是发送给按钮的父窗口处理的，但是父窗口也可以把这个皮球再踢回给按钮，让它自己解决）。在
Win32
API中，凡是使用BS_OWNERDRAW风格创建、并且能够（通过消息反射）响应WS_DRAWITEM消息的按钮，都可以获得这种定制的能力。
了解这一点，接下来的任务就是研究Button组件有没有开放这个接口供我们修改了。对Button组件的源代码进行粗略的浏览后，我发现了如下的方法：<br />
<br />
<table width="90%" align="center" bgcolor="#e7e9e9" border="1" bordercolor="#cccccc">
    <tbody>
        <tr>
            <td>package org.eclipse.swt.widgets;<br />
            <br />
            public class Button extends Control {<br />
            &#8230;<br />
            LRESULT wmDrawChild (int wParam, int lParam) {<br />
            if ((style &amp; SWT.ARROW) == 0) return super.wmDrawChild (wParam, lParam);<br />
            DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT ();<br />
            ....</td>
        </tr>
    </tbody>
</table>
<br />
其中DRAWITEMSTRUCT结构的出现是一个明显的提示：这里就是WM_DRAWITEM消息的响应函数，很幸运它没有声明为final的，只要重载它并提供自己的实现就行了。<br />
<br />
看起来是个小case，实际上也是。不过，还有一处小麻烦需要克服。注意wmDrawChild方法没有使用任何访问限定符，这意味着它是
package
friendly的——同一个包中的对象可以访问和重载此方法，其他包中的对象就没有这个权力了。也就是说，要定制按钮对象，我们新建的对象也需要放在同
一个包（org.eclipse.swt.widgets）中。看起来有点像在使用Hack手段，不过为了突破SWT给我们的限制，眼下也只好稍稍将就一
下。好在swt的包没有密封（Sealed），不然我就不得不再次宣称此路不通了。<br />
<br />
既然障碍已经扫清，接下来我们可以来实现前面的想
法了。这里我做了一个决定，在上述包中只加入一个抽象类，目的是把必要的接口暴露出来；至于如何绘制按钮，则留给具体的按钮对象根据应用程序的需求来决
定。这样，不管你希望实现Windows
XP风格的按钮、还是卡通风格的按钮、或是平面样式的，总之不论什么千奇百怪的风格，只要继承一个类并重载一个绘制方法就行了，而不必每次都要和
Button类的内部打交道。<br />
<br />
基于这种考虑，实现自绘按钮的抽象类如下：<br />
<br />
<table width="90%" align="center" bgcolor="#e7e9e9" border="1" bordercolor="#cccccc">
    <tbody>
        <tr>
            <td>package org.eclipse.swt.widgets;<br />
            <br />
            import org.eclipse.swt.internal.win32.*;<br />
            <br />
            public abstract class OwnerDrawButton extends Button<br />
            {<br />
            public OwnerDrawButton( Composite parent, int style )<br />
            {<br />
            super( parent, style );<br />
            <br />
            int osStyle = OS.GetWindowLong( handle, OS.GWL_STYLE );<br />
            osStyle |= OS.BS_OWNERDRAW;<br />
            OS.SetWindowLong( handle, OS.GWL_STYLE, osStyle );<br />
            }<br />
            <br />
            LRESULT wmDrawChild( int wParam, int lParam )<br />
            {<br />
            super.wmDrawChild( wParam, lParam );<br />
            DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT();<br />
            OS.MoveMemory( struct, lParam, DRAWITEMSTRUCT.sizeof );<br />
            ownerDraw( struct );<br />
            return null;<br />
            }<br />
            <br />
            protected abstract void ownerDraw( DRAWITEMSTRUCT dis );<br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
注意这个抽象类所作的工作。在构造函数中，它调用操作系统方法为自己加入了BS_OWNERDRAW风格。如果没有这一步，那么操作系统将不
会把这个按钮视为自绘的按钮，也不会向其发送任何绘制消息。接下来是WM_DRAWITEM消息的响应函数。在这个函数中，我们简单的把必要的绘制参数提
取出来，然后调用抽象方法ownerDraw去进行实际的绘制工作。任何从OwnerDrawButton类派生的按钮对象必须重载此ownerDraw
方法，来决定如何绘制自身。<br />
作为一个例子，我实现了一个具体的按钮类。这个按钮用从上至下的渐变色背景添充整个按钮，然后绘制出按钮的文字。
如果当前按钮被按下，该类还调整了一下文字的位置，以显示出&#8220;按下&#8221;的外观效果。代码稍微有些长，这是因为消息函数所提供的是一个操作系统才了解的原生
HDC对象，而不是我们所熟悉的GC类，因此也需要相应的用原生API进行处理。不过，其原理是相当简单的——你只需要在给出的HDC上画出你想要的任何
效果就行了。<br />
<br />
<table width="90%" align="center" bgcolor="#e7e9e9" border="1" bordercolor="#cccccc">
    <tbody>
        <tr>
            <td>import org.eclipse.swt.SWT;<br />
            import org.eclipse.swt.graphics.*;<br />
            import org.eclipse.swt.internal.win32.*;<br />
            import org.eclipse.swt.widgets.*;<br />
            <br />
            public class TestButton extends OwnerDrawButton<br />
            {<br />
            TestButton( Composite parent )<br />
            {<br />
            super( parent, SWT.PUSH );<br />
            }<br />
            <br />
            @Override<br />
            protected void ownerDraw( DRAWITEMSTRUCT dis )<br />
            {<br />
            Rectangle rc = new Rectangle( dis.left, dis.top, dis.right - dis.left,dis.bottom - dis.top );<br />
            Color clr1 = new Color( getDisplay(), 0, 255, 128 );<br />
            Color clr2 = new Color( getDisplay(), 0, 128, 255 );<br />
            fillGradientRectangle( dis.hDC, rc, true, clr1, clr2 );<br />
            clr1.dispose();<br />
            clr2.dispose();<br />
            <br />
            SIZE size = new SIZE();<br />
            String text = getText();<br />
            char[] chars = text.toCharArray();<br />
            int oldFont = OS.SelectObject( dis.hDC, getFont().handle );<br />
            OS.GetTextExtentPoint32W( dis.hDC, chars, chars.length, size );<br />
            RECT rcText = new RECT();<br />
            rcText.left = rc.x;<br />
            rcText.top = rc.y;<br />
            rcText.right = rc.x + rc.width;<br />
            rcText.bottom = rc.y + rc.height;<br />
            if ( (dis.itemState &amp; OS.ODS_SELECTED) != 0 )<br />
            OS.OffsetRect( rcText, 1, 1 );<br />
            OS.SetBkMode( dis.hDC, OS.TRANSPARENT );<br />
            OS.DrawTextW( dis.hDC, chars, -1, rcText, OS.DT_SINGLELINE | OS.DT_CENTER | OS.DT_VCENTER );<br />
            OS.SelectObject( dis.hDC, oldFont );<br />
            }<br />
            <br />
            private void fillGradientRectangle( int handle, Rectangle rc,boolean vertical, Color clr1, Color clr2 )<br />
            {<br />
            final int hHeap = OS.GetProcessHeap();<br />
            final int pMesh = OS.HeapAlloc( hHeap, OS.HEAP_ZERO_MEMORY,GRADIENT_RECT.sizeof + TRIVERTEX.sizeof * 2 );<br />
            final int pVertex = pMesh + GRADIENT_RECT.sizeof;<br />
            <br />
            GRADIENT_RECT gradientRect = new GRADIENT_RECT();<br />
            gradientRect.UpperLeft = 0;<br />
            gradientRect.LowerRight = 1;<br />
            OS.MoveMemory( pMesh, gradientRect, GRADIENT_RECT.sizeof );<br />
            <br />
            TRIVERTEX trivertex = new TRIVERTEX();<br />
            trivertex.x = rc.x;<br />
            trivertex.y = rc.y;<br />
            trivertex.Red = (short)(clr1.getRed() &lt;&lt; 8);<br />
            trivertex.Green = (short)(clr1.getGreen() &lt;&lt; 8);<br />
            trivertex.Blue = (short)(clr1.getBlue() &lt;&lt; 8);<br />
            trivertex.Alpha = -1;<br />
            OS.MoveMemory( pVertex, trivertex, TRIVERTEX.sizeof );<br />
            <br />
            trivertex.x = rc.x + rc.width;<br />
            trivertex.y = rc.y + rc.height;<br />
            trivertex.Red = (short)(clr2.getRed() &lt;&lt; 8);<br />
            trivertex.Green = (short)(clr2.getGreen() &lt;&lt; 8);<br />
            trivertex.Blue = (short)(clr2.getBlue() &lt;&lt; 8);<br />
            trivertex.Alpha = -1;<br />
            OS.MoveMemory( pVertex + TRIVERTEX.sizeof, trivertex, TRIVERTEX.sizeof );<br />
            <br />
            boolean success = OS.GradientFill( handle, pVertex, 2, pMesh,
            1,vertical ? OS.GRADIENT_FILL_RECT_V : OS.GRADIENT_FILL_RECT_H );<br />
            OS.HeapFree( hHeap, 0, pMesh );<br />
            <br />
            if ( success )<br />
            return;<br />
            }<br />
            <br />
            @Override<br />
            protected void checkSubclass()<br />
            {}<br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
如果你使用的是JDK 1.4或者更低的版本，请把@Override标记去掉以后才能编译，因为这是一个<a href="http://dev.yesky.com/devjava/" target="_blank"><font color="#000000">Java</font></a> 5.0中才有的特性。此外，我重载了checkSubclass方法并提供了一个空的实现；如果不这么做的话，那么SWT在默认情况下是不允许你从Button类继承的。<br />
<br />
这个地方请允许我稍稍跑一下题。上面代码中的fillGradientRectangle方法——从它的名字你大概可以猜到，这个方法的作用是画出一个
渐变色的矩形区域。我是从GC.fillGradientRectangle中&#8220;偷&#8221;来的代码，针对按钮类作了一些修改就可以了。让我感到讶异的是，在整
理这段代码的时候，我发现从SWT中调用Win32
API实在是太方便了——比我原先猜想的还要容易得多。即便是微软的P/Invoke也要比这麻烦。当然，这很大程度上要归功于SWT将系统函数很好的封
装在了一个OS静态类中。（如果你不知道P/Invoke是什么的话，简单的说它就是微软在.Net平台中提供的、用来调用系统API和自定义DLL中的
方法的技术）。<br />
<br />
上面那些绘图的代码基本上是Windows
SDK的编程风格。因为我本人有很多这方面的开发经验，所以这些代码对我来说是相当清晰且直观的。不过我估计纯粹的Java程序员或许对这段代码不会有很
大的好感。理论上讲，我可以把这些代码用更加OO的方式包装起来，从而看上去能好看一些。不过，本文的目的在于讲述实现技术，用包装的话反而会破坏效果。
如果你感兴趣的话，也可以尝试自己来包装一下。<br />
<br />
需要讲解的地方到这里就全部结束了。为了完整起见，我把程序框架类的代码也列在下面，但是不做什么说明——基本上每个SWT程序中这段代码都是大同小异的。<br />
<br />
<table width="90%" align="center" bgcolor="#e7e9e9" border="1" bordercolor="#cccccc">
    <tbody>
        <tr>
            <td>import org.eclipse.swt.layout.FillLayout;<br />
            import org.eclipse.swt.widgets.*;<br />
            <br />
            public class Application<br />
            {<br />
            public static void main( String[] args )<br />
            {<br />
            Display display = Display.getDefault();<br />
            Shell shell = new Shell( display );<br />
            init( shell );<br />
            <br />
            shell.pack();<br />
            shell.open();<br />
            while ( !shell.isDisposed() )<br />
            {<br />
            if ( !display.readAndDispatch() )<br />
            display.sleep();<br />
            }<br />
            }<br />
            <br />
            private static void init( Shell shell )<br />
            {<br />
            shell.setText( "Owner Draw Button Test" );<br />
            FillLayout layout = new FillLayout();<br />
            layout.marginWidth = layout.marginHeight = 8;<br />
            shell.setLayout( layout );<br />
            <br />
            Button btn = new TestButton( shell );<br />
            btn.setText( "Owner Draw Button" );<br />
            btn.setToolTipText( "Hello, I'm a OwnerDraw Button!" );<br />
            }<br />
            }</td>
        </tr>
    </tbody>
</table>
<br />
下面是程序运行的界面。尽管这远远算不上完美——真正的按钮还应该考虑，是否能够和用户的任何配置下，特别是有窗口主题的时候也能正常工作？
完美的按钮实现可能需要至少数百行的代码才行。不过对本文的目的来说，这样已经足够了。可惜的是按下按钮的效果无法从图中体现；你可以自己运行一下这个程
序来体验一下实际的感觉。
<img src ="http://www.blogjava.net/sealyu/aggbug/192000.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-04-10 22:41 <a href="http://www.blogjava.net/sealyu/archive/2008/04/10/192000.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse SWT应用程序项目的打包与部署（转载）</title><link>http://www.blogjava.net/sealyu/archive/2008/04/10/191999.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 10 Apr 2008 14:40:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/04/10/191999.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/191999.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/04/10/191999.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/191999.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/191999.html</trackback:ping><description><![CDATA[<h2><font size="4">Eclipse SWT应用程序项目的打包与部署</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </h2>
<p>当项目完成后接下来的就是打包发行了，应用程序（Application）项目和Eclipse插件项目（plugin）的打包是不同的，本章将分别介绍两者的打包方法，并给出实际的打包例子。<br />
</p>
<h2>7.1&nbsp; 应用程序项目的打包与发行</h2>
<h3>7.1.1&nbsp; 简介</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java应用程序项目完成后是可以脱离Eclipse运行的，要运行程序先要打它打成一个JAR包，它打包的大部份方法和标准Java的AWT/SWING的打包方法一样，主要有以下几个要点</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MANIFEST.MF － &nbsp;打包清单。它是打包的关键性文件，主要是设置执行入口类和支持库的路径，在运行Java应用程序时是要根据此文件中给出的信息来查找入口类和支持库。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持包
－如果Java应用程序用到了一些Eclipse包，那么就必须将这些包也复制到程序运行目录，否则程序将无法运行。如swt组件支持包swt.jar，
jface组件支持包jface.jar。这些包都要在MANIFEST.MF文件中设置好。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本地化文件 － 如果用到了SWT组件，则还需要将SWT的本地化文件swt-win32-3063.dll（3063是版本号）复制到程序运行目录，否则程序将无法运行。</p>
<h3>7.1.2&nbsp; 打包的具体操作步骤</h3>
<p>本节将用前几章开发的SWT/JFace项目"myswt"的打包为例，来介绍打包应用程序项目的方法。</p>
<p>1、编辑清单MANIFEST.MF </p>
<p>（1）Eclipse提供了用于打包项目的"导出"向导，但本例运行此向导之前先需要创建一个MANIFEST.MF清单文件，其内容如下：</p>
<p>Manifest-Version: 1.0</p>
<p>Main-Class: book.chapter_4.wizard_dialog.WizardDialog1</p>
<p>Class-Path: ./lib/swt.jar ./lib/jface.jar ./lib/runtime.jar</p>
<p>说明：</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Manifest-Version － 指定清单文件的版本号</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Main-Class － 指定程序运行的入口类。本例设为运行4.5.2节开发的向导式对话框。注意：类名后不要加class扩展名</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class-Path －
指定支持库的路径。"."指程序运行目录，即导出的JAR包所在目录。程序运行时依据Class-Path项的设置路径来查找支持库。每一个支持库之间用
空格隔开。在这里jface.jar需要用到runtime.jar包，所以runtime.jar包也要加入到Class-Path中。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 除了入口类的包名和类名之外，其他设置项都不分大小写，比如：Class-Path写成class-path或CLASS-PATH也可以，swt.jar写成SWT.JAR也行。</p>
<p>（2）将清单文件保存下来，建议放在myswt项目的根目录下。它的文件名可以任意取，本例取名为manifes.txt，Eclipse向导在打包时会自动的将manifes.txt的内容复制到JAR包的META-INF目录下的MANIFEST.MF文件中。</p>
<p>2、使用Eclipse"导出"向导来打包项目</p>
<p>（1）右键单击myswt项目的项目名，在弹出菜单中选择"导出"。在弹出的如下图7.1所示的对话框中，选择"JAR文件"，单击"下一步"。</p>
<p>图7.1&nbsp; 导出对话框</p>
<p>（2）如下图7.2所示，将右边不需要的文件都取消勾选。在"选择导出目标"项文本框中设置JAR包的输出路径和包名（可以任意取名）为"D:"myswt_application"myswt.jar"。接受其他的默认设置不变，单击"下一步"。</p>
<p>附注：左边虽然选择了src目录，但源文件并不会导出到包中，除非勾选了"导出Java源代码文件和资源"项。</p>
<p>图7.2&nbsp; 选择导入文件</p>
<p>（3）如下图7.3所示，接受默认设置不变，单击"下一步"。</p>
<p>图7.3&nbsp; 导出类的选项</p>
<p>（4）这一步较关键。如下图7.4所示，选择"从工作空间中使用现有清单"项，将创建的清单文件输入，也可以通过旁边的"浏览"按钮来选择清单文件。输入清单文件后，单击"完成"，Eclipse开始将项目打包。</p>
<p>图7.4&nbsp; 清单文件设置</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
经过以上四步后，在"D:"myswt_application"路径下生成了一个名为"myswt.jar"的文件。myswt.jar是一个ZIP格
式的压缩文件，可以用WinRAR或WinZip软件打开，也就是说用这两个软件也可以替代Eclipse向导来打包文件。如果用WinRAR来打包文
件，则压缩格式要选择ZIP格式而非RAR格式，压缩率倒可以任意选。</p>
<p>用WinRAR打开myswt.jar文件后其内部的目录结构如下图7.5所示：</p>
<p>图7.5&nbsp; myswt.jar文件的内部目录结构</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在myswt.jar文件的内部目录META-INF中仅一个文件：MANIFEST.MF，它和以前创建的清单文件manifest.txt的内容是一样的，如下：</p>
<p>Manifest-Version: 1.0</p>
<p>Class-Path: ./lib/swt.jar ./lib/jface.jar ./lib/runtime.jar</p>
<p>Main-Class: book.chapter_4.wizard_dialog.WizardDialog1</p>
<p>3、复制Java应用程序的支持包及本地化文件</p>
<p>在MANIFEST.MF文件中的Class-Path项设置了三个包，从Eclipse的plugins目录中将此三个支持包复制到D:"
myswt_application"lib目录，本地化文件swt-win32-3063.dll复制到D:"myswt_application目录
中。此三个文件在Eclipse中的路径为：</p>
<p>plugins"org.eclipse.swt.win32_3.0.1"ws"win32"swt.jar</p>
<p>plugins"org.eclipse.jface_3.0.0"jface.jar</p>
<p>plugins"org.eclipse.core.runtime_3.0.1"runtime.jar</p>
<p>plugins"org.eclipse.swt.win32_3.0.1"os"win32"x86"swt-win32-3063.dll</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 复制完成后的目录结构如下图7.6所示：</p>
<p>图7.6&nbsp; 目录结构图</p>
<p>4、编写运行myswt.jar包的批处理程序"run.bat"</p>
<p>在myswt_application目录下创建一个批处理程序run.bat（名字任取，扩展名必须是bat），其内容仅一句语句，如下：</p>
<p>javaw -jar myswt.jar</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明：</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; javaw对应c:"jdk"jre"bin"javaw.exe文件，如果windows提示命令未发现，则需要将c:"jdk"jre"bin路径加入到windows环境变量path中。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在运行程序的时候有一个讨厌的黑色命令行窗口，要去掉它，可以将run.bat内容更改如下："start javaw -jar myswt.jar"，start是指调用了windows的"运行"命令。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果想将swt-win32-3063.dll也放在单独的目录中，如"D:"myswt_application"native"目录，则需将run.bat内容更改为：</p>
<p>start javaw -Djava.library.path=./native/ -jar myswt.jar </p>
<p>5、运行程序</p>
<p>双击run.bat文件，得到如下图7.7所示的程序界面。</p>
<p>图7.7&nbsp; 程序运行效果图</p>
<p>6、注意事项</p>
<p>本例只需要三个支持包，但你的程序也许会需要更多的支持包才能运行。如果你想一次到位，则可以将"Java构建路径"的"库"选项卡中所有引用的包
都复制到lib目录中。如果你喜欢用到什么包才加入什么包，希望维持打包文件的简洁，则需要自己一步步的去试：如果缺少某支持包，运行程序时会输出的未找
到类的错误信息，从信息中的包名可得知程序缺少哪一个支持包。比如"Exception in thread "main"
java.lang.NoClassDefFoundError:
org/eclipse/jface/wizard/IWizard"，从错误信息中很明显的就能知道程序缺少jface包</p>
<h3>7.1.3&nbsp; 其他得到JAR包的方式</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要得到JAR包除了以上所说的用Eclipse"导出"向导、用WinZip和WinRAR，另外还能用Java自带的命令行式打包软件jar.exe（位于c:"jdk"bin目录），其打包命令为：</p>
<p>c:"jdk"bin"jar cvfm myswt.jar
C:"eclipse3.0.1"eclipse"workspace"myswt"manifest.txt -C
C:"eclipse3.0.1"eclipse"workspace"myswt"bin .</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明：</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c:"jdk"bin"jar － 由于本书没有把c:"jdk"bin加入到windows环境变量path中，所以手工指定jar.exe的路径</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cvfm － jar.exe的参数，"c"创建新的jar包；"v"将调试信息打印在屏幕上；"f"指定生成的jar文件名；"m"使用清单文件。注意它们都是小写</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myswt.jar － 打包后的JAR包名</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在前面是把清单文件manifest.txt放在C:"eclipse3.0.1"eclipse"workspace"myswt"目录下。如果将它和批处理文件放在一个目录就不必指定长长的路径了。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-C 路径 . "指将路径下（包括子目录）的所有文件打包，由于class文件是输出在项目的bin目录下，所以路径指定到项目的bin目录，注意三者之间是用空格隔开，并且最后一个字符是小数点。</p>
<p>这种方式的优点是没有Eclipse导出向导的操作那么麻烦，适合经常需要导出JAR包的情况。</p>
<p>7.1.4&nbsp; 使用第三方插件对项目打包</p>
<p>开源组织（http://sourceforge.net/）中有一款可将Eclipse支持包和项目编译文件一起打到一个包中的插件，叫"Fat
Jar"，它的下载地址是"http://fjep.sourceforge.net/"，具体下载不再说明，安装步骤参阅第1章SWT
Designer的安装。</p>
<p>Fat Jar的使用步骤如下：</p>
<p>（1）右键单击myswt项目的项目名，可见菜单中多了一项"Build Fat Jar"，如下图7.8所示，选择"Build Fat Jar"项。</p>
<p>图7.8&nbsp; 右键菜单</p>
<p>（2）在下图7.9所示的对话框中，"Jar-Name"项填入JAR包的输出路径。文件清单"Manifest"项不用填，默认会自动创建一个。"Main-Class"项填入程序的入口类。其他都接受默认值，单击"下一步"。</p>
<p>图7.9&nbsp; 输出配置</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
（3）如下图7.10所示，窗口中将myswt项目所用到的支持包都列了出来。我们仅勾选图中runtime.jar、swt.jar、
jface.jar这三项即可，当然全选也并尝不可，只是最后得到的JAR包会更大一些，因为Fat Jar会将所有支持包合并在一个JAR包中。</p>
<p>图7.10&nbsp; 选择要打包的文件</p>
<p>单击图7.10的"完成"按钮后，
JAR包myswt.jar将输出到D:"myswt_applicationh目录中。和以前一样，要运行此JAR包需要一个批处理文件以及本地化文件
swt-win32-3063.dll，唯一不同的是不再需要Eclipse支持包，其目录结构如下图7.11所示：</p>
<p>图7.11&nbsp; 目录结构</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为什么不需要Eclipse支持包了呢？那是因为支持包已经在myswt.jar文件中了，从下图7.12可以看到swt.jar等都被拆散成目录，并包含在myswt.jar包中。</p>
<p>图7.12&nbsp; myswt.jar的内部目录结构</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中META-INF目录的MANIFEST.MF文件内容如下，可以发现和以前不同的地方是：Class-Path项没有了。</p>
<p>Manifest-Version: 1.0</p>
<p>Created-By: Fat Jar Eclipse Plug-In</p>
<p>Main-Class: book.chapter_4.wizard_dialog.WizardDialog1</p>
<h3>7.1.4&nbsp; 让用户电脑不必安装JRE环境</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通常运行Java程序有个前提条件：用户电脑必须先安装JRE环境。虽然安装JRE环境非常简单，但毕竟多了一步，算是有一点点的瑕疵。这里给出一个不必让用户安装JRE环境的方法，其实现步骤如下：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （1）将原JDK中的"jre"目录复制到"D:"myswt_application"java1.4.2"目录下（java1.4.2也可换成其他名称）。</p>
<p>（2）将JDK和JRE从本机卸载掉，这样表示本机没有安装JAVA运行环境。</p>
<p>（3）修改批处理文件run.bat中的命令为"start java1.4.2"jre"bin"javaw -jar myswt.jar"，仅仅是在javaw前加上了一个相对应路径。</p>
<p>双击run.bat即可在不安装JRE环境的电脑运行此Java应用程序。</p>
<h3>7.1.5&nbsp; 更进一步的完善</h3>
<p>1、抛弃批处理文件（*.bat）</p>
<p>用批处理文件运行程序似乎不够专业，虽然它足以完成运行任务。但习惯就象一种毒药一旦染上就很难摆脱它的影响，Windows统治下的人们早已经习惯运行扩展名是EXE的程序，用*.bat他们就会感觉别扭。</p>
<p>我们可以用一个叫JavaLauncher的免费小程序来代替批处理文件去运行Java程序。JavaLauncher的下载网址是：</p>
<p><a href="http://www.rolemaker.dk/nonRoleMaker/javalauncher/marner_java_launcher.htm">http://www.rolemaker.dk/nonRoleMaker/javalauncher/marner_java_launcher.htm</a></p>
<p>下载下来的文件是一个名JavaLauncher.zip的压缩包，解压后的目录结构如下图7.13所示：</p>
<p>图7.13&nbsp; JavaLauncher.zip目录结构</p>
<p>在上图的目录中</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source目录包含了JavaLauncher的源程序，是用C语言写的</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; changes.txt是新版的修改说明</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; launch.exe是主程序</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; launcher.cfg是配置文件</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readme.txt是一些说明和示例</p>
<p>我们只需要launch.exe、launcher.cfg两个文件，将这两个文件复制到打包文件所在的目录。launcher.cfg是一个仅三行内容的文本文件，将它修改如下：</p>
<p>.</p>
<p>."java1.4.2"jre"bin"javaw.exe </p>
<p>-jar myswt.jar</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第一行设置指向JAR包myswt.jar的目录，由于launch.exe和myswt.jar同在一个目录，所以用"."即当前目录。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二行设置指向jre"bin"javaw.exe的路径。在上一小节（7.1.4节）已将jre目录复制到了java1.4.2子目录中</p>
<p>配置好launcher.cfg后，双击launch.exe即可运行java应用程序。</p>
<p>如果仔佃研究eclipse的启动方式，发现eclipse和JavaLauncher的原理一样：eclipse.exe相当于
launch.exe，startup.jar相当于myswt.jar。只不过eclipse.exe不象launch.exe要具有通用性，所以它没
有*.cfg这样的配置文件，而是将启动信息固化在eclipse.exe中。</p>
<p>2、美化图标</p>
<p>launch.exe文件的图标太单调了，让我们给它换个好看点的。换程序的图标需要用到一个免费的软件：Resource Hacker，它有中文版，下载网址是：</p>
<p><a href="http://www.users.on.net/johnson/resourcehacker/">http://www.users.on.net/johnson/resourcehacker/</a></p>
<p>用Resource Hacker来替换launch.exe的图标的步骤如下：</p>
<p>（1）运行Resource Hacker，得到如下图7.14所示的窗口。</p>
<p>图7.14&nbsp; Resource Hacker的主界面</p>
<p>（2）单击主菜单"文件&#8594;打开"，将launch.exe载入到程序中，结果如下图7.15所示。</p>
<p>图7.15&nbsp; 载入Lanunch.exe之后的界面</p>
<p>（3）如上图，选择左边的"图标&#8594;1&#8594;1030"，然后右键单击"1030"项，选择"替换资源..."。如下图7.16所示，在弹出窗口中单击"打开新图标文件"，选择一个满意的图标，然后单击"替换"按钮。</p>
<p>附注：图标文件可以是exe、dll、res、ico，该软件可以从exe、dll、res抽取出图标，本例选择的是java的一个图标文件JavaCup.ico。</p>
<p>图7.16&nbsp; 选择图标文件</p>
<p>（4）如下图7.17所示，选择"文件&#8594;另存为"，取名myswt.exe。</p>
<p>附注：按理说选择"保存"也是可以的，这时Resource Hacker会将老的launch.exe备份成launch_original.exe。但也许是刷新上有问题，用"保存"方式有时launch.exe无法显示出新图标，但有时又可以。</p>
<p>图7.17&nbsp; 保存修改</p>
<p>（5）最后的目录如下图7.18所示，可见myswt.exe（也就是launch.exe改了个名称）的图标换成了Java的图标。双击myswt.exe即可运行Java应用程序。</p>
<p>图7.18&nbsp; 最后的效果</p>
<p>3、最后的打包</p>
<p>发送给用户之前，通常要用WinZip或WinRAR将所有的文件全部打成一个压缩包，然后用户得到这个压缩包后，将其解压缩后即可运行程序，Eclipse软件就是这种方式。</p>
<p>另一种方式是用InstallShield、InstallAnyWhere这样的安装程序制作软件来创建一个单一的setup.exe文件，它具有向导式的安装界面，而且还可以往windows的程序栏插入菜单项，关于这些安装程序制作软件的具体使用请参阅相关书籍。</p>
<table>
    <tbody>
        <tr>
            <td><br />
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/sealyu/aggbug/191999.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-04-10 22:40 <a href="http://www.blogjava.net/sealyu/archive/2008/04/10/191999.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>修改 SWT browser类，添加getText()方法</title><link>http://www.blogjava.net/sealyu/archive/2008/04/10/191997.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 10 Apr 2008 14:35:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/04/10/191997.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/191997.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/04/10/191997.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/191997.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/191997.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最近用到了SWT中的Browser类，这个类不允许被继承，在网上搜索的时候发现了下面的帖子。这个类实际上是使用OLE，将IE直接嵌套进SWT程序中去。下面代码的修改实际上将SWT中的WebBrowser类的子类IE直接和Browser类合到一起，而同时也就没有了原来SWT中的跨平台的优点。该作者添加了setHtml这个函数和_text属性。从而得到对应的网页的html内容。/*...&nbsp;&nbsp;<a href='http://www.blogjava.net/sealyu/archive/2008/04/10/191997.html'>阅读全文</a><img src ="http://www.blogjava.net/sealyu/aggbug/191997.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-04-10 22:35 <a href="http://www.blogjava.net/sealyu/archive/2008/04/10/191997.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>