﻿<?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-随笔分类-GWT</title><link>http://www.blogjava.net/sealyu/category/43681.html</link><description>--- The devil's in the Details</description><language>zh-cn</language><lastBuildDate>Tue, 02 Feb 2010 11:53:05 GMT</lastBuildDate><pubDate>Tue, 02 Feb 2010 11:53:05 GMT</pubDate><ttl>60</ttl><item><title>GWT的loading indicator（装载指示器）</title><link>http://www.blogjava.net/sealyu/archive/2010/02/02/311683.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Tue, 02 Feb 2010 07:28:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/02/02/311683.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/311683.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/02/02/311683.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/311683.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/311683.html</trackback:ping><description><![CDATA[本文参考：http://groups.google.com/group/Google-Web-Toolkit/browse_thread
/thread/7ed0d179b89fa062/aaeb5391a760adef?lnk=gst&amp;q=indicator+AsyncCallback&amp;rnum=1#aaeb5391a760adef
<br />
<br />
大部分代码也是参考文中的。
<br />
<br />
<div>
<div>
<div>Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.javaeye.dengyin2000.truck.client.server%3B%0A%0Aimport%20com.google.gwt.user.client.Window%3B%0Aimport%20com.google.gwt.user.client.rpc.AsyncCallback%3B%0A%0Apublic%20abstract%20class%20AsyncCallbackWithStatus%20implements%20AsyncCallback%20%7B%0A%09private%20static%20LoadingIndicator%20loadingIndicator%3B%0A%0A%09public%20static%20final%20void%20setLoadingIndicator(LoadingIndicator%20indicator)%20%7B%0A%09%09loadingIndicator%20%3D%20indicator%3B%0A%09%7D%0A%0A%09public%20AsyncCallbackWithStatus()%20%7B%0A%09%09setLoading(true)%3B%0A%09%7D%0A%0A%09public%20final%20void%20onSuccess(Object%20object)%20%7B%0A%09%09setLoading(false)%3B%0A%09%09onSuccessInternal(object)%3B%0A%09%7D%0A%0A%09public%20final%20void%20onFailure(Throwable%20throwable)%20%7B%0A%09%09setLoading(false)%3B%0A%09%09onFailureInternal(throwable)%3B%0A%09%7D%0A%0A%09protected%20abstract%20void%20onSuccessInternal(Object%20object)%3B%0A%0A%09protected%20void%20onFailureInternal(Throwable%20throwable)%7B%0A%09%09Window.alert(%22%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%B2%A1%E6%9C%89%E5%93%8D%E5%BA%94%2C%E8%AF%B7%E7%A8%8D%E5%90%8E%E5%86%8D%E8%AF%95!%22)%3B%0A%09%7D%0A%0A%09private%20void%20setLoading(boolean%20isLoading)%20%7B%0A%09%09if%20(null%20!%3D%20loadingIndicator)%20%7B%0A%09%09%09if%20(isLoading)%20%7B%0A%09%09%09%09loadingIndicator.show()%3B%0A%09%09%09%7D%20else%20%7B%0A%09%09%09%09loadingIndicator.hide()%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%0A%09interface%20LoadingIndicator%20%7B%0A%09%09void%20show()%3B%0A%0A%09%09void%20hide()%3B%0A%09%7D%0A%0A%7D%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol start="1">
    <li>package&nbsp;com.javaeye.dengyin2000.truck.client.server;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>import&nbsp;com.google.gwt.user.client.Window;&nbsp;&nbsp;</li>
    <li>import&nbsp;com.google.gwt.user.client.rpc.AsyncCallback;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>public&nbsp;abstract&nbsp;class&nbsp;AsyncCallbackWithStatus&nbsp;implements&nbsp;AsyncCallback&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;LoadingIndicator&nbsp;loadingIndicator;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;final&nbsp;void&nbsp;setLoadingIndicator(LoadingIndicator&nbsp;indicator)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loadingIndicator&nbsp;=&nbsp;indicator;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;AsyncCallbackWithStatus()&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setLoading(true);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;final&nbsp;void&nbsp;onSuccess(Object&nbsp;object)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setLoading(false);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onSuccessInternal(object);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;final&nbsp;void&nbsp;onFailure(Throwable&nbsp;throwable)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setLoading(false);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onFailureInternal(throwable);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;abstract&nbsp;void&nbsp;onSuccessInternal(Object&nbsp;object);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;onFailureInternal(Throwable&nbsp;throwable){&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Window.alert("服务器没有响应,请稍后再试!");&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;setLoading(boolean&nbsp;isLoading)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(null&nbsp;!=&nbsp;loadingIndicator)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(isLoading)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loadingIndicator.show();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loadingIndicator.hide();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;interface&nbsp;LoadingIndicator&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;show();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;hide();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">package com.javaeye.dengyin2000.truck.client.server;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
public abstract class AsyncCallbackWithStatus implements AsyncCallback {
private static LoadingIndicator loadingIndicator;
public static final void setLoadingIndicator(LoadingIndicator indicator) {
loadingIndicator = indicator;
}
public AsyncCallbackWithStatus() {
setLoading(true);
}
public final void onSuccess(Object object) {
setLoading(false);
onSuccessInternal(object);
}
public final void onFailure(Throwable throwable) {
setLoading(false);
onFailureInternal(throwable);
}
protected abstract void onSuccessInternal(Object object);
protected void onFailureInternal(Throwable throwable){
Window.alert("服务器没有响应,请稍后再试!");
}
private void setLoading(boolean isLoading) {
if (null != loadingIndicator) {
if (isLoading) {
loadingIndicator.show();
} else {
loadingIndicator.hide();
}
}
}
interface LoadingIndicator {
void show();
void hide();
}
}
</pre>
<br />
<br />
<div>
<div>
<div>Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20com.javaeye.dengyin2000.truck.client.server%3B%0A%0Aimport%20com.google.gwt.user.client.Window%3B%0Aimport%20com.google.gwt.user.client.WindowResizeListener%3B%0Aimport%20com.google.gwt.user.client.ui.HTML%3B%0Aimport%20com.google.gwt.user.client.ui.PopupPanel%3B%0Aimport%20com.javaeye.dengyin2000.truck.client.server.AsyncCallbackWithStatus.LoadingIndicator%3B%0A%0Apublic%20class%20LoadingStatus%20implements%20LoadingIndicator%2C%20WindowResizeListener%20%7B%0A%20%20%20%20private%20PopupPanel%20popup%3B%0A%0A%20%20%20%20public%20LoadingStatus()%20%7B%0A%20%20%20%20%20%20%20%20popup%20%3D%20new%20PopupPanel()%3B%0A%20%20%20%20%20%20%20%20popup.add(new%20HTML(%22%3Cdiv%20style%3D'background-color%3A%20red%3B'%3E%20Loading%2C%20please%20wait...%3C%2Fdiv%3E%22))%3B%0A%20%20%20%20%20%20%20%20placeIndicator()%3B%0A%20%20%20%20%20%20%20%20Window.addWindowResizeListener(this)%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20set%20the%20style%20name%20for%20greater%20control%20over%20the%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20show()%20%7B%0A%20%20%20%20%20%20%20%20popup.show()%3B%20%0A%20%20%20%20%7D%0A%0A%20%20%20%20public%20void%20hide()%20%7B%0A%20%20%20%20%20%20%20%20popup.hide()%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20private%20void%20placeIndicator()%7B%0A%20%20%20%20%09popup.setPopupPosition(Window.getClientWidth()%20-%20120%2C%2010)%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20public%20void%20onWindowResized(int%20width%2C%20int%20height)%20%7B%0A%20%20%20%20%09%20placeIndicator()%3B%0A%20%20%20%20%7D%20%0A%0A%7D%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol start="1">
    <li>package&nbsp;com.javaeye.dengyin2000.truck.client.server;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>import&nbsp;com.google.gwt.user.client.Window;&nbsp;&nbsp;</li>
    <li>import&nbsp;com.google.gwt.user.client.WindowResizeListener;&nbsp;&nbsp;</li>
    <li>import&nbsp;com.google.gwt.user.client.ui.HTML;&nbsp;&nbsp;</li>
    <li>import&nbsp;com.google.gwt.user.client.ui.PopupPanel;&nbsp;&nbsp;</li>
    <li>import&nbsp;com.javaeye.dengyin2000.truck.client.server.AsyncCallbackWithStatus.LoadingIndicator;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>public&nbsp;class&nbsp;LoadingStatus&nbsp;implements&nbsp;LoadingIndicator,&nbsp;WindowResizeListener&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;PopupPanel&nbsp;popup;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;LoadingStatus()&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;popup&nbsp;=&nbsp;new&nbsp;PopupPanel();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;popup.add(new&nbsp;HTML("&lt;div&nbsp;style='background-color:&nbsp;red;'&gt;&nbsp;Loading,&nbsp;please&nbsp;wait...&lt;/div&gt;"));&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;placeIndicator();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Window.addWindowResizeListener(this);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;the&nbsp;style&nbsp;name&nbsp;for&nbsp;greater&nbsp;control&nbsp;over&nbsp;the&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;show()&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;popup.show();&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;hide()&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;popup.hide();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;placeIndicator(){&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;popup.setPopupPosition(Window.getClientWidth()&nbsp;-&nbsp;120,&nbsp;10);&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onWindowResized(int&nbsp;width,&nbsp;int&nbsp;height)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;placeIndicator();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">package com.javaeye.dengyin2000.truck.client.server;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.PopupPanel;
import com.javaeye.dengyin2000.truck.client.server.AsyncCallbackWithStatus.LoadingIndicator;
public class LoadingStatus implements LoadingIndicator, WindowResizeListener {
private PopupPanel popup;
public LoadingStatus() {
popup = new PopupPanel();
popup.add(new HTML("&lt;div style='background-color: red;'&gt; Loading, please wait...&lt;/div&gt;"));
placeIndicator();
Window.addWindowResizeListener(this);
// set the style name for greater control over the
}
public void show() {
popup.show();
}
public void hide() {
popup.hide();
}
private void placeIndicator(){
popup.setPopupPosition(Window.getClientWidth() - 120, 10);
}
public void onWindowResized(int width, int height) {
placeIndicator();
}
}
</pre>
<br />
<br />
在你的EntryPoint中装配好你的indicator
<br />
<br />
<div>
<div>
<div>Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%09private%20void%20prepareLoadingIndicator()%7B%0A%09%09LoadingStatus%20status%20%3D%20new%20LoadingStatus()%3B%0A%09%09AsyncCallbackWithStatus.setLoadingIndicator(status)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol start="1">
    <li>private&nbsp;void&nbsp;prepareLoadingIndicator(){&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;LoadingStatus&nbsp;status&nbsp;=&nbsp;new&nbsp;LoadingStatus();&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;AsyncCallbackWithStatus.setLoadingIndicator(status);&nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">	private void prepareLoadingIndicator(){
LoadingStatus status = new LoadingStatus();
AsyncCallbackWithStatus.setLoadingIndicator(status);
}</pre>
<br />
<br />
这样调用。
<br />
<br />
<div>
<div>
<div>Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%09private%20void%20populateAndReadEnterprisesInfo()%7B%0A%09%09GWTRPCServiceLocator.getUserService().getEnterprisesInfo(new%20AsyncCallbackWithStatus()%7B%0A%0A%09%09%09protected%20void%20onSuccessInternal(Object%20object)%20%7B%0A%09%09%09%09EnterprisesInfoGTO%20gto%20%3D%20(EnterprisesInfoGTO)%20object%3B%0A%09%09%09%09enterpriseName.setText(gto.getEnterprisesName())%3B%0A%09%09%09%09contactName.setText(gto.getContactName())%3B%0A%09%09%09%09contactTel.setText(gto.getContactTel())%3B%0A%09%09%09%09contactFax.setText(gto.getContactFax())%3B%0A%09%09%09%09contactAddress.setText(gto.getContactAddress())%3B%0A%09%09%09%09zipCode.setText(gto.getZipCode())%3B%0A%09%09%09%09email.setText(gto.getEmail())%3B%0A%09%09%09%09siteAddress.setText(gto.getSiteAddress())%3B%0A%09%09%09%7D%0A%09%09%09%0A%09%09%7D)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol start="1">
    <li>private&nbsp;void&nbsp;populateAndReadEnterprisesInfo(){&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;GWTRPCServiceLocator.getUserService().getEnterprisesInfo(new&nbsp;AsyncCallbackWithStatus(){&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;onSuccessInternal(Object&nbsp;object)&nbsp;{&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnterprisesInfoGTO&nbsp;gto&nbsp;=&nbsp;(EnterprisesInfoGTO)&nbsp;object;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enterpriseName.setText(gto.getEnterprisesName());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contactName.setText(gto.getContactName());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contactTel.setText(gto.getContactTel());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contactFax.setText(gto.getContactFax());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contactAddress.setText(gto.getContactAddress());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zipCode.setText(gto.getZipCode());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;email.setText(gto.getEmail());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;siteAddress.setText(gto.getSiteAddress());&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;</li>
    <li>}&nbsp; <br />
    </li>
</ol>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/311683.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> 2010-02-02 15:28 <a href="http://www.blogjava.net/sealyu/archive/2010/02/02/311683.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Coding Quickie – display a message while your GWT app loads</title><link>http://www.blogjava.net/sealyu/archive/2010/02/02/311679.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Tue, 02 Feb 2010 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/02/02/311679.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/311679.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/02/02/311679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/311679.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/311679.html</trackback:ping><description><![CDATA[<p>The Problem</p>
<p>When a <a href="http://developerlife.com/tutorials/?p=80" target="_blank">GWT</a>
application loads, nothing is actually displayed by your application
until all the generated JavaScript has been downloaded by the browser.
I was looking for way to display a loading screen while my GWT
application was loading, and then remove it once the GWT application is
loaded.</p>
<h4>The Solution</h4>
<p>Since every GWT application has to be embedded in an <em>HTML Host Page</em>, an easy way to display a loading message is to place the loading message in a <em><strong>&lt;div&gt;</strong></em> in the <em>HTML Host Page</em>.
Once all the GWT application JavaScript is done loading, we can have
the GWT application remove the loading message by doing some DOM
manipulation on the <em>HTML Host Page</em>.</p>
<p>Here is a sample <em>HTML Host Page</em>. The loading message, along with a loading animation image is contained in a <em><strong>&lt;div&gt;</strong></em> named <em>&#8220;Loading-Message&#8221;.</em></p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   1:</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   2:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   3:</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   4:</span>   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000ff;">&gt;</span>GWT Application<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   5:</span>   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">link</span> <span style="color: #ff0000;">rel</span><span style="color: #0000ff;">="stylesheet"</span> <span style="color: #ff0000;">href</span><span style="color: #0000ff;">="style.css"</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   6:</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   7:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   8:</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   9:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  10:</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script</span> <span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/javascript"</span> <span style="color: #ff0000;">language</span><span style="color: #0000ff;">="javascript"</span> <span style="color: #ff0000;">src</span><span style="color: #0000ff;">="gwtapp.nocache.js"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  11:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  12:</span>   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h2</span><span style="color: #0000ff;">&gt;</span>GWT Application<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h2</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  13:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  14:</span>   <span style="color: #008000;">&lt;!-- The loading message div --&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  15:</span>   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div</span> <span style="color: #ff0000;">id</span><span style="color: #0000ff;">="Loading-Message"</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  16:</span>     <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img</span> <span style="color: #ff0000;">src</span><span style="color: #0000ff;">="loading-animation.gif" </span> <span style="color: #ff0000;">alt</span><span style="color: #0000ff;">="loading"</span><span style="color: #0000ff;">&gt;</span> Loading GWT Application, please wait... </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  17:</span>   <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  18:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  19:</span>   <span style="color: #008000;">&lt;!-- The Application's UI elements will be placed in this div by the Application module's --&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  20:</span>   <span style="color: #008000;">&lt;!-- entry point class when it is loaded                                                  --&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  21:</span>   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div</span> <span style="color: #ff0000;">id</span><span style="color: #0000ff;">="GWT-Application-Panel"</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  22:</span>   <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  23:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  24:</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">  25:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  26:</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span></pre>
</div>
</div>
<p>The &#8220;<em>Loading-Message</em>&#8221; <em><strong>&lt;div&gt;</strong></em> can be removed from the <em>HTML Host Page</em> using the following line of Java Code:</p>
<div>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">DOM.setInnerHTML(RootPanel.get(<span style="color: #006080;">"Loading-Message"</span>).getElement(), <span style="color: #006080;">""</span>);</pre>
</div>
<p>Where would you put this line of code? You can put it anywhere in
your GWT application. However, a good place to put it would be in your
GWT application <em>EntryPoint</em> class&#8217;s <em>onModuleLoad</em> method. You can place it either before or after your application loads the UI elements. Here is an example <em>onModuleLoad</em> method:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> onModuleLoad() {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   2:</span>   <span style="color: #008000;">// Remove the loading message</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   3:</span>   DOM.setInnerHTML(RootPanel.get(&#8220;Loading-Message&#8221;).getElement(), &#8220;&#8221;);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   4:</span>&nbsp; </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   5:</span>   <span style="color: #008000;">// Get the Application Container div from the DOM</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   6:</span>   mainPanel = RootPanel.get(&#8220;GWT-Application_Panel&#8221;);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   7:</span>   </pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">   8:</span>   <span style="color: #008000;">// Add GWT UI components</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #606060;">   9:</span>   addWidgetsTo(mainPanel);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #606060;">  10:</span> }</pre>
</div>
</div>
<p>If you aren&#8217;t the artistic type, <a href="http://www.ajaxload.info/" target="_blank">here is a website</a> you can use to download a customized animation image. <a href="http://www.napyfab.com/ajax-indicators/">Here is another website</a>, where you can select some existing animations to use in your app.</p>
<p>If you haven&#8217;t already, please check out our continuing series of GWT Tutorials beginning with <a href="http://developerlife.com/tutorials/?p=80" target="_blank">Introduction to GWT.</a> You can find the rest of our GWT tutorials <a href="http://developerlife.com/tutorials/?cat=27" target="_blank">here.</a></p>
<img src ="http://www.blogjava.net/sealyu/aggbug/311679.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> 2010-02-02 15:15 <a href="http://www.blogjava.net/sealyu/archive/2010/02/02/311679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GWT File DownLoad</title><link>http://www.blogjava.net/sealyu/archive/2010/02/01/311554.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Mon, 01 Feb 2010 13:21:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/02/01/311554.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/311554.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/02/01/311554.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/311554.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/311554.html</trackback:ping><description><![CDATA[Per some requests for the File Download opposite of File Upload.
<br />
<br />
On the server side I implemented the doGet method of the
HttpServlet class. I grab the raw data from the database and set it
into the response (with the appropriate response type):
<br />
<br />
BufferedOutputStream output = null;
<br />
try {
<br />
RawAttachmentItem attachment = attachmentFileDao.retrieveContents(fileid);
<br />
ByteArrayInputStream input = new ByteArrayInputStream(attachment.getContents());
<br />
int contentLength = input.available();
<br />
<br />
resp.reset();
<br />
resp.setContentType("application/octet-stream");
<br />
resp.setContentLength(contentLength);
<br />
resp.setHeader("Content-disposition", "attachment; filename=""" + attachment.getFilename()
<br />
+ """");
<br />
output = new BufferedOutputStream(resp.getOutputStream());
<br />
for(int data; (data=input.read()) != -1;) {
<br />
output.write(data);
<br />
}
<br />
output.flush();
<br />
}
<br />
catch (IOException e) {
<br />
<br />
e.printStackTrace();
<br />
}
<br />
finally {
<br />
close(output);
<br />
}
<br />
On the client side, you simple create a new iFrame with its 'src' attribute set to the servlet url for downloading the file:
<br />
<br />
boolean frameExists = (RootPanel.get("downloadiframe") != null);
<br />
if(frameExists) {
<br />
Widget widgetFrame = (Widget)RootPanel.get("downloadiframe");
<br />
widgetFrame.removeFromParent();
<br />
}
<br />
<br />
NamedFrame frame = new NamedFrame("downloadiframe");
<br />
frame.setUrl(GWT.getModuleBaseURL()
<br />
+ "/attachmentHandler?action=dl&amp;fileid="
<br />
+ model.getFileId());
<br />
frame.setVisible(false);
<br />
<br />
RootPanel.get().add(frame);
<br />
When the file gets sent back to the iFrame, the browser will treat
it as a file download and prompt you to do something with it (open,
save, cancel, etc).
<br />
<br />
If anyone has questions or requires more detail, please do not hesitate to ask!!
<img src ="http://www.blogjava.net/sealyu/aggbug/311554.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> 2010-02-01 21:21 <a href="http://www.blogjava.net/sealyu/archive/2010/02/01/311554.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GWT开发的8个忠告(转载)</title><link>http://www.blogjava.net/sealyu/archive/2010/01/28/311099.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 28 Jan 2010 09:47:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/01/28/311099.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/311099.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/01/28/311099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/311099.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/311099.html</trackback:ping><description><![CDATA[<p><strong>Google Web工具包（GWT）确实是使用Java开发Ajax应用的一种诱人方法。如果你在AWT/Swing/SWT和服务器小程序方面有着扎实背景，实际上很容易学会使用GWT，但如果要做的不仅仅是快速原型设计，那么某些难题仍然存在。</strong>
</p>
<p style="color: red;">忠告之一: 分而治之
</p>
<p>众所周知，GWT应用就是Java应用。不过，问题在于是&#8220;哪种Java&#8221;，我们需要牢记:
GWT编译的是与J2SE 1.4.2或者更早版本兼容的Java源代码。另外，只有J2SE 1.4.2
API的子集得到支持，即java.lang和java.util程序包。即便在使用这些程序包时，也要非常认真地研究Google在运行库支持方面的注
释，并且牢记相应的忠告:
如果确保从一开始就只使用客户端代码中的可转换类，那么就可以避免许多问题。为了及早发现问题，只要在宿主模式（hosted
mode）下运行，就要对照JRE仿真库检验代码。因而，第一次运行应用时，就会发现大部分不支持的库。所以，要及早并且经常运行。
</p>
<p>现在，笔者给出的忠告就是&#8220;分而治之&#8221;，具体意思就是一开始就把应用代码分成三个不同的部分:
客户端代码、RPC相关代码和服务器端代码，然后构建相应的Eclipse项目，从而完成任务。这样一来，就可以利用不同的Java语言版本，用于客户端
和服务器部分。笔者用Java 5构建了应用的服务器部分（服务器小程序代码）;
但如果使用Mustang版本，那么在本文的代码片段中（由于篇幅有限，本文所涉及的程序代码可通过以下链接查询:
http://blog.ccw.com.cn/article-htm-itemid-17924-type-blog.html），可以用Java
6取代Java 5。即便在服务器端仍然使用J2SE
1.4.2，这种分治法也可以在将来提供更大的灵活性，明确分离代码（&#8220;分离问题&#8221;），而不会在GWT宿主模式下限制调试操作。如果所有部分都在一个
Eclipse项目中，则需要非常严谨，特别是在服务器端上; 不然，就会出现编译或者运行问题。
</p>
<p>需要使用特殊的命名约定，这样可以清楚确认不同项目，并且简化部署脚本。可以使用譬如名为GWT-&lt; ModuleName&gt;的Eclipse工作集来包括所有三个项目。这里，&#8220;ModuleName&#8221;是识别Web应用的GWT模块的名称。
</p>
<p>● 客户端代码: 包含与用户界面相关的代码，可以转换成JavaScript。因此，局限于J2SE
1.4.2和GWT运行时支持。启用每个项目的Eclipse
Java编译器设置和&#8220;Java编译器错误/警告&#8221;，把Java依从级别调整到1.4、把源代码和类文件兼容性调整到1.4（假设不是使用1.4之前的
JDK版本）。该项目的名称是&lt;
ModuleName&gt;-client，譬如&#8220;JUnit2MR-client&#8221;，它依赖于构建路径设置中的&lt;
ModuleName&gt;-rpc项目。程序包名称类似&lt; com.company.project&gt;.gwt.&lt;
moduleName&gt;.client。
</p>
<p>● RPC相关代码:
包含RPC相关的代码，可以转换成JavaScript。该项目遵从与上述客户端代码项目同样的指导准则。项目名是&lt;
ModuleName&gt;-rpc，譬如&#8220;JUnit2MR-rpc&#8221;，它并不依赖于其他任何项目。程序包名称与&lt;
ModuleName&gt;-client项目的程序包名称一样。RPC项目包含客户端上的远程接口、RPC期间由GWT进行序列化的数据传输对象，以
及全局常量类。
</p>
<p>● 服务器端代码:
含有服务器小程序代码，如果服务器端由Java服务器小程序组成的话。如果使用Tomcat 5.5或者Tomcat 6，可以充分利用Java
5+的全部功能。启用每个项目的Eclipse编译器设置，然后使用Java 5编译器设置，依从级别设置为5.0。如果使用Eclipse
3.2.2，那么其新的&#8220;源代码&#8594;清理&#8221;特性也值得配置。该项目名称是&lt;
ModuleName&gt;-server，譬如&#8220;JUnit2MR-server&#8221;，它依赖于构建路径设置中的&lt;
ModuleName&gt;-rpc项目。如果按照GWT的默认程序包提案进行编程，程序包名称是&lt;
com.company.project&gt;.gwt.&lt; moduleName&gt;.server。
</p>
<p style="color: red;">忠告之二: 调试和错误报告不仅仅只有Window.alert ()
</p>
<p>在创建GWT应用时，其实可以使用IDE的全部调试功能。但在深入分析何处可能出现错误之前，需要代码的客户端和
服务器端都有可靠的异常报告机制。使用try/catch代码块通常可以做到这一点。在客户端的catch代码块中，应当注意这一现实:
默认的方法调用e.printStackTrace()并不是在所有情况下都适合的解决办法。它适用于应用运行在GWT宿主模式下，把文本输出到
Eclipse控制台。不过在Web模式下，要问问自己:
&#8220;我发送到stdout或者stderr的堆栈跟踪信息和错误信息会在什么地方显示？&#8221;一种可能的解决方法就是使用Mat
Gessel的调试实用程序类（http://www.asquare.net/gwttk），但是需要浏览器JavaScript控制台来查看Web模
式下的结果。
</p>
<p>在客户端，建议要做的一件事就是，使用GWT.setUncaughtExceptionHandler()方
法，为任何未被发现的异常提供自己的异常处理程序。发现了这几种异常后，有几个选择: GWT.log（message,
caught）、Debug.println (message_with_stacktrace); 如果使用Mat
Gessel的Debug类，可选择Window.alert（message_with_stacktrace），或者自己定制的错误报告。
</p>
<p>视来源而定，会得到&#8220;无法装入模块&#8221;或者&#8220;未被发现的异常被漏过&#8221;的信息。笔者编写了一个小小的DebugUtility类，它提供了易于定制的默认客户端错误处理机制（见代码片段1）。
</p>
<p>在服务器端，可以使用java.util.logging
API或者log4j的广泛功能，具体取决于个人偏好或者项目的约束条件。但要是没有为GWT的
com.google.gwt.user.server.rpc.RemoteServiceServlet类打补丁，对于未被发现、未被检查的异常，只
会在堆栈跟踪里面得到提示，指向生成该错误的服务器端类。对于catch()代码块里面发现及报告的被检查的异常，一切都正常。
</p>
<p style="color: red;">忠告之三: 当心GWT Shell的&#8220;刷新&#8221;按钮陷阱
</p>
<p>在宿主模式下启动应用时，会在浏览器任务栏上看到&#8220;刷新&#8221;按钮。要是摁了这个按钮，GWT就会把修改过的Java
客户端源代码重新编译成Java字节码（作为.gwt.-cache/bytecode目录中的.tmp文件），然后重新装入模块。可以使用这个按钮来缩
短编辑&#8594;编译&#8594;调试周期，但在使用这项特性时要牢记几个方面: </p>
<p>● 只有修改过的源代码才重新编译，也就是说，不会为依赖修改过代码的文件生成新的字节码。所以，如果改变了全局常量的值，假设public final int字段的值，不会立即在相关文件看到这个变化。
</p>
<p>● 只有修改过的源代码才由GWT重新编译。这意味着，即便Eclipse IDE里面的&#8220;Project clean&#8221;也帮不上忙; 要影响到所有的相关源代码，譬如通过添加新的空行。
</p>
<p>因为这个过程相当笨拙，笔者的忠告是在修改全局常量时遵循以下四个步骤:
</p>
<p>1．在相应的源文件里面改变public final constant值;
</p>
<p>2．重新编译改变后的源代码;
</p>
<p>3．移除整个&lt; ModuleName&gt;-client/.get-cache/bytecode目录，从而删除GWT缓存内容;
</p>
<p>4、使用Eclipse里面的&#8220;Run
as&#8221;，重新开始启动应用，从而创建带重新编译后字符码的新GWT缓存内容，这种情况下，最好忽视&#8220;刷新&#8221;按钮，不过在有些情况下，删除整个&lt;
ModuleName&gt;-client/.get-cache/bytecode目录后可以使用&#8220;刷新&#8221;按钮。
</p>
<p>在修改服务器端代码时，GWT字节码缓存内容不受影响。不过，嵌入的Tomcat实例会缓存它，因而在使用&#8220;刷新&#8221;按钮后，只有重新开始启动应用后最初改变的代码才会得到认可。所以为了安全起见，改变服务器端代码后，最好还是重新开始启动应用。
</p>
<p style="color: red;">忠告之四: 在宿主模式下读取Servlet Init参数
</p>
<p>在处理数据库系统时，一般不希望服务器小程序源代码中有硬编码的数据库连接参数。通常会从属性文件读取这些参数;
或者更好的是，把它们作为init参数提供给服务器小程序（作为应用的Web.xml文件的一部分）。如果在Web模式下运行应用那没有什么，但在宿主模
式下会出问题，这是由于GWT宿主模式下的服务器小程序处理存在限制。
</p>
<p>好消息是，只要修改由嵌入式Tomcat实例使用的Web.xml文件，就可以解决这个问题。为此，修
改&lt;
ModuleName&gt;-client/tomcat/webapps/ROOT/WEB-INF目录中的Web.xml文件（或者必要时创建一
个）:
除了嵌入式Tomcat的GWTShellServlet映射外，添加带有init参数的上下文部分。因为上下文信息是&#8220;全局性的&#8221;，而不是针对特定的服
务器小程序，在这里只有一部分的init参数信息，或者使用特殊的命名方案，把参数与不同的服务器小程序联系起来。如果使用这个新的web.xml文件，
可以删除src/web/WEB-INF文件夹中的那个旧文件。
</p>
<p>在服务器小程序代码中，访问init参数的方式与Web模式下读取它们的方式一样，譬如final
String host =
getInitParameter("host")。笔者实现这一点的办法就是修改GWT的RemoteServiceServlet，方法跟第二个忠告
里面的如出一辙。现在，只要覆盖GenericServlet的getInitParameter()方法，以便使用
getServletContext()，而不是 getServletConfig()。 </p>
<p>另一个忠告是，如果在宿主模式下和Web模式下测试不同的服务器代码，略过Gant脚本中的GWT编译部分，从&#8220;temp&#8221;位置拷贝编译前的JavaScript代码，则可以节省时间。这适用于客户端代码复杂、编译时间超过10分钟的情形。
</p>
<p style="color: red;">忠告之五: 在浏览器里面显示PDF文件
</p>
<p>大多数实际的Web应用提供了生成及阅读PDF文件的方法。本文假设这个PDF文件由服务器小程序生成，譬如通过
JasperReport。以后只要点击某个超文本链接，就可以在浏览器里面阅读生成的文件。如果想在宿主模式下和Web模式下测试这项特性，建议采取以
下步骤: </p>
<p>1．设计一个RPC接口，接受告诉服务器是在宿主模式下运行还是在Web模式下运行的布尔参数。接口方法会返回的字符串应当带有服务器小程序生成的PDF文件的名称（即文件名的最后一部分）。
</p>
<p>2．根据代码片段4显示的代码，实现服务器小程序代码，这取决于布尔参数&#8220;isScript&#8221;。
</p>
<p>3．在客户端: 在窗口组件代码里面，使用GWT.isScript()参数调用createXyzPDF()方法，从而生成包含服务器小程序结果字符串的外部超文本链接。
</p>
<p>代码片段4显示了接口方法名为createSummaryPDF()的示例。从服务器小程序返回的字符串是&#8220;summary.pdf&#8221;。
</p>
<p>这当然不是处理这种情况的惟一办法，但目前适用于我们这个示例。请注意:
在宿主模式下启动应用之前，必须在&lt; ModuleName&gt;-client project's
src/&#8230;/public文件夹中至少创建一个虚假的&#8220;summary.pdf&#8221;文件（文件名从服务器小程序返回）。不然，在浏览器中点击了超文本链接
后，GWT试图读取PDF文件时，会出现&#8220;HTTP 404－找不到网页&#8221;的信息。
</p>
<p style="color: red;">忠告之六:力求获得无状态服务器
</p>
<p>设计客户机/服务器Web应用时要考虑的一个关键问题就是: 如何处理会话和状态管理？在Web
1.0时代，答案很显然:
会话和状态管理是一个服务器问题。但若使用GWT，就有另一个选择。服务器再也不是只提供HTML内容的&#8220;web&#8221;服务。使用GWT
RPC，服务器现在可以支持只提供结构化数据的服务———在本文示例中，服务由服务器小程序实现。
</p>
<p>那么，GWT对会话和状态管理有何影响呢？GWT的技术领导Bruce Johnson在去年的JAOO大会上指出，若使用GWT，会话管理现在应当是一个客户端问题。附图显示的幻灯片评述了种种变化。 <br />
</p>
<p><img alt="" src="http://www.cnitblog.com/images/cnitblog_com/rd416/b07_3t2.jpg" width="650" height="506" /></p>
<p>在本文的JUnit2MR
GWT应用中，笔者一开始使用传统方法来处理服务器小程序中的会话状态。但这是相当笨拙的任务，于是寻找另一种选择。因此，看了Bruce的幻灯片后，决
定重新设计整个应用。但这一步需要改变所有RPC接口、缓存策略; 最重要的是，还要改变所有的服务器小程序。因此笔者的建议是:
及早考虑在何处实施会话和状态管理，不妨试试Bruce Johnson的诀窍。最终会收到成效。
</p>
<p>由于这个决定，客户端对象之间有了更多的联系。于是笔者使用了有名的GoF中介者模式（mediator
pattern）。不过，在客户端有一些JDK
1.4和GWT运行库的限制。因此，重新实现了PropertyChangeEvent类和中介者支持，来处理监听程序注册和消息广播。
</p>
<p style="color: red;">忠告之七: 使用Selenium实现GWT Web测试的自动化
</p>
<p>Selenium是一种开源工具，它能够轻松测试包含丰富、互动的客户端内容的Web应用。 所以，它非常适用于测试像用GWT创建的应用那样的Ajax应用。
</p>
<p>当然，GWT里面仍有JUnit和JUnit支持功能，特别是针对系统的异步部分。这里着重介绍
Selenium，因为它易于使用（至少它的IDE是这样）、功能强大。最后但并非最不重要的一点是，它与JUnit有许多共同之处。可以使用
Selenium
IDE来记录GUI用例，然后使用其&#8220;Play&#8221;特性来运行记录下来的操作。每个操作之后跟着类似JUnit的&#8220;assert&#8221;命令，负责确认页面上的某
些文本。该IDE是Firefox的扩展插件，但务必要使用最新版本的Selenium: Selenium IDE 0 .8
.7，因为它包含了&#8220;waitFor&#8230;&#8221;命令的重大修正版。说到测试Ajax应用，这些命令以及&#8220;pause&#8221;命令非常重要。
</p>
<p style="color: red;">忠告之八: 使用Groovy Gant脚本部署应用
</p>
<p>在GWT宿主模式下试运行应用，这确实很好，但把应用部署到应用服务器上或者类似Tomcat的服务器小程序容器
上，GWT的真实功能才会体现出来。在这一步，需要创建一个war文件，它会自动拷贝到Tomcat&#8220;webapps&#8221;目录。当然，可以使用Ant和
ant-contrib进行所有必要的准备、编译、拷贝及其他任务。但由于Ant脚本变得更复杂后，
ant-contrib控制结构和属性regex处理有一点笨拙。于是可以使用集Groovy和Ant两者之所长的Gant。安装Groovy和Gant
用不了10分钟，然后，使用来自&#8220;build.properties&#8221;文件的普通属性，即可定制&#8220;build.gant&#8221;脚本。（小黑编译）
</p>
<p align="right">（计算机世界报 2007年6月25日 第24期 B22、B23）
</p>
<img src ="http://www.blogjava.net/sealyu/aggbug/311099.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> 2010-01-28 17:47 <a href="http://www.blogjava.net/sealyu/archive/2010/01/28/311099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GWT Tutorial – Transport Objects over RPC – GWT Object Serialization</title><link>http://www.blogjava.net/sealyu/archive/2010/01/22/310548.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Fri, 22 Jan 2010 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/01/22/310548.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/310548.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/01/22/310548.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/310548.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/310548.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: IntroductionGWT is a Java framework that allows you to easily develop AJAX(Asynchronous JavaScript and XML) based web applications. This tutorialwill teach you how to create and use Serializable...&nbsp;&nbsp;<a href='http://www.blogjava.net/sealyu/archive/2010/01/22/310548.html'>阅读全文</a><img src ="http://www.blogjava.net/sealyu/aggbug/310548.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> 2010-01-22 17:33 <a href="http://www.blogjava.net/sealyu/archive/2010/01/22/310548.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GWT Right-click Context Menu</title><link>http://www.blogjava.net/sealyu/archive/2010/01/20/310186.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Wed, 20 Jan 2010 01:21:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/01/20/310186.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/310186.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/01/20/310186.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/310186.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/310186.html</trackback:ping><description><![CDATA[<div>
<p>The <a modo="false" href="http://code.google.com/webtoolkit/"><font color="#b85b5a">Google Web Toolkit</font></a>
has been out for a while now, and yet there is still basic
functionality that is missing from the toolkit. Don&#8217;t get me started on
the lack of draggable/resizable columns for the FlexTable, because
that&#8217;s a rant and a half. Given that GWT&#8217;s event handling model isn&#8217;t
bad, you&#8217;d think they&#8217;d have included from the get-go the ability to
handle right-clicks and bringing up a <a href="http://en.wikipedia.org/wiki/Context_menu"><font color="#b85b5a">context menu or popup menu</font></a>.
Well, even with 1.6 on the doorstep it seems they forgot again or just
don&#8217;t care.&nbsp;&nbsp; Now some people will spout out &#8220;web apps don&#8217;t need or
shouldn&#8217;t have right-clicks handled or context menus overridden&#8221;&#8230;&#8230;and
for those I say STFU! Web apps are used for more than just banking,
news, forums and dare I say blogs. The browser is becoming the new
medium for running applications and just because an application is
running in a browser doesn&#8217;t mean we should limit functionality. That&#8217;s
about as narrow minded as saying that we&#8217;ve only had one mouse button
for this long, why add a second one? Duh!</p>
<p>Anyway, enough with the blabbing. I&#8217;ve put together a simple example
to add a right click context menu and override the default browser
context menu using GWT. <br />
<br />
In the box below you can try it out, right-click in there and you can demo it.</p>
<table>
    <tbody>
        <tr>
            <td> <br />
            </td>
            <td> <br />
            </td>
        </tr>
    </tbody>
</table>
<p>In case the iframe doesn&#8217;t show up in your browser you can see and try the example <a href="http://whatwouldnickdo.com/rightclickex/RightClickEx.html"><font color="#b85b5a">here</font></a>.<br />
Now here&#8217;s how it&#8217;s done.</p>
<p>I used a DeckPanel to switch between several panels. The popup
context menu is used to choose. To allow the DeckPanel to catch the
right-click event (and you can also listen for double-clicks and
several other things) I extended the DeckPanel.&nbsp;&nbsp; For simplicity I
added &#8220;Adv&#8221; (Advanced) in front of the several classes I&#8217;ve extended so
this one will be <strong>AdvDeckPanel</strong>. The first thing to do in the constructor is add <strong>sinkEvents()</strong>. Then we&#8217;ll override <strong>onBrowserEvent()</strong> in the class. Here&#8217;s the code:</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre><span style="color: #000000; font-weight: bold;">public</span> AdvDeckPanel<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
sinkEvents<span style="color: #009900;">(</span><span style="color: #003399;">Event</span>.<span style="color: #006633;">ONMOUSEUP</span> <span style="color: #339933;">|</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">ONDBLCLICK</span> <span style="color: #339933;">|</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">ONCONTEXTMENU</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onBrowserEvent<span style="color: #009900;">(</span><span style="color: #003399;">Event</span> event<span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
GWT.<span style="color: #006633;">log</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"onBrowserEvent"</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
event.<span style="color: #006633;">cancelBubble</span><span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><span style="font-style: italic; color: #666666;">//This will stop the event from being propagated</span><br />
<br />
event.<span style="color: #006633;">preventDefault</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">switch</span> <span style="color: #009900;">(</span>DOM.<span style="color: #006633;">eventGetType</span><span style="color: #009900;">(</span>event<span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">ONMOUSEUP</span><span style="color: #339933;">:</span><br />
<br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">(</span>DOM.<span style="color: #006633;">eventGetButton</span><span style="color: #009900;">(</span>event<span style="color: #009900;">)</span> <span style="color: #339933;">==</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">BUTTON_LEFT</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
GWT.<span style="color: #006633;">log</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Event.BUTTON_LEFT"</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
listener.<span style="color: #006633;">onClick</span><span style="color: #009900;">(</span><span style="color: #000000; font-weight: bold;">this</span>, event<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">(</span>DOM.<span style="color: #006633;">eventGetButton</span><span style="color: #009900;">(</span>event<span style="color: #009900;">)</span> <span style="color: #339933;">==</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">BUTTON_RIGHT</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
GWT.<span style="color: #006633;">log</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Event.BUTTON_RIGHT"</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
listener.<span style="color: #006633;">onRightClick</span><span style="color: #009900;">(</span><span style="color: #000000; font-weight: bold;">this</span>, event<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">ONDBLCLICK</span><span style="color: #339933;">:</span><br />
<br />
<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #003399;">Event</span>.<span style="color: #006633;">ONCONTEXTMENU</span><span style="color: #339933;">:</span><br />
<br />
GWT.<span style="color: #006633;">log</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Event.ONCONTEXTMENU"</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">default</span><span style="color: #339933;">:</span><br />
<br />
<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span> <span style="font-style: italic; color: #666666;">// Do nothing</span><br />
<br />
<span style="color: #009900;">}</span><span style="font-style: italic; color: #666666;">//end switch</span><br />
<br />
<span style="color: #009900;">}</span></pre>
</div>
</div>
<p>Notice the two lines in onBrowserEvent():<br />
<strong>event.cancelBubble(true);<br />
event.preventDefault();</strong></p>
<p>These are the two lines that tell the browser not to show it&#8217;s
default context popup menu. Also note that overriding the default
context menu doesn&#8217;t work in all browsers, I&#8217;m not sure if this is a
bug in GWT. If you&#8217;re using firefox then you&#8217;ll have no problems, with
IE you may need to add the following to your html:</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre>&lt;body oncontextmenu="return false;"&gt;</pre>
</div>
</div>
<p>Other than that there&#8217;s just a switch statement that checks the event type, in this case we&#8217;re interested with <strong>ONMOUSEUP</strong>, and we&#8217;ll call the listener&#8217;s <strong>onClick() </strong>or <strong>onRightClick()</strong> based on the Event&#8217;s fields.</p>
<p>AdvDeckPanel also has a reference to AdvClickListener which looks like:</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> AdvClickListener <span style="color: #000000; font-weight: bold;">extends</span> ClickListener <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000066; font-weight: bold;">void</span> onClick<span style="color: #009900;">(</span>Widget sender, <span style="color: #003399;">Event</span> event<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000066; font-weight: bold;">void</span> onRightClick<span style="color: #009900;">(</span>Widget sender, <span style="color: #003399;">Event</span> event<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span></pre>
</div>
</div>
<p>This reference is basically the same as ClickListener, but has a separate method to handle the right-click. I also pass the <strong>Event</strong>
object so I can get the x and y from the click so the context menu
shows up at that location instead of the top-left of the screen.</p>
<p>AdvDeckPanel implements <strong>AdvClickNotifier</strong> which does the same thing as GWT&#8217;s <strong>SourcesClickEvents</strong> interface, but handles the <strong>AdvClickListener</strong> instead.</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> AdvClickNotifier <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> addClickListener<span style="color: #009900;">(</span>AdvClickListener listener<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> removeClickListener<span style="color: #009900;">(</span>AdvClickListener listener<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span></pre>
</div>
</div>
<p>So, once you have your widget (in this case the AdvDeckPanel) and
the listeners set up to handle the right-click, then we add in the code
to build the popup menu and commands that go with it. I put all of this
in the <strong>EntryPoint</strong>. I have three widgets (panels) and a <strong>Command</strong> for each like this:</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre><span style="color: #000000; font-weight: bold;">private</span> AdvDeckPanel deckPanel <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AdvDeckPanel<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">private</span> PopupPanel popupPanel <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PopupPanel<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">private</span> VerticalPanel defaultPanel <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> VerticalPanel<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">private</span> SimplePanel imagePanel <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimplePanel<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">private</span> SimplePanel sponserPanel <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimplePanel<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
Command showAlertCommand <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Command<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> execute<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
deckPanel.<span style="color: #006633;">showWidget</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupPanel.<span style="color: #006633;">hide</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003399;">Window</span>.<span style="color: #006633;">alert</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Hope this example helps."</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<span style="color: #009900;">}</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
Command showImageCommand <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Command<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> execute<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
deckPanel.<span style="color: #006633;">showWidget</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupPanel.<span style="color: #006633;">hide</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<span style="color: #009900;">}</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
Command showSponserCommand <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Command<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> execute<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
deckPanel.<span style="color: #006633;">showWidget</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupPanel.<span style="color: #006633;">hide</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<span style="color: #009900;">}</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>A <strong>Command</strong> is called when the <strong>MenuItem</strong> is clicked.</p>
<p>Now the code to build the menu, link the commands, and handle the right-click:</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> createPopupMenu<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #003399;">MenuBar</span> popupMenuBar <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">MenuBar</span><span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003399;">MenuItem</span> alertItem <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">MenuItem</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Show alert"</span>, <span style="color: #000066; font-weight: bold;">true</span>, showAlertCommand<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003399;">MenuItem</span> imageItem <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">MenuItem</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Show Oliver "</span>, <span style="color: #000066; font-weight: bold;">true</span>, showImageCommand<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #003399;">MenuItem</span> sponserItem <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">MenuItem</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Show sponser "</span>, <span style="color: #000066; font-weight: bold;">true</span>, showSponserCommand<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
popupPanel.<span style="color: #006633;">setStyleName</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"popup"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
alertItem.<span style="color: #006633;">addStyleName</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"popup-item"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
imageItem.<span style="color: #006633;">addStyleName</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"popup-item"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
sponserItem.<span style="color: #006633;">addStyleName</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"popup-item"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
popupMenuBar.<span style="color: #006633;">addItem</span><span style="color: #009900;">(</span>alertItem<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupMenuBar.<span style="color: #006633;">addItem</span><span style="color: #009900;">(</span>imageItem<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupMenuBar.<span style="color: #006633;">addItem</span><span style="color: #009900;">(</span>sponserItem<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<br />
<br />
popupMenuBar.<span style="color: #006633;">setVisible</span><span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupPanel.<span style="color: #006633;">add</span><span style="color: #009900;">(</span>popupMenuBar<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span><br />
<br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onRightClick<span style="color: #009900;">(</span>Widget sender, <span style="color: #003399;">Event</span> event<span style="color: #009900;">)</span> <span style="color: #009900;">{</span><br />
<br />
<span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> DOM.<span style="color: #006633;">eventGetClientX</span><span style="color: #009900;">(</span>event<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> DOM.<span style="color: #006633;">eventGetClientY</span><span style="color: #009900;">(</span>event<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupPanel.<span style="color: #006633;">setPopupPosition</span><span style="color: #009900;">(</span>x, y<span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
popupPanel.<span style="color: #006633;">show</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">}</span></pre>
</div>
</div>
<p>Lastly, to make the menu actually look like a popup menu I modified the CSS like so:</p>
<div style="padding-bottom: 0px;" class="wp_syntax">
<div>
<pre><span style="color: #6666ff;">.popup</span> <span style="color: #00aa00;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00aa00;">:</span> <span style="color: #993333;">gray</span><span style="color: #00aa00;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">border-color</span><span style="color: #00aa00;">:</span> <span style="color: #993333;">gray</span> <span style="color: #993333;">gray</span> <span style="color: #993333;">gray</span> <span style="color: #993333;">gray</span><span style="color: #00aa00;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">border-width</span><span style="color: #00aa00;">:</span> <span style="color: #993333;">1px</span> <span style="color: #993333;">3px</span> <span style="color: #993333;">3px</span> <span style="color: #993333;">1px</span><span style="color: #00aa00;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">border-style</span><span style="color: #00aa00;">:</span> <span style="color: #993333;">solid</span> <span style="color: #993333;">solid</span> <span style="color: #993333;">solid</span> <span style="color: #993333;">solid</span><span style="color: #00aa00;">;</span><br />
<br />
<span style="color: #00aa00;">}</span><br />
<br />
<br />
<br />
<span style="color: #6666ff;">.popup-item</span> <span style="color: #00aa00;">{</span><br />
<br />
<span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00aa00;">:</span> <span style="color: #993333;">normal</span><span style="color: #00aa00;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00aa00;">:</span> <span style="color: #993333;"><span style="color: #cc66cc;">80</span>%</span><span style="color: #00aa00;">;</span><br />
<br />
<span style="color: #00aa00;">}</span></pre>
</div>
</div>
<p>What this does is makes it so the border isn&#8217;t the thick default GWT
blue, and uses a thin border with the right and bottom borders a bit
thicker. This gives the popup that shadowed look.</p>
<p>A couple of books worth checking out are: <a modo="false" href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FGWT-Action-Easy-Google-Toolkit%2Fdp%2F1933988231%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1250784594%26sr%3D8-2&amp;tag=homenick-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325"><font color="#b85b5a">GWT in Action</font></a><font color="#b85b5a"><img style="border-style: none ! important; margin: 0px;" src="http://www.assoc-amazon.com/e/ir?t=homenick-20&amp;l=ur2&amp;o=1" alt="" border="0" width="1" height="1" /></font>and <a modo="false" href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FGWT-Practice-Robert-Cooper%2Fdp%2F1933988290%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1250784594%26sr%3D8-1&amp;tag=homenick-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325"><font color="#b85b5a">GWT in Practice</font></a><font color="#b85b5a"><img style="border-style: none ! important; margin: 0px;" src="http://www.assoc-amazon.com/e/ir?t=homenick-20&amp;l=ur2&amp;o=1" alt="" border="0" width="1" height="1" /><br />
</font><a href="http://whatwouldnickdo.com/wordpress/blog-attachments/right-click-gwt.7z"><font color="#b85b5a">Here&#8217;s the source</font></a> and more links.</p>
<br />
<a stico_default="" title="ShareThis via email, AIM, social bookmarking and networking sites, etc." st_page="home" href="http://hi.baidu.com/wzbg/blog/item/:void%280%29"><span st_page="home"><font color="#b85b5a">ShareThis</font></span></a>
<p>Tags: <a rel="tag" href="http://whatwouldnickdo.com/wordpress/tag/gwt/"><font color="#b85b5a">GWT</font></a>, <a rel="tag" href="http://whatwouldnickdo.com/wordpress/tag/java/"><font color="#b85b5a">Java</font></a>, <a rel="tag" href="http://whatwouldnickdo.com/wordpress/tag/web-dev/"><font color="#b85b5a">web-dev</font></a></p>
<p><small><font color="#aaaaaa">This entry was posted on Tuesday, February 17th, 2009 at 8:12 pm and is filed under </font><a title="View all posts in GWT" rel="category tag" href="http://whatwouldnickdo.com/wordpress/category/gwt/"><font color="#b85b5a">GWT</font></a><font color="#aaaaaa">, </font><a title="View all posts in Java" rel="category tag" href="http://whatwouldnickdo.com/wordpress/category/java/"><font color="#b85b5a">Java</font></a><font color="#aaaaaa">, </font><a title="View all posts in Programming" rel="category tag" href="http://whatwouldnickdo.com/wordpress/category/programming/"><font color="#b85b5a">Programming</font></a><font color="#aaaaaa">. You can follow any responses to this entry through the </font><a href="http://whatwouldnickdo.com/wordpress/370/gwt-right-click-context-menu/feed/"><font color="#b85b5a">RSS 2.0</font></a><font color="#aaaaaa"> feed. You can </font><a href="http://whatwouldnickdo.com/wordpress/370/gwt-right-click-context-menu/#respond"><font color="#b85b5a">leave a response</font></a><font color="#aaaaaa">, or </font><a rel="trackback" href="http://whatwouldnickdo.com/wordpress/370/gwt-right-click-context-menu/trackback/"><font color="#b85b5a">trackback</font></a><font color="#aaaaaa"> from your own site. </font></small></p>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/310186.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> 2010-01-20 09:21 <a href="http://www.blogjava.net/sealyu/archive/2010/01/20/310186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Debug Google Web Toolkit with Struts/Tiles</title><link>http://www.blogjava.net/sealyu/archive/2010/01/15/309666.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Fri, 15 Jan 2010 04:05:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/01/15/309666.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/309666.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/01/15/309666.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/309666.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/309666.html</trackback:ping><description><![CDATA[<p>Ok,
your fresh new GWT user interface is ready, it works great with GWTShell's internal Tomcat and with server-side stubs,
but as you compile and deploy it on your web-app there are problems.</p>
<p>Of course you can debug with a JavaScript debugger (Venkman or Microsoft's Script Debugger),
but generated JavaScript is really complex, for people and for those unstable debuggers.</p>
<p>But, wait, we have a debugger, is our state-of-the-art debugger,
integrated in our IDE and GWT can use it, if only you could run client
into the Shell and server side into your preferred development
envinroment !!!</p>
<p>We could deploy our web-app into the integrated Tomcat, but it's not easy to do (and an hell to mantain)
and also can be that you don't want (or you can't) use Tomcat for your Web Application.</p>
<p>I think that everyone should do his work, so let's Google Shell do
the client, and your application server run the server side code. It's
not difficult, you only need to follow these few steps.</p>
<p>First thing do to it's a little (I promise really little and only
one) change to your GWT code, so that the client will always use
absolute urls for your web-app, allowing us to use the ContextPath
without problems, whatever it's the relative position of your Google
client inside your root context.</p>
<p>To do that we have to register this way the end-point of the remote service:</p>
<pre>	endpoint.setServiceEntryPoint( GWT.getModuleBaseURL()+"/myRemoteService" );</pre>
<p>now we must also remember to change our servlet path inside the GWT module file (*.gwt.xml)
putting the complete service name at the top, in this case <strong>/mypackage.google.GWTClient</strong>:	</p>
<pre>  	&lt;servlet path="/mypackage.google.GWTClient/myRemoteService" class="mypackage.google.server.MyRemoteServiceImpl"/&gt;</pre>
<p>No other change to your client side code, I promise again.
</p>
<p>Now let's start to modify the web-app to run our services. The first thing is to include in our <em>WEB-INF/lib</em> the <strong>gwt-user.jar</strong>.</p>
<p>Unfortunately the one supplied by Google doesn't work, because it
includes the javax.servlet.* classes to simplify the automatic
generation of development projects.</p>
<p>We must strip that out (with an ANT Task obviously):</p>
<textarea readonly="true" cols="100" rows="16">	&lt;property name="original.gwt.jar.lib" value="&lt;path-to&gt;"gwt-user.jar" /&gt;
&lt;property name="temp.dir" value="./tempDir"/&gt;
&lt;target name="stripGWT-lib"&gt;
&lt;mkdir dir="${temp.dir}"/&gt;
&lt;unjar src="${original.gwt.jar.lib}" dest="${temp.dir}"&gt;
&lt;patternset&gt;
&lt;exclude name="javax/**/*.*"/&gt;
&lt;/patternset&gt;
&lt;/unjar&gt;
&lt;jar destfile="${web-inf.lib.dir}/gwt-user.jar" basedir="${temp.dir}"/&gt;
&lt;delete dir="${temp.dir}"/&gt;
&lt;/target&gt;</textarea>
<p>Now we can also add that to our IDE build-path.</p>
<p>Everything is ready to begin the configuration of our web-app,
beginning with the registration of the remote service inside web.xml,
remembering the module name we used in the *.gwt.xml file:</p>
<textarea readonly="true" cols="100" rows="10">	&lt;servlet&gt;
&lt;servlet-name&gt;MyRemoteService&lt;/servlet-name&gt;
&lt;servlet-class&gt;mypackage.google.server.MyRemoteServiceImpl&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;MyRemoteService&lt;/servlet-name&gt;
&lt;url-pattern&gt;/mypackage.google.GWTClient/myRemoteService&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</textarea>
<p>We don't have yet finished, we must also "simulate" one of the call
implemented by GWTServlet, registering its path into web.xml and with
the help of a JSP::</p>
<textarea readonly="true" rows="10" cols="100">	&lt;servlet&gt;
&lt;servlet-name&gt;gwt-hosted&lt;/servlet-name&gt;
&lt;jsp-file&gt;/gwt-hosted.jsp&lt;/jsp-file&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;gwt-hosted&lt;/servlet-name&gt;
&lt;url-pattern&gt;/mypackage.google.GWTClient/gwt-hosted.html&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</textarea>
<p>the
<strong>gwt-hosted.jsp</strong> JSP it's only a simple script with a row of scriptlet that export our web-app context to the GWT client::</p>
<textarea readonly="true" rows="18" cols="100">	&lt;html&gt;
&lt;body&gt;
&lt;script&gt;
var $wnd = parent;
var $doc = $wnd.document;
var q = location.search.substring(1);
var i = q.lastIndexOf("=");
var $moduleName = q;
var $moduleBaseURL = "&lt;%= request.getContextPath()%&gt;/" + $moduleName;
if (i != -1) {
$moduleBaseURL = q.substring(0, i);
$moduleName = q.substring(i+1);
}
parent.__gwt_initHostedModeModule(this, $moduleName);
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</textarea>
<p>We did it !!!!The good thing is that we don't even have to "Compile" our
JavaScript in the destination context during debug. Infact the GWT Shell
callback will always call our Java classes and not the JavaScript code.</p>
<p>So we have together maximum flexibility on client-side project for our debugging purposes,
and only at the very finish of the development cycle we will produce the JavaScript code.</p>
<p>Could we be in a better position as web developer ?</p>
<p>Now some tips about GWT's Shell:</p>
<p>Are we in debug mode or not ? The answer is yes, so we should
configure the Shell log to a more verbose level (if you have used
GWT.log in your code):</p>
<pre>	-logLevel ERROR|WARN|INFO|TRACE|DEBUG|SPAM|ALL</pre>
<p>We should also disable the integrated Tomcat:</p>
<pre>	-noserver</pre>
<p>and configure the Shell to generate JavaScript code directly inside our web-app project:</p>
<pre>	-out &lt;web-app-project-dir&gt;</pre>
<p>Also can be useful to open directly the Shell browser to our web-app
at startup, simply putting the http url as the last parameter of the
command line that start the Shell.</p>
<p>But what if all this it's not enough to solve our problems, may be because the generated JavaScript is not working fine ?
Well, together with much luck, we can try to switch the generation code to DETAILED:</p>
<pre> -style DETAILED</pre>
<p>and use traditional JavaScript debugging tecnique.</p>
<h1>Integrate Google Web Toolkit with Struts/Tiles</h1>
<p>Ok, now everything it's integrated with your web-application and
you're in love with GWT. You did really a great work, a prototype that
it's working fine and looks pretty. But when time comes that you must
put it into your old fashioned Struts/Tiles web-application it stops
working and sure you can't write everything from scratch again, but do
a step after another and start with a single functionality done with
GWT.</p>
<p>Well, I don't know you, but I suffered from this problem, but at the
end, thank to some little tips, I was able to let Struts and GWT not
only to live together, but to cooperate to make my application look
better.</p>
<p>It was like having an old fashioned B&amp;W TV Set and a new HDMI on the same bench, side by side !!!</p>
<p>Well, to achieve this, we have to do some simple steps:</p>
<p> - In <em>web.xml</em> add another Struts <em>action</em> mapping, this time it must be extension based, for instance I choosed *.gwt:</p>
<textarea readonly="true" cols="80" rows="6">		&lt;servlet-mapping&gt;
&lt;servlet-name&gt;action&lt;/servlet-name&gt;
&lt;url-pattern&gt;*.gwt&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</textarea>
<p> - In <em>struts-config.xml</em> write the new Struts <em>action</em>
that will render the GWT page, taking care to put at the top of the
path the complete GWT's module name, so that the script will be able to
find internal files with no problems:</p>
<textarea readonly="true" cols="80" rows="5">        &lt;action path="/mypackage.google.GWTClient/GWTClient"
forward=".my.gwt.application"/&gt;
</textarea>
<p> - (only if you use Tiles as view)Add a <em>Tiles</em> definition that will include GWT's (in my example into the body of the layout JSP):</p>
<textarea readonly="true" cols="80" rows="8">    &lt;definition name=".my.gwt.application" extends=".mainLayout"&gt;
&lt;put name="title"  value="Google Web Toolkit in Tiles" /&gt;
&lt;put name="body"
value="/mypackage.google.GWTClient/GWTClient.html" /&gt;
&lt;put name="header"   value="/WEB-INF/jsp/header.jsp" /&gt;
&lt;/definition&gt;
</textarea>
<p> - (if you used filters for Struts Action mapping)Update
your filters so that they will be able to do their work also with the
new GWT module:</p>
<textarea readonly="true" cols="80" rows="5">	&lt;filter-mapping&gt;
&lt;filter-name&gt;AuthenticationFilter&lt;/filter-name&gt;
&lt;url-pattern&gt;*.gwt&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</textarea>
<p>That's all, the game is made.</p>
<br />
<strong>P.S.:</strong>the same applies if you used Spring MVC.
<h1>Integrating it also with Spring/Hibernate</h1>
<p>The life-cycle of a GWT's Service is managed by your
servlet-container, because as a design choice Google opted for the
portabily and simplicity of the <strong>Servlet</strong> model.<br />
In our code this mean that our service implementations will all inherit (indirectly) from <em>HttpServlet</em>. This means also that to integrate them in our Spring managed container we have to play dirty. I decided to use <strong>static</strong> property inside our Google Service implementation, so that Spring will be able to assign it at startup time.<br />
Pratically, if we want to inject something in GWT's service <em>mypackage.google.server.MyRemoteServiceImpl</em>'s  <em>myProperty</em> property, it's enough to declare it static:</p>
<textarea rows="3" cols="100" readonly="true">	private static MyProperty myProperty;
</textarea>
<p>Then to let Spring works, we also need an instance setter:</p>
<textarea rows="5" cols="120" readonly="true">	public void setMyProperty(MyProperty mp) // remember, myProperty is static, you can't use this
{
myProperty = mp;
}
</textarea>
<p>In our <em>applicationContext.xml</em> we can inject the <em>myPropertyBean</em> Bean simply with a dummy bean declaration of the GWT implementation class:</p>
<textarea rows="4" cols="100" readonly="true">	&lt;bean id="myGWTService" class="mypackage.google.server.MyRemoteServiceImpl"&gt;
&lt;property name="myProperty"&gt;&lt;ref local="myPropertyBean"/&gt;&lt;/property&gt;
&lt;/bean&gt;
</textarea>
<p>This works because at startup Spring will instantiate an
instance of the MyRemoteServiceImpl class, this instance will never be
used by the servlet-container, but the bean property is contained into
a static variable, so <strong>every</strong> instance will have it !!!<br />
Now, if your business bean <em>myPropertyBean</em> uses <strong>Hibernate</strong> and you usually use Spring's <strong>OpenSessionInView</strong><em>Filter/Interceptor</em>
to manage your Session, you need a further step and use an AOP
Interceptor. But we are lucky in this, because all is done by Spring
out-of-the-box only with few lines of configuration::</p>
<textarea rows="40" cols="120" readonly="true">	&lt;!-- Our Propagation policy --&gt;
&lt;bean id="matchAllWithPropReq"
class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource"&gt;
&lt;property name="transactionAttribute"&gt;&lt;value&gt;PROPAGATION_REQUIRED&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- Match them all interceptor --&gt;
&lt;bean id="matchAllTxInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"&gt;
&lt;property name="transactionManager"&gt;&lt;ref bean="transactionManager"/&gt;&lt;/property&gt;
&lt;property name="transactionAttributeSource"&gt;&lt;ref bean="matchAllWithPropReq"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- This AutoProxyCreator bean will let us declaratively decide which beans will have the transaction
managed with PROPAGATION_REQUIRED --&gt;
&lt;bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"&gt;
&lt;property name="interceptorNames"&gt;
&lt;list&gt;
&lt;idref local="matchAllTxInterceptor"/&gt;
&lt;idref bean="myHibernateInterceptor"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;property name="beanNames"&gt;
&lt;list&gt;
&lt;idref local="myPropertyBean"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;!--  This is the bean that, if it doesn't exist, create and then close Hibernate Session --&gt;
&lt;bean id="myHibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor"&gt;
&lt;property name="sessionFactory"&gt;&lt;ref local="sessionFactory"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;
&lt;property name="sessionFactory"&gt;&lt;ref local="sessionFactory"/&gt;&lt;/property&gt;
&lt;/bean&gt;
</textarea>
<p>With this configuration, if <em>myPropertyBean</em> is used
outside a transaction scope, a new Hibernate transaction will be
created and assigned to it. In our case this is also the span of the
Hibernate's Session (thanks to HibernateTransactionManager). The <em>myHibernateInterceptor</em> will also take charge of eventually close the Session at the end of the business method.</p>
<p>
<a href="http://www.jroller.com/page/masini?entry=template_project_for_gwt_with">continue here...</a>
</p>
<br />
<img src ="http://www.blogjava.net/sealyu/aggbug/309666.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> 2010-01-15 12:05 <a href="http://www.blogjava.net/sealyu/archive/2010/01/15/309666.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Integrating GWT with Spring Security</title><link>http://www.blogjava.net/sealyu/archive/2010/01/15/309637.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Fri, 15 Jan 2010 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/01/15/309637.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/309637.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/01/15/309637.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/309637.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/309637.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Yesterday, I wrote about How to do cross-domain GWT RPC with a ProxyServlet. Today I'll be discussinghow to modify the ProxyServlet to authenticate with Spring Security. For the application I'm work...&nbsp;&nbsp;<a href='http://www.blogjava.net/sealyu/archive/2010/01/15/309637.html'>阅读全文</a><img src ="http://www.blogjava.net/sealyu/aggbug/309637.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> 2010-01-15 09:39 <a href="http://www.blogjava.net/sealyu/archive/2010/01/15/309637.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>