Sie sind auf Seite 1von 81

August1

GOOGLE PROJECT

2008

ThisBookismeantjusttobeaguideforthosewhowishtodevelop applicationsusingGooglesDeveloper.

Contents
Developer's Guide

Getting started Fundamentals User Interfaces Remote Procedure Calls Unit Testing Internationalization JavaScript Native Interface (JSNI) JRE Emulation GWT Class API

Complied By Sivasankar

Getting Started

Installing Google Web Toolkit Building a Sample Application Creating an Application from Scratch (without Eclipse) Creating an Application from Scratch (with Eclipse)

Installing Google Web Toolkit


1. Install the Java SDK. If you don't have a recent version of the Java SDK installed, download and install Sun Java Standard Edition SDK. 2. Download Google Web Toolkit. Download the Google Web Toolkit package for your operating system. 3. Unzip the Google Web Toolkit package. On Windows, extract the files from gwt-windows-1.4.62.zip with a program like WinZip. On Mac and Linux, you can unpack the package with a command like
tar xvzf gwt-mac-1.4.62.tar.gz

4. Done! Start using Google Web Toolkit. GWT doesn't have an installer application. All the files you need to run and use GWT are located in the extracted directory. The main application you'll need to use GWT is applicationCreator, which is described below. It may be easiest to start out by building one of the sample applications shipped with GWT.

Building a Sample Application


All the sample applications are in the samples/ directory in your GWT package. Each sample has a script you can run to start it in hosted mode and a script you can use to compile it into JavaScript and HTML to run it web mode.

Running in Hosted Mode


To run the Kitchen Sink sample in hosted mode, navigate to the samples/KitchenSink/ directory and run the KitchenSink-shell script. This will open the GWT browser with the Kitchen Sink application running inside:

Since you're running in hosted mode, the application is running in the Java Virtual Machine (JVM). This is typically the mode you'll use to debug your applications.

Running in Web Mode


To run the application in web mode, compile the application by running the KitchenSinkcompile script. The GWT compiler will generate a number of JavaScript and HTML files from the Kitchen Sink Java source code in the www/ subdirectory. To see the application, open the file www/com.google.gwt.sample.kitchensink.KitchenSink/KitchenSink.html in your favorite web browser.

Since you've compiled the project, you're now running pure JavaScript and HTML that should work in IE, Firefox, or Safari. If you were to deploy the Kitchen Sink example project in production, you would distribute the files in your www/com.google.com.google.gwt.sample.kitchensink.KitchenSink/ directory to your web servers.

Make a Few Changes


The source code for Kitchen Sink is in the src/ subdirectory. Try closing your browser windows, and open the file src/com/google/gwt/sample/kitchensink/client/Info.java in a text editor. Line 26 of the file is the first line of the static initialization method for the first tab in the Kitchen Sink application ("Intro"):
return new SinkInfo("Intro", "<h2>Introduction to the Kitchen Sink.</h2>") {

Change the second string from "<h2>Introduction to the Kitchen Sink.</h2>" to "<h2>Foo bar</h2>":
return new SinkInfo("Intro", "<h2>Foo bar</h2>") {

Now, save the file and simply click "Refresh" in the hosted mode application to see your recent change (if you previously closed hosted mode, go ahead and re-run the KitchenSink-shell script). The header should now say "Foo bar" instead of "Introduction to the Kitchen Sink.":

Creating an Application from Scratch (without Eclipse)


GWT ships with a command line utility called applicationCreator that automatically generates all the files you'll need in order to start a GWT project. It can also generate Eclipse project files and launch config files for easy hosted mode debugging, as described below. Based on the recommended GWT project structure, your main GWT application class should be in a subpackage client. You can create a new application called MyApplication with the command:
applicationCreator com.mycompany.client.MyApplication

The applicationCreator script will generate a number of files in src/com/mycompany/, including some basic "Hello, world" functionality in the class src/com/mycompany/client/MyApplication.java. The script also generates a hosted mode launch script called MyApplication-shell and a compilation script called MyApplicationcompile, just like the sample application above. To run your newly created application in hosted mode, run the MyApplication-shell script:

Try editing the files src/com/mycompany/client/MyApplication.java and src/com/mycompany/public/MyApplication.html to see how it changes your application.

Creating an Application from Scratch (with Eclipse)


GWT ships with a command line utility called applicationCreator that automatically generates all the files you'll need in order to start a GWT project. It can also generate Eclipse project files and launch config files for easy hosted mode debugging. To generate an Eclipse project for a new application, first use the projectCreator script to generate a shell Eclipse project for your application:
projectCreator -eclipse MyProject

Then generate your GWT application as described above, but with an additional -eclipse flag specifying the name of your Eclipse project:
applicationCreator -eclipse MyProject com.mycompany.client.MyApplication

When you're done with these scripts, in addition to the MyApplication-shell and MyApplication-compile scripts, you should see .project, .classpath, and MyApplication.launch files in your current directory. To open your project in Eclipse, launch Eclipse and click the File -> Import menu. Choose "Existing Projects into Workspace" in the first screen of the wizard, and enter the directory in which you genetrated the .project file in the next screen of the wizard. When you are complete, you should see your GWT project loaded into your Eclipse workspace:

Just click the green "Run" button at the top of the window to start your project in hosted mode.

Fundamentals
Core GWT concepts such as compiling Java source into JavaScript, debugging, cross-browser support, and defining modules.

Contents

GWTCompiler o LanguageSupport o RuntimeLibrarySupport CrossbrowserSupport DebugginginHostedMode DeploymentinWebMode HTMLHostPages ClientsideCode ServersideCode ProjectStructure Modules o ModuleXMLFormat o AutomaticResourceInclusion o FilteringPublicPackages CommandlineTools o projectCreator o applicationCreator o junitCreator o i18nCreator o benchmarkViewer

GWT Compiler
TheheartofGWTisacompilerthatconvertsJavasourceintoJavaScript,transformingyourworkingJava applicationintoanequivalentJavaScriptapplication.Generallyspeaking, 1. IfyourGWTapplicationcompilesandrunsinhostedmodeasyouexpect 2. AndGWTcompilesyourapplicationintoJavaScriptoutputwithoutcomplaint, 3. Thenyourapplicationwillworkthesamewayinawebbrowserasitdidinhostedmode. TheGWTcompilersupportsthevastmajorityoftheJavalanguageitself.TheGWTruntimelibrary emulatesarelevantsubsetoftheJavaruntimelibrary.

Language Support
GWTcompilesJavasourcethatiscompatiblewithJ2SE1.4.2orearlier.

Intrinsictypes
byte,char,short,int,long,float,double,Object,String,andarraysaresupported.

However,thereisno64bitintegraltypeinJavaScript,sovariablesoftypelongaremapped ontoJavaScriptdoubleprecisionfloatingpointvalues.Toensuremaximumconsistency betweenhostedmodeandwebmode,werecommendthatyouuseintvariables.

Exceptions
try,catch,finallyanduserdefinedexceptionsaresupportedasnormal,although Throwable.getStackTrace()isnotsupportedforwebmode.SeeThrowableforadditional

details.

Assertions TheGWTcompilerparsesJavaassertstatements,butitdoesnotemitcodeJavaScriptcode forthem.

MultithreadingandSynchronization JavaScriptinterpretersaresinglethreaded,sowhileGWTsilentlyacceptsthesynchronized keyword,ithasnorealeffect.Synchronizationrelatedlibrarymethodsarenotavailable, includingObject.wait(),Object.notify(),andObject.notifyAll()

Reflection Formaximumefficiency,GWTcompilesyourJavasourceintoamonolithicscript,anddoesnot supportsubsequentdynamicloadingofclasses.Thisandotheroptimizationsprecludegeneral supportforreflection.Itispossibletoqueryanobjectforitsclassnameusing GWT.getTypeName(Object).

Finalization JavaScriptdoesnotsupportobjectfinalizationduringgarbagecollection,soGWTisn'tabletobe honorJavafinalizersinwebmode.

StrictFloatingPoint TheJavalanguagespecificationpreciselydefinesfloatingpointsupport,includingsingle precisionanddoubleprecisionnumbersaswellasthestrictfpkeyword.GWTdoesnot supportthestrictfpkeywordandcan'tensureanyparticulardegreeoffloatingpoint precisionintranslatedcode,soyoumaywanttoavoidcalculationsinclientsidecodethat requireaguaranteedleveloffloatingpointprecision.

Runtime Library Support


GWTsupportsonlyasmallsubsetoftheclassesavailableintheJava2StandardandEnterpriseEdition libraries,astheselibrariesarequitelargeandrelyonfunctionalitythatisunavailablewithinweb browsers.TofindoutexactlywhichclassesandmethodsaresupportedforcoreJavaruntimepackages, seetheAPIreferenceforjava.langandjava.util,whichlistssupportedclassesandcontainsnotes onbehavioraldifferencesfromthestandardJavaruntime.

Some specific areas in which GWT emulation differs from the standard Java runtime:

RegularExpressions ThesyntaxofJavaregularexpressionsissimilar,butnotidentical,toJavaScriptregular expressions.Forexample,thereplaceAllandsplitmethodsuseregularexpressions.So,you'll probablywanttobecarefultoonlyuseJavaregularexpressionsthathavethesamemeaningin JavaScript.

Serialization JavaserializationreliesonafewmechanismsthatarenotavailableincompiledJavaScript,such asdynamicclassloadingandreflection.Asaresult,GWTdoesnotsupportstandardJava serialization.Instead,GWThasanRPCfacilitythatprovidesautomaticobjectserializationtoand fromtheserverforthepurposeofinvokingremotemethods.

Tip You'llsaveyourselfalotoffrustrationifyoumakesurethatyouuseonlytranslatableclassesinyour clientsidecodefromtheverybeginning.Tohelpyouidentifyproblemsearly,yourcodeischecked againsttheJREemulationlibrarywheneveryouruninhostedmode.Asaresult,mostusesof unsupportedlibrarieswillbecaughtthefirsttimeyouattempttorunyourapplication.So,runearlyand often.

Cross-browser Support
GWTshieldsyoufromworryingtoomuchaboutcrossbrowserincompatibilities.Ifyousticktobuiltin widgetsandcomposites,yourapplicationswillworksimilarlyonthemostrecentversionsofInternet Explorer,Firefox,andSafari.(Opera,too,mostofthetime.)DHTMLuserinterfacesareremarkably quirky,though,somakesuretotestyourapplicationsthoroughlyoneverybrowser.

Whenever possible, GWT defers to browsers' native user interface elements. For example, GWT's Button widget is a true HTML <button> rather than a synthetic button-like widget built, say, from a <div>. That means that GWT buttons render appropriately in different browsers and

on different client operating systems. We like the native browser controls because they're fast, accessible, and most familiar to users. When it comes to styling web applications, CSS is ideal. So, instead of attempting to encapsulate UI styling behind a wall of least-common-denominator APIs, GWT provides very few methods directly related to style. Rather, developers are encouraged to define styles in stylesheets that are linked to application code using style names. In addition to cleanly separating style from application logic, this division of labor helps applications load and render more quickly, consume less memory, and even makes them easier to tweak during edit/debug cycles since there's no need to recompile for style tweaks.

Debugging in Hosted Mode


Youwillspendmostofyourdevelopmenttimeworkinginhostedmode,whichmeansthatyouare interactingwithyourGWTapplicationwithoutithavingbeentranslatedintoJavaScript.Anytimeyou edit,run,anddebugapplicationsfromaJavaintegrateddevelopmentenvironment(IDE),youare workinginhostedmode.Whenrunninginhostedmode,theJavaVirtualMachine(JVM)isactually executingyourapplicationcodeascompiledJavabytecode,usingGWTplumbingtoautomatean embeddedbrowserwindow.Byremaininginthistraditional"codetestdebug"cycle,hostedmodeisby farthemostproductivewaytodevelopyourapplicationquickly.

To launch a hosted mode session, your startup class should be com.google.gwt.dev.GWTShell, found in gwt-dev-windows.jar (or gwt-dev-linux.jar).
Tip Inhostedmode,theGWTdevelopmentshelllooksformodules(andthereforeclientsidesource)using theJVM'sclasspath.Makesuretoaddyoursourcedirectoriesfirstinyourclasspathwhenrunningthe developmentshell.

Deployment in Web Mode


Asyoumovefromdevelopmentintoendtoendtestingandproduction,youwillbegintointeractwith yourapplicationinwebmodemoreoften.Webmodereferstoaccessingyourapplicationfromanormal browserwhereitrunsaspureJavaScriptasitisultimatelyintendedtobedeployed.

To create a web mode version of your module, you compile it using either the "Compile/Browse" button available in the hosted browser window or the command-line compiler com.google.gwt.dev.GWTCompiler. Web mode demonstrates what makes GWT unusual: when your application is launched in web mode, it runs completely as JavaScript and does not require any browser plug-ins or JVM.

HTML Host Pages


AnyHTMLpagecontainingtheproperincantationcanincludecodecreatedwithGWT,referredtoasa hostpage.AtypicalHTMLhostpagelookslikethis:
<html> <head>

<!-- Properties can be specified to influence deferred binding --> <meta name='gwt:property' content='locale=en_UK'>

<!-- Stylesheets are optional, but useful --> <link rel="stylesheet" href="Calendar.css">

<!-- Titles are optional, but useful --> <title>Calendar App</title>

</head> <body>

<!-- The fully-qualified module name, followed by 'nocache.js' --> <script language="javascript" src="com.example.cal.Calendar.nocache.js"></script>

<!-- Include a history iframe to enable full GWT history support --> <!-- (the id must be exactly as shown) <iframe src="javascript:''" id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe> -->

</body> </html>

ThestructurewasdesignedtomakeiteasytoaddGWTfunctionalitytoexistingwebapplicationswith onlyminorchanges.

Client-side Code
Yourapplicationissentacrossanetworktoauser,whereitrunsasJavaScriptinsidehisorherweb browser.Everythingthathappenswithinyouruser'swebbrowserisreferredtoasclientsideprocessing. Whenyouwriteclientsidecodethatisintendedtoruninthewebbrowser,rememberthatitultimately becomesJavaScript.Thus,itisimportanttouseonlylibrariesandJavalanguageconstructsthatcanbe translated.

Server-side Code
Everythingthathappenswithinyourservercomputerisreferredtoasserversideprocessing.When yourapplicationneedstointeractwithyourserver(forexample,toloadorsavedata),itmakesaclient siderequest(fromthebrowser)acrossthenetworkusingaremoteprocedurecall(RPC).While processinganRPC,yourserverisexecutingserversidecode. Tip GWTdoesn'tmeddlewithyourabilitytorunJavabytecodeonyourserverwhatsoever.Serversidecode doesn'tneedtobetranslatable,soyou'refreetouseanyJavalibraryyoufinduseful.

Project Structure
GWTprojectsareoverlaidontoJavapackagessuchthatmostoftheconfigurationcanbeinferredfrom theclasspathandyourmoduledefinitions.

If you are starting a GWT project from scratch, you should use the standard GWT package layout, which makes it easy to differentiate client-side code from server-side code. For example, suppose your new project is called "Calendar". The standard package layout would look like this:
Package
com/example/cal/

Purpose Theprojectrootpackagecontains moduleXMLfiles Clientsidesourcefilesandsubpackages Serversidecodeandsubpackages Staticresourcesthatcanbeserved publicly

com/example/cal/client/ com/example/cal/server/

com/example/cal/public/

and examples files would be arranged like so:


File Purpose Acommonbasemodulefor yourprojectthatinherits
com.google.gwt.user.Use rmodule

com/example/cal/Calendar.gwt.xml

Inheritsthe
com/example/cal/CalendarApp.gwt.xml com.example.cal.Calenda rmodule(above)andaddsan

entrypointclass
com/example/cal/CalendarTest.gwt.xml

Amoduledefinedbyyour project ClientsideJavasourceforthe entrypointclass AnRPCserviceinterface definedinasubpackage ServersideJavasourcethat

com/example/cal/client/CalendarApp.java

com/example/cal/client/spelling/SpellingService.java

com/example/cal/server/spelling/SpellingServiceImpl.ja implementsthelogicofthe va

spellingservice

com/example/cal/public/Calendar.html

AnHTMLpagethatloadsthe calendarapp Astylesheetthatstylesthe calendarapp Alogo

com/example/cal/public/Calendar.css

com/example/cal/public/images/logo.gif

Tip TheeasiestwaytocreateaGWTprojectfromscratchistousetheprojectCreatorscript.

Modules
IndividualunitsofGWTconfigurationareXMLfilescalledmodules.Amodulebundlestogetherallthe configurationsettingsthatyourGWTprojectneeds,namely

Inheritedmodules Anentrypointapplicationclassname;theseareoptional,althoughanymodulereferredtoin HTMLmusthaveatleastoneentrypointclassspecified Sourcepathentries Publicpathentries Deferredbindingrules,includingpropertyprovidersandclassgenerators

Modulesmayappearinanypackageinyourclasspath,althoughitisstronglyrecommendedthatthey appearintherootpackageofastandardprojectlayout.

Entry-Point Classes
AmoduleentrypointisanyclassthatisassignabletoEntryPointandthatcanbeconstructedwithout parameters.Whenamoduleisloaded,everyentrypointclassisinstantiatedandits EntryPoint.onModuleLoad()methodgetscalled.

Source Path
Modulescanspecifywhichsubpackagescontaintranslatablesource,causingthenamedpackageandits subpackagestobeaddedtothesourcepath.Onlyfilesfoundonthesourcepatharecandidatestobe translatedintoJavaScript,makingitpossibletomixclientsideandserversidecodetogetherinthe sameclasspathwithoutconflict.

When module inherit other modules, their source paths are combined so that each module will have access to the translatable source it requires.

Public Path
Modulescanspecifywhichsubpackagesarepublic,causingthenamedpackageanditssubpackagesto beaddedtothepublicpath.WhenyoucompileyourapplicationintoJavaScript,allthefilesthatcanbe foundonyourpublicpatharecopiedtothemodule'soutputdirectory.Theneteffectisthatuservisible URLsneednotincludeafullpackagename.

When module inherit other modules, their public paths are combined so that each module will have access to the static resources it expects.

Module XML Format


ModulesaredefinedinXMLfileswhosefileextensionis.gwt.xml.ModuleXMLfilesshouldresidein yourproject'srootpackage.

If you are using the standard project structure, your module XML can be as simple as this:

<module> <inherits name="com.google.gwt.user.User"/> <entry-point class="com.example.cal.client.CalendarApp"/> </module>

Loading Modules
ModuleXMLfilesarefoundontheJavaclasspath,referencedbytheirlogicalmodulenamesfromhost pagesandbybeinginheritedbyothermodules.

Modules are always referred to by their logical names. The logical name of a module is of the form pkg1.pkg2.ModuleName (although any number of packages may be present) and includes neither the actual file system path nor the file extension. For example, the logical name of a module XML file located at
~/src/com/example/cal/Calendar.gwt.xml

is
com.example.cal.Calendar

Available Elements
<inheritsname="logicalmodulename"/> Inheritsallthesettingsfromthespecifiedmoduleasifthecontentsoftheinheritedmodule's XMLwerecopiedverbatim.Anynumberofmodulescanbeinheritedinthismanner. <entrypointclass="classname"/> Specifiesanentrypointclass.Anynumberofentrypointclassescanbeadded,includingthose frominheritedmodules. <sourcepath="path"/> AddspackagestothesourcepathbycombiningthepackageinwhichthemoduleXMLisfound withthespecifiedpathtoasubpackage.AnyJavasourcefileappearinginthissubpackageor anyofitssubpackagesisassumedtobetranslatable.

If no <source> element is defined in a module XML file, the client subpackage is implicitly added to the source path as if <source path="client"> had been found in the XML. This default helps keep module XML compact for standard project layouts.
<publicpath="path"/>

AddspackagestothepublicpathbycombiningthepackageinwhichthemoduleXMLisfound withthespecifiedpathtoidentifytherootofapublicpathentry.Anyfileappearinginthis packageoranyofitssubpackageswillbetreatedasapubliclyaccessibleresource.The <public>elementsupportspatternbasedfilteringtoallowfinegrainedcontroloverwhich resourcesgetcopiedintotheoutputdirectoryduringaGWTcompile.

If no <public> element is defined in a module XML file, the public subpackage is implicitly added to the public path as if <public path="public"> had been found in the XML. This default helps keep module XML compact for standard project layouts.
<servletpath="urlpath"class="classname"/> ForconvenientRPCtesting,thiselementloadsaservletclassmountedatthespecifiedURL path.TheURLpathshouldbeabsoluteandhavetheformofadirectory(forexample, /spellcheck).YourclientcodethenspecifiesthisURLmappinginacallto ServiceDefTarget.setServiceEntryPoint(String).Anynumberofservletsmaybeloadedinthis manner,includingthosefrominheritedmodules. <scriptsrc="jsurl"/> AutomaticallyinjectstheexternalJavaScriptfilelocatedatthelocationspecifiedbysrc.See automaticresourceinclusionfordetails. <stylesheetsrc="cssurl"/> AutomaticallyinjectstheexternalCSSfilelocatedatthelocationspecifiedbysrc.Seeautomatic resourceinclusionfordetails. <extendpropertyname="clientpropertyname"values="commaseparatedvalues"/> Extendsthesetofvaluesforanexistingclientproperty.Anynumberofvaluesmaybeaddedin thismanner,andclientpropertyvaluesaccumulatethroughinheritedmodules.Youwilllikely onlyfindthisusefulforspecifyinglocalesininternationalization.

Automatic Resource Inclusion


ModulescancontainreferencestoexternalJavaScriptandCSSfiles,causingthemtobeautomatically loadedwhenthemoduleitselfisloaded.

Including External JavaScript


ScriptinclusionisaconvenientwaytoautomaticallyassociateexternalJavaScriptfileswithyour module.UsethefollowingsyntaxtocauseanexternalJavaScriptfiletobeloadedintothehostpage beforeyourmoduleentrypointiscalled.

<script src="js-url"/>

Thescriptisloadedintothenamespaceofthehostpageasifyouhadincludeditexplicitlyusingthe HTML<script>element.ThescriptwillbeloadedbeforeyouronModuleLoad()iscalled.

Including External Stylesheets


StylesheetinclusionisaconvenientwaytoautomaticallyassociateexternalCSSfileswithyourmodule. UsethefollowingsyntaxtocauseaCSSfiletobeautomaticallyattachedtothehostpage.
<stylesheet src="css-url"/>

Youcanaddanynumberofstylesheetsthisway,andtheorderofinclusionintothepagereflectsthe orderinwhichtheelementsappearinyourmoduleXML.

Inclusion and Module Inheritance


Moduleinheritancemakesresourceinclusionparticularlyconvenient.Ifyouwishtocreateareusable librarythatreliesuponparticularstylesheetsorJavaScriptfiles,youcanbesurethatclientsofyour libraryhaveeverythingtheyneedautomaticallybyinheritingfromyourmodule. Tip VersionsofGWTpriorto1.4requiredascriptreadyfunctiontodeterminewhenanincludedscriptwas loaded.Thisisnolongerrequired;allincludedscriptswillbeloadedwhenyourapplicationstarts,inthe orderinwhichtheyaredeclared.

Filtering Public Packages


The<public>elementsupportscertainattributesandnestedelementstoallowpatternbased inclusionandexclusion.ItfollowsthesamerulesasAnt'sFileSetelement.Pleaseseethe documentationforFileSetforageneraloverview.

The <public> element does not support the full FileSet semantics. Only the following attributes and nested elements are currently supported:

Theincludesattribute Theexcludesattribute Thedefaultexcludesattribute Thecasesensitiveattribute Nestedincludetags Nestedexcludetags

Otherattributesandnestedelementsarenotsupported.

Important Thedefaultvalueofdefaultexcludesistrue.Bydefault,thepatternslistedhereareexcluded.

Command-line Tools
GWTcomeswithafewhandycommandlinetoolstogetyouupandrunningquickly.Theyarealso usefulforaddingnewthingstoexistingprojects.Forexample,projectCreatorcouldbeusedtomake anEclipseprojectforoneofthesamplesthatcomeswithGWT.

projectCreator
GeneratesanAntbuildfileorEclipseproject.
projectCreator [-ant projectName] [-eclipse projectName] [-out dir] [overwrite] [-ignore]

-ant -eclipse -out

GenerateanAntbuildfiletocompilesource(.ant.xmlwillbe appended) Generateaneclipseproject Thedirectorytowriteoutputfilesinto(defaultstocurrent)

Overwriteanyexistingfiles overwrite -ignore

Ignoreanyexistingfiles;donotoverwrite

Example
~/Foo> projectCreator -ant Foo -eclipse Foo Created directory src Created directory test Created file Foo.ant.xml Created file .project Created file .classpath

Running ant -f Foo.ant.xml will compile src into bin. The buildfile also contains a package target for bundling the project into a jar.
.project can be imported into an Eclipse workspace.

applicationCreator
GeneratesastarterapplicationandscriptsforlaunchinghostedmodeandcompilingtoJavaScript.
applicationCreator [-eclipse projectName] [-out dir] [-overwrite] [-ignore] className -eclipse -out

Createsadebuglaunchconfigurationforthenamedeclipseproject Thedirectorytowriteoutputfilesinto(defaultstocurrent)

-overwrite Overwriteanyexistingfiles -ignore

Ignoreanyexistingfiles;donotoverwrite

className Thefullyqualifiednameoftheapplicationclasstocreate

Example
~/Foo> applicationCreator -eclipse Foo com.example.foo.client.Foo Created directory src/com/example/foo/client Created directory src/com/example/foo/public Created file src/com/example/foo/Foo.gwt.xml Created file src/com/example/foo/public/Foo.html Created file src/com/example/foo/client/Foo.java Created file Foo.launch Created file Foo-shell Created file Foo-compile

RunningFoo-shellbringsupthenewappinhostedmode.Foo-compiletranslatestheJavaappto JavaScript,creatingawebfolderunderwww.Foo.launchisalaunchconfigurationforEclipse.

junitCreator
GeneratesaJUnittestandscriptsfortestinginbothhostedmodeandwebmode.
junitCreator -junit pathToJUnitJar [-eclipse projectName] [-out dir] [overwrite] [-ignore] className -junit

Specifythepathtoyourjunit.jar(required)

-module -eclipse -out

Specifynameoftheapplicationmoduletouse(required) Createsadebuglaunchconfigurationforthenamedeclipseproject Thedirectorytowriteoutputfilesinto(defaultstocurrent)

-overwrite Overwriteanyexistingfiles -ignore

Ignoreanyexistingfiles;donotoverwrite

className Thefullyqualifiednameofthetestclasstocreate

Example
~/Foo> junitCreator -junit /opt/eclipse/plugins/org.junit_3.8.1/junit.jar -module com.example.foo.Foo -eclipse Foo com.example.foo.client.FooTest Created directory test/com/example/foo/test Created file test/com/example/foo/client/FooTest.java Created file FooTest-hosted.launch Created file FooTest-web.launch Created file FooTest-hosted Created file FooTest-web

RunningFooTest-hostedtestsasJavabytecodeinaJVM.FooTest-webtestsascompiledJavaScript. ThelaunchconfigurationsdothesamethinginEclipse.

i18nCreator
Generatesinternationalizationscriptsforstaticinternationalization,alongwithsamplepropertiesfiles.
i18nCreator [-eclipse projectName] [-out dir] [-overwrite] [-ignore] [createMessages] interfaceName -eclipse -out -overwrite

CreatesadebuglaunchconfigforthenamedEclipseproject Thedirectorytowriteoutputfilesinto(defaultstocurrent) Overwriteanyexistingfiles

-ignore

Ignoreanyexistingfiles;donotoverwrite

GeneratescriptsforaMessagesinterfaceratherthana createMessages Constantsone


interfaceName

Thefullyqualifiednameoftheinterfacetocreate

Example
~/Foo> i18nCreator -eclipse Foo -createMessages com.example.foo.client.FooMessages Created file src/com/example/foo/client/FooMessages.properties Created file FooMessages-i18n.launch Created file FooMessages-i18n

~/Foo> i18nCreator -eclipse Foo com.example.foo.client.FooConstants Created file src/com/example/foo/client/FooConstants.properties Created file FooConstants-i18n.launch Created file FooConstants-i18n

Running FooMessages-i18n will generate an interface from FooMessages.properties that extends Messages (The messages will take parameters, substituting {n} with the nth parameter). Running FooConstants-i18n will generate an interface from FooConstants.properties that extends Constants (The constants will not take parameters).
Thelaunchconfigurationsdothesamethingasthescripts,fromwithinEclipse.

benchmarkViewer
Readsbenchmarkreportsfromafolderanddisplaystheirresults,includingvariousvisualizations.
benchmarkViewer [path]

path

SpecifythepathtotheXMLbenchmarkreports.Ifthepathisnotspecified, itdefaultstothecurrentworkingdirectory.

Example
~/Foo> benchmarkViewer my/benchmark/results

LooksforreportXMLfilesinthefoldermy/benchmark/resultsanddisplaysthemintheviewer.

1. Docs > 2. User Interfaces

Building User Interfaces


As shown in the gallery, GWT includes a variety of pre-built Java widgets and panels that serve as cross-browser building blocks for your application. GWT also includes unique and powerful optimization facilities such as image bundles.

Contents

Overview Widgets and Panels Widgets Gallery Events and Listeners Creating Custom Widgets Understanding Layout Style Sheets Image Bundles o Creating and Using an Image Bundle o Image Bundles and Localization

Overview
GWT user interface classes are similar to those in existing UI frameworks such as Swing and SWT except that the widgets are rendered using dynamically-created HTML rather than pixeloriented graphics. While it is possible to manipulate the browser's DOM directly using the DOM interface, it is far easier to use classes from the Widget hierarchy. You should rarely, if ever, need to access the DOM directly. Using widgets makes it much easier to quickly build interfaces that will work correctly on all browsers.

Widgets and Panels


GWT applications construct user interfaces using widgets that are contained within panels. Examples of widgets include Button, TextBox, and Tree.

Widgets and panels work the same way on all browsers; by using them, you eliminate the need to write specialized code for each browser. But you are not limited to the set of widgets provided by the toolkit. There are a number of ways to create custom widgets yourself.

Panels
Panels, such as DockPanel, HorizontalPanel, and RootPanel, contain widgets and are used to define how they are laid out in the browser.

Styles
Visual styles are applied to widgets using Cascading Style Sheets (CSS). This section describes in detail how to use this feature.

Widgets Gallery
The following are widgets and panels available in the GWT user-interface library. Button RadioButton

PushButton

ToggleButton

CheckBox

TextBox

PasswordTextBox

TextArea

Hyperlink

ListBox

MenuBar

Tree

Table

TabBar

DialogBox

PopupPanel

StackPanel

HorizontalPanel

VerticalPanel

FlowPanel

VerticalSplitPanel

HorizontalSplitPanel

DockPanel

TabPanel

RichTextArea

DisclosurePanel

SuggestBox

Events and Listeners


Events in GWT use the "listener interface" model similar to other user interface frameworks. A listener interface defines one or more methods that the widget calls to announce an event. A class

wishing to receive events of a particular type implements the associated listener interface and then passes a reference to itself to the widget to "subscribe" to a set of events. The Button class, for example, publishes click events. The associated listener interface is ClickListener.
public void anonClickListenerExample() { Button b = new Button("Click Me"); b.addClickListener(new ClickListener() { public void onClick(Widget sender) { // handle the click event } }); }

Using anonymous inner classes as in the above example can be inefficient for a large number of widgets, since it could result in the creation of many listener objects. Widgets supply their this pointer as the sender parameter when they invoke a listener method, allowing a single listener to distinguish between multiple event publishers. This makes better use of memory but requires slightly more code, as shown in the following example:
public class ListenerExample extends Composite implements ClickListener { private FlowPanel fp = new FlowPanel(); private Button b1 = new Button("Button 1"); private Button b2 = new Button("Button 2");

public ListenerExample() { initWidget(fp); fp.add(b1); fp.add(b2); b1.addClickListener(this); b2.addClickListener(this); }

public void onClick(Widget sender) { if (sender == b1) { // handle b1 being clicked } else if (sender == b2) { // handle b2 being clicked

} } }

Some event interfaces specify more than one event. If you are only interested in a subset of these events, subclass one of the event "adapters". Adapters are simply empty concrete implementations of a particular event interface, from which you can derive a listener class without having to implement every method.
public void adapterExample() { TextBox t = new TextBox(); t.addKeyboardListener(new KeyboardListenerAdapter() { public void onKeyPress(Widget sender, char keyCode, int modifiers) { // handle only this one event } }); }

Creating Custom Widgets


GWT makes it easy to create custom widgets entirely in the Java language.

Composites
Composites are by far the most effective way to create new widgets. You can easily combine groups of existing widgets into a composite that is itself a reusable widget. Composite is a specialized widget that can contain another component (typically, a panel) but behaves as if it were its contained widget. Using Composite is preferable to attempting to create complex widgets by subclassing Panel because a composite usually wants to control which methods are publicly accessible without exposing those methods that it would inherit from its panel superclass. This is an example of how to create a composite.

From Scratch in Java code


It is also possible to create a widget from scratch, although it is trickier since you have to write code at a lower level. Many of the basic widgets are written this way, such as Button and TextBox. Please refer to the implementations of these widgets to understand how to create your own.

Using JavaScript

When implementing a custom widget that derives directly from the Widget base class, you may also write some of the widget's methods using JavaScript. This should generally be done only as a last resort, as it becomes necessary to consider the cross-browser implications of the native methods that you write, and also becomes more difficult to debug. For an example of this pattern in practice, see the TextBox widget and its underlying implementation.

Understanding Layout
Panels in GWT are much like their counterparts in other user interface libraries. The main difference lies in the fact that they use HTML elements such as DIV and TABLE to layout their child widgets.

RootPanel
The first panel you're likely to encounter is the RootPanel. This panel is always at the top of the containment hierarchy. The default RootPanel wraps the HTML document's body, and is obtained by calling RootPanel.get(). If you need to get a root panel wrapping another element in the HTML document, you can do so using RootPanel.get(String).

CellPanel
CellPanel is the abstract base class for DockPanel, HorizontalPanel, and VerticalPanel. What these panels all have in common is that they position their child widgets within logical "cells". Thus, a child widget can be aligned within the cell that contains it, using setCellHorizontalAlignment() and setCellVerticalAlignment(). CellPanels also allow you to set the size of the cells themselves (relative to the panel as a whole) using CellPanel.setCellWidth and CellPanel.setCellHeight.

Other Panels
Other panels include DeckPanel, TabPanel, FlowPanel, HTMLPanel, and StackPanel.

Sizes and Measures


It is possible to set the size of a widget explicitly using setWidth(), setHeight(), and setSize(). The arguments to these methods are strings, rather than integers, because they accept any valid CSS measurements, such as pixels (128px), centimeters (3cm), and percentage (100%).

Style Sheets
GWT widgets rely on cascading style sheets (CSS) for visual styling. Each widget has an associated style name that binds it to a CSS rule. A widget's style name is set using

setStyleName(). For example, the Button has a default style of gwt-Button. In order to give all buttons a larger font, you could put the following rule in your application's CSS file:
.gwt-Button { font-size: 150%; }

Complex Styles
Some widgets have somewhat more complex styles associated with them. MenuBar, for example, has the following styles:
.gwt-MenuBar { the menu bar itself } .gwt-MenuBar .gwt-MenuItem { menu items } .gwt-MenuBar .gwt-MenuItem-selected { selected menu items }

In this example, there are two styles rules that apply to menu items. The first applies to all menu items (both selected and unselected), while the second (with the -selected suffix) applies only to selected menu items. A selected menu item's style name will be set to "gwt-MenuItem gwtMenuItem-selected", specifying that both style rules will be applied. The most common way of doing this is to use setStyleName to set the base style name, then addStyleName() and removeStyleName() to add and remove the second style name.

CSS Files
Typically, stylesheets are placed in a package that is part of your module's public path. Then simply include a reference to the stylesheet in your host page, such as
<link rel="stylesheet" href="mystyles.css" type="text/css">

Documentation
It is standard practice to document the relevant CSS style names for each widget class as part of its doc comment. For a simple example, see Button. For a more complex example, see MenuBar.

Image Bundles
Typically, an application uses many small images for icons. An HTTP request has to be sent to the server for each of these images, and in some cases, the size of the image is smaller than the HTTP response header that is sent back with the image data. These round trips to the server for small pieces of data are wasteful. Even when the images have been cached by the client, a 304 ("Not Modified") request is still sent to check and see if the image has changed. Since images change infrequently, these freshness checks are also wasteful. Sending out requests and freshness checks for many images will slow down your application. HTTP 1.1 requires browsers to limit the number of outgoing HTTP connections to two per domain/port. A multitude of image requests will tie up the browser's available connections,

which blocks the application's RPC requests. RPC requests are the real work that the application needs to do. To solve this problem, GWT introduces the concept of an image bundle. An image bundle is a composition of many images into a single image, along with an interface for accessing the individual images from within the composite. Users can define an image bundle that contains the images used by their application, and GWT will automatically create the composite image and provide an implementation of the interface for accessing each individual image. Instead of a round trip to the server for each image, only one round trip to the server for the composite image is needed. Since the filename of the composite image is based on a hash of the file's contents, the filename will change only if the composite image is changed. This means that it is safe for clients to cache the composite image permanently, which avoids the unnecessary freshness checks for unchanged images. To make this work, the server configuration needs to specify that composite images never expire. In addition to speeding up startup, image bundles prevent the 'bouncy' effect of image loading in browsers. While images are loading, browsers put a standard placeholder for each image in the UI. The placeholder is a standard size because the browser does not know what the size of an image is until it has been fully downloaded from the server. The result is a 'bouncy' effect, where images 'pop' into the UI once they are downloaded. With image bundles, the size of each individual image within the bundle is discovered when the bundle is created, so the size of the image can be explicitly set whenever images from a bundle are used in an application. Tip Check out the ImageBundle documentation for important information regarding: A potential security issue with the generation of the composite image on certain versions of the JVM Caching recommendations for image bundle files Protecting image bundle files with web application security constraints Using image bundles with the HTTPS protocol

Creating and Using an Image Bundle


To define an image bundle, the user needs to extend the ImageBundle interface. The ImageBundle interface is a tag interface that can be extended to define new image bundles. The derived interface can have zero or more methods, where each method

takes no parameters, has a return type of AbstractImagePrototype, and may have an optional gwt.resource metadata tag which specifies the name of the image file in the module's classpath

Valid image file types are png, gif, and jpg. If the image name contains '/' characters, it is assumed to be the name of a resource on the classpath, formatted as would be expected by

ClassLoader.getResource(String). Otherwise, the image must be located in the same

package as the user-defined image bundle. If the gwt.resource metadata tag is not specified, then

the image filename is assumed to match the method name, the extension is assumed to be either .png, .gif, or .jpg, and the file is assumed to be in the same package as the derived interface

In the event that there are multiple image files with different extensions, the order of extension precedence is (1) png, (2) gif, then (3) jpg. An image bundle for icons in a word processor application could be defined as follows:
public interface WordProcessorImageBundle extends ImageBundle {

/** * Would match the file 'new_file_icon.png', 'new_file_icon.gif', or * 'new_file_icon.png' located in the same package as this type. */ public AbstractImagePrototype new_file_icon();

/** * Would match the file 'open_file_icon.gif' located in the same * package as this type. * * @gwt.resource open_file_icon.gif */ public AbstractImagePrototype openFileIcon();

/** * Would match the file 'savefile.gif' located in the package * 'com.mycompany.mygwtapp.icons', provided that this package is part * of the module's classpath. * * @gwt.resource com/mycompany/mygwtapp/icons/savefile.gif */ public AbstractImagePrototype saveFileIcon();

Methods in an image bundle return AbstractImagePrototype objects (rather than Image objects, as you might have expected) because AbstractImagePrototype objects provide additional lightweight representations of an image. For example, the AbstractImagePrototype.getHTML() method provides an HTML fragment representing an image without having to create an actual instance of the Image widget. In some cases, it can be more efficient to manage images using these HTML fragments. Another use of AbstractImagePrototype is to use AbstractImagePrototype.applyTo(Image) to transform an existing Image into one that matches the prototype without having to instantiate another Image object. This can be useful if your application has an image that needs to be swapped depending on some user-initiated action. Of course, if an Image is exactly what you need, the AbstractImagePrototype.createImage() method can be used to generate new Image instances. The following example shows how to use the image bundle that we just defined in your application:
public void useImageBundle() { WordProcessorImageBundle wpImageBundle = (WordProcessorImageBundle) GWT.create(WordProcessorImageBundle.class); HorizontalPanel tbPanel = new HorizontalPanel(); tbPanel.add(wpImageBundle.new_file_icon().createImage()); tbPanel.add(wpImageBundle.openFileIcon().createImage()); tbPanel.add(wpImageBundle.saveFileIcon().createImage()); }

Tip Image bundles are immutable, so you can keep a reference to a singleton instance of an image bundle instead of creating a new instance every time the image bundle is needed.

Image Bundles and Localization


Sometimes applications need different images depending on the locale that the user is in. When using image bundles, this means that we need different image bundles for different locales. Although image bundles and localization are orthogonal concepts, they can work together by having locale-specific factories create instances of image bundles. The best way to explain this technique is with an example. Suppose that we define the following ImageBundle for use by a mail application:
public interface MailImageBundle extends ImageBundle {

/** * The default 'Compose New Message' icon if no locale-specific * image is specified. * * @gwt.resource compose_new_message_icon.gif */ public AbstractImagePrototype composeNewMessageIcon();

/** * The default 'Help' icon if no locale-specific image is specified. * Will match 'help_icon.png', 'help_icon.gif', or 'help_icon.jpg' in * the same package as this type. */ public AbstractImagePrototype help_icon(); }

Suppose the application has to handle both English and French users. We define English and French variations of each image in MailImageBundle by creating locale-specific image bundles that extend MailImageBundle:
public interface MailImageBundle_en extends MailImageBundle {

/** * The English version of the 'Compose New Message' icon. * Since we are not overriding the help_icon() method, this bundle * uses the inherited method from MailImageBundle. * * @gwt.resource compose_new_message_icon_en.gif */ public AbstractImagePrototype composeNewMessageIcon(); } public interface MailImageBundle_fr extends MailImageBundle {

/** * The French version of the 'Compose New Message' icon. * * @gwt.resource compose_new_message_icon_fr.gif

*/ public AbstractImagePrototype composeNewMessageIcon();

/** * The French version of the 'Help' icon. * * @gwt.resource help_icon_fr.gif */ public AbstractImagePrototype help_icon(); }

The final step is to create a mechanism for choosing the correct image bundle based on the user's locale. By extending Localizable, we can create a locale-sensitive factory that will return new instances of MailImageBundle that match the factory's locale:
public interface MailImageBundleFactory extends Localizable {

public MailImageBundle createImageBundle(); } public class MailImageBundleFactory_en implements MailImageBundleFactory {

public MailImageBundle createImageBundle() { return (MailImageBundle) GWT.create(MailImageBundle_en.class); } } public class MailImageBundleFactory_fr implements MailImageBundleFactory {

public MailImageBundle createImageBundle() { return (MailImageBundle) GWT.create(MailImageBundle_fr.class); } }

The application code that utilizes a locale-sensitive image bundle would look something like this:
public void useLocalizedImageBundle() { // Create a locale-sensitive MailImageBundleFactory MailImageBundleFactory mailImageBundleFactory = (MailImageBundleFactory) GWT .create(MailImageBundleFactory.class);

// This will return a locale-sensitive MailImageBundle, since we are using // a locale-sensitive factory to create it. MailImageBundle mailImageBundle = mailImageBundleFactory.createImageBundle();

// Get the image prototype for the icon that we are interested in. AbstractImagePrototype helpIconProto = mailImageBundle.help_icon();

// Create an Image object from the prototype and add it to a panel. HorizontalPanel panel = new HorizontalPanel(); panel.add(helpIconProto.createImage()); }

1. Docs> 2. RemoteProcedureCalls

Remote Procedure Calls


An easy-to-use RPC mechanism for passing Java objects to and from a server over standard HTTP.

Contents

Overview RPCPlumbingDiagram CreatingServices ImplementingServices ActuallyMakingaCall SerializableTypes HandlingExceptions GettingUsedtoAsynchronousCalls ArchitecturalPerspectives

Overview
AfundamentaldifferencebetweenGWTapplicationsandtraditionalHTMLwebapplicationsisthatGWT applicationsdonotneedtofetchnewHTMLpageswhiletheyexecute.BecauseGWTenhancedpages actuallyrunmorelikeapplicationswithinthebrowser,thereisnoneedtorequestnewHTMLfromthe servertomakeuserinterfaceupdates.However,likeallclient/serverapplications,GWTapplications

usuallydoneedtofetchdatafromtheserverastheyexecute.Themechanismforinteractingwitha serveracrossanetworkiscalledmakingaremoteprocedurecall(RPC),alsosometimesreferredtoasa servercall.GWTRPCmakesiteasyfortheclientandservertopassJavaobjectsbackandforthover HTTP.

When used properly, RPCs give you the opportunity to move all of your UI logic to the client, resulting in greatly improved performance, reduced bandwidth, reduced web server load, and a pleasantly fluid user experience. The server-side code that gets invoked from the client is often referred to as a service, so the act of making a remote procedure call is sometimes referred to as invoking a service. To be clear, though, the term service in this context isn't the same as the more general "web service" concept. In particular, GWT services are not related to the Simple Object Access Protocol (SOAP).

RPC Plumbing Diagram


Thissectionoutlinesthemovingpartsrequiredtoinvokeaservice.Eachservicehasasmallfamilyof helperinterfacesandclasses.Someoftheseclasses,suchastheserviceproxy,areautomatically generatedbehindthescenesandyougenerallywillneverrealizetheyexist.Thepatternforhelper classesisidenticalforeveryservicethatyouimplement,soitisagoodideatospendafewmomentsto familiarizeyourselfwiththeterminologyandpurposeofeachlayerinservercallprocessing.Ifyouare familiarwithtraditionalremoteprocedurecall(RPC)mechanisms,youwillrecognizemostofthis terminologyalready.

Creating Services
Todevelopanewserviceinterface,beginbycreatingaclientsideJavainterfacethatextendsthe RemoteServicetaginterface.
public interface MyService extends RemoteService { public String myMethod(String s); }

Thissynchronousinterfaceisthedefinitiveversionofyourservice'sspecification.Anyimplementation ofthisserviceontheserversidemustextendRemoteServiceServletandimplementthisservice interface.


public class MyServiceImpl extends RemoteServiceServlet implements MyService {

public String myMethod(String s) { // Do something interesting with 's' here on the server. return s;

Asynchronous Interfaces
Beforeyoucanactuallyattempttomakearemotecallfromtheclient,youmustcreateanother interface,anasynchronousone,basedonyouroriginalserviceinterface.Continuingwiththeexample above...
interface MyServiceAsync { public void myMethod(String s, AsyncCallback callback); }

The nature of asynchronous method calls requires the caller to pass in a callback object that can be notified when an asynchronous call completes, since by definition the caller cannot be blocked until the call completes. For the same reason, asynchronous methods do not have return types; they must always return void. After an asynchronous call is made, all communication back to the caller is via the passed-in callback object.
Therelationshipbetweenaserviceinterfaceanditsasynchronouscounterpartisstraightforward:

Ifaserviceinterfaceiscalledcom.example.cal.client.SpellingService,thenthe asynchronousinterfacemustbecalled com.example.cal.client.SpellingServiceAsync.Theasynchronousinterfacemustbe inthesamepackageandhavethesamename,butwiththesuffixAsync. Foreachmethodinyourserviceinterface,


public ReturnType methodName(ParamType1 param1, ParamType2 param2);

anasynchronoussiblingmethodshouldbedefinedthatlookslikethis:
public void methodName(ParamType1 param1, ParamType2 param2, AsyncCallback callback);

SeeAsyncCallbackforadditionaldetailsonhowtoimplementanasynchronouscallback.

Implementing Services
Everyserviceultimatelyneedstoperformsomeprocessingtoordertorespondtoclientrequests.Such serversideprocessingoccursintheserviceimplementation,whichisbasedonthewellknownservlet architecture.

A service implementation must extend RemoteServiceServlet and must implement the associated service interface. Note that the service implementation does not implement the asynchronous version of the service interface. Every service implementation is ultimately a servlet, but rather than extending HttpServlet, it extends RemoteServiceServlet instead. RemoteServiceServlet automatically handles serialization and invoking the intended method in your service implementation.

Testing Services During Development


Toautomaticallyloadyourserviceimplementation,usethe<servlet>tagwithinyourmoduleXML. TheGWTdevelopmentshellincludesanembeddedversionofTomcatwhichactsasadevelopmenttime servletcontainerfortesting.

Deploying Services Into Production


Inproduction,youcanuseanyservletcontainerthatisappropriateforyourapplication.Youneedonly toensurethattheclientcodeisconfiguredtoinvoketheserviceusingtheURLtowhichyourservletis mappedbytheweb.xmlconfiguration.SeeServiceDefTargetformoreinformation.

Actually Making a Call


TheprocessofmakinganRPCfromtheclientalwaysinvolvestheexactsamesteps. 1. 2. 3. 4. InstantiatetheserviceinterfaceusingGWT.create(). SpecifyaserviceentrypointURLfortheserviceproxyusingServiceDefTarget. CreateanasynchronouscallbackobjecttobenotifiedwhentheRPChascompleted. Makethecall.

Example
Supposeyouwanttocallamethodonaserviceinterfacedefinedasfollows:
public interface MyEmailService extends RemoteService { void emptyMyInbox(String username, String password); }

Itscorrespondingasynchronousinterfacewilllooklikethis:
public interface MyEmailServiceAsync { void emptyMyInbox(String username, String password, AsyncCallback callback);

Theclientsidecallwilllooklikethis:
public void menuCommandEmptyInbox() { // (1) Create the client proxy. Note that although you are creating the // service interface proper, you cast the result to the asynchronous // version of // the interface. The cast is always safe because the generated proxy // implements the asynchronous interface automatically. // MyEmailServiceAsync emailService = (MyEmailServiceAsync) GWT.create(MyEmailService.class);

// (2) Specify the URL at which our service implementation is running. // Note that the target URL must reside on the same domain and port from // which the host page was served. // ServiceDefTarget endpoint = (ServiceDefTarget) emailService; String moduleRelativeURL = GWT.getModuleBaseURL() + "email"; endpoint.setServiceEntryPoint(moduleRelativeURL);

// (3) Create an asynchronous callback to handle the result. // AsyncCallback callback = new AsyncCallback() { public void onSuccess(Object result) { // do some UI stuff to show success }

public void onFailure(Throwable caught) { // do some UI stuff to show failure } };

// (4) Make the call. Control flow will continue immediately and later // 'callback' will be invoked when the RPC completes.

// emailService.emptyMyInbox(fUsername, fPassword, callback); }

Itissafetocachetheinstantiatedserviceproxytoavoidcreatingitforsubsequentcalls.

Serializable Types
Methodparametersandreturntypesmustbeserializable,whichmeanstheymustconformtocertain restrictions.GWTtriesreallyhardtomakeserializationaspainlessaspossible,sowhiletherules regardingserializationaresubtle,inpracticethebehaviorbecomesintuitiveveryquickly.

A type is serializable and can be used in a service interface if it


isprimitive,suchaschar,byte,short,int,long,boolean,float,ordouble; isString,Date,oraprimitivewrappersuchasCharacter,Byte,Short,Integer,Long, Boolean,Float,orDouble; isanarrayofserializabletypes(includingotherserializablearrays); isaserializableuserdefinedclass;or hasatleastoneserializablesubclass

Serializable User-defined Classes


Auserdefinedclassisserializableif 1. itisassignabletoIsSerializableorSerializable,eitherbecauseitdirectlyimplementsoneofthese interfacesorbecauseitderivesfromasuperclassthatdoes 2. allnonfinal,nontransientinstancefieldsarethemselvesserializable,and 3. ithasapublicdefault(zeroargument)constructor Thetransientkeywordishonored,sovaluesintransientfieldsarenotexchangedduringRPCs.Fields thataredeclaredfinalarealsonotexchangedduringRPCs,sotheyshouldgenerallybemarked transientaswell.

Polymorphism
GWTRPCsupportspolymorphicparametersandreturntypes.Tomakethebestuseofpolymorphism, however,youshouldstilltrytobeasspecificasyourdesignallowswhendefiningserviceinterfaces. Increasedspecificityallowsthecompilertodoabetterjobofremovingunnecessarycodewhenit optimizesyourapplicationforsizereduction.

Type Arguments

Collectionclassessuchasjava.util.Setandjava.util.Listaretrickybecausetheyoperatein termsofObjectinstances.Tomakecollectionsserializable,youshouldspecifytheparticulartypeof objectstheyareexpectedtocontain.ThisrequiresyoutousethespecialJavadocannotation @gwt.typeArgs.Defininganitemtypeforacollectionmeansthatyouwillensurethatthecollection onlyevercontainsobjectsofthatitemtypeorasubclassthereof.ThishintisnecessarysothattheGWT proxygeneratorcancreateefficientcode.Addinganobjecttoacollectionthatviolatesitsasserteditem typewillleadtoundefinedbehavior.

To annotate fields of collection type in a serializable user-defined class:


public class MyClass implements IsSerializable { /** * This field is a Set that must always contain Strings. * * @gwt.typeArgs <java.lang.String> */ public Set setOfStrings;

/** * This field is a Map that must always contain Strings as its keys and * values. * * @gwt.typeArgs <java.lang.String,java.lang.String> */ public Map mapOfStringToString;

/** * Default Constructor. The Default Constructor's explicit declaration * is required for a serializable class. */ public MyClass() { } }

Notethatthereisnoneedtospecifythenameofthefieldinthe@gwt.typeArgsdeclarationsinceit canbeinferred.

Similarly, to annotate parameters and return types:

public interface MyService extends RemoteService { /** * The first annotation indicates that the parameter named 'c' is a List * that will only contain Integer objects. The second annotation * indicates that the returned List will only contain String objects * (notice there is no need for a name, since it is a return value). * * @gwt.typeArgs c <java.lang.Integer> * @gwt.typeArgs <java.lang.String> */ List reverseListAndConvertToStrings(List c); }

Notethatparameterannotationsmustincludethenameoftheparametertheyareannotatingin additiontothecollectionitemtype,whilereturntypeannotationsdonot. Tip Althoughtheterminologyisverysimilar,GWT'sconceptof"serializable"isdifferentthanserialization basedonthestandardJavainterfaceSerializable.AllreferencestoserializationarereferringtotheGWT conceptasdefinedabove.

Handling Exceptions
MakingRPCsopensupthepossibilityofavarietyoferrors.Networksfail,serverscrash,andproblems occurwhileprocessingaservercall.GWTletsyouhandletheseconditionsintermsofJavaexceptions. RPCrelatedexceptionsfallintotwocategories.

Checked Exceptions
Serviceinterfacemethodssupportthrowsdeclarationstoindicatewhichexceptionsmaybethrown backtotheclientfromaserviceimplementation.Callersshouldimplement AsyncCallback.onFailure(Throwable)tocheckforanyexceptionsspecifiedintheserviceinterface.

Unexpected Exceptions
InvocationException AnRPCmaynotreachtheserviceimplementationatall.Thiscanhappenformanyreasons:thenetwork maybedisconnected,aDNSservermightnotbeavailable,theHTTPservermightnotbelistening,and soon.Inthiscase,anInvocationExceptionispassedtoyourimplementationof

AsyncCallback.onFailure(Throwable).TheclassiscalledInvocationExceptionbecausetheproblem waswiththeinvocationattemptitselfratherthanwiththeserviceimplementationitself.

An RPC can also fail with an invocation exception if the call does reach the server, but an undeclared exception occurs during normal processing of the call. There are many reasons such a situation could arise: a necessary server resource, such as a database, might be unavailable, a NullPointerException could be thrown due to a bug in the service implementation, and so on. In these cases, a InvocationException is thrown in application code.
IncompatibleRemoteServiceException

Another type of failure can be caused by an incompatibility between the client and the server. This most commonly occurs when a change to a service implementation is deployed to a server but out-of-date clients are still active. For more details please see IncompatibleRemoteServiceException. When the client code receives an IncompatibleRemoteServiceException, it should ultimately attempt to refresh the browser in order to pick up the latest client.

Getting Used to Asynchronous Calls


AsynchronousRPCisn'tthesimplestthingintheworld,butitdoesallowyoutoachievetrueparallelism inyourapplication,evenwithoutmultithreading.

For example, suppose your application displays a large table containing many widgets. Constructing and laying out all those widgets can be time consuming. At the same time, you need to fetch data from the server to display inside the table. This is a perfect reason to use asynchronous calls. Initiate an asynchronous call to request the data immediately before you begin constructing your table and its widgets. While the server is fetching the required data, the browser is executing your user interface code. When the client finally receives the data from the server, the table has been constructed and laid out, and the data is ready to be displayed. To give you an idea of how effective this technique can be, suppose that building the table takes 1 second and fetching the data takes 1 second. If you make the server call synchronously, the whole process will require at least 2 seconds. But if you fetch the data asynchronously, the whole process still takes just 1 second, even though you are doing 2 seconds' worth of work. The hardest thing to get used to about asynchronous calls is that the calls are non-blocking. However, Java inner classes go a long way toward making this manageable.
Tip TheAsyncCallbackinterfaceisthekeyinterfaceyou'llextendtohandleRPCresponses.

Architectural Perspectives
Therearevariouswaystoapproachserviceswithinyourapplicationarchitecture.Understandfirstofall thatGWTservicesarenotintendedtoreplaceJ2EEservers,noraretheyintendedtoprovideapublic webservices(e.g.SOAP)layerforyourapplication.GWTRPCs,fundamentally,aresimplyamethodof "gettingfromtheclienttotheserver."Inotherwords,youuseRPCstoaccomplishtasksthatarepartof yourapplicationbutthatcannotbedoneontheclientcomputer.

Architecturally, you can make use of RPC two alternative ways. The difference is a matter of taste and of the architectural needs of your application. The first and most straightforward way to think of service definitions is to treat them as your application's entire back end. From this perspective, client-side code is your "front end" and all service code that runs on the server is "back end." If you take this approach, your service implementations would tend to be more general-purpose APIs that are not tightly coupled to one specific application. Your service definitions would likely directly access databases through JDBC or Hibernate or even files in the server's file system. For many applications, this view is appropriate, and it can be very efficient because it reduces the number of tiers. In more complex, multi-tiered architectures, your GWT service definitions could simply be lightweight gateways that call through to back-end server environments such as J2EE servers. From this perspective, your services can be viewed of as the "server half" of your application's user interface. Instead of being general-purpose, services are created for the specific needs of your user interface. Your services become the "front end" to the "back end" classes that are written by stitching together calls to a more general-purpose back-end layer of services, implemented, for example, as a cluster of J2EE servers. This kind of architecture is appropriate if you require your back-end services to run on a physically separate computer from your HTTP server.
1. Docs> 2. UnitTesting

JUnit Integration
Integration with JUnit lets you test your AJAX code almost as easily as any other Java code.

Contents

Overview AsynchronousTesting Benchmarking

Overview
GWTincludesaspecialGWTTestCasebaseclassthatprovidesJUnitintegration.Runningacompiled GWTTestCasesubclassunderJUnitlaunchesaninvisibleGWTbrowser.

By default, tests run in hosted mode as normal Java bytecode in a JVM. Overriding this default behavior requires passing arguments to the GWT shell. Arguments cannot be passed directly through the command line, because normal command-line arguments go directly to the JUnit runner. Instead, define the system property gwt.args to pass arguments to GWT. For example, to run in web mode, declare -Dgwt.args="-web" as a JVM argument when invoking JUnit. To get a full list of supported options, declare -Dgwt.args="-help" (instead of running the test, help is printed to the console).

Creating a Test Case


GWT includes a handy junitCreator tool that will generate a starter test case for you, plus scripts for testing in both hosted mode and web mode. But here are the steps if you want to set it up by hand:
1. DefineaclassthatextendsGWTTestCase. 2. Createamodulethatcausesthesourceforyourtestcasetobeincluded.Ifyouareaddingatest casetoanexistingGWTapp,youcanusuallyjustusetheexistingmodule. 3. ImplementthemethodGWTTestCase.getModuleName()toreturnthefullyqualifiednameof themodule. 4. Compileyourtestcaseclasstobytecode(usingjavacoraJavaIDE). 5. Whenrunningthetestcase,makesureyourclasspathincludes: o yourproject'ssrcdirectory o yourproject'sbindirectory o gwt-user.jar o gwt-dev-windows.jar(orgwt-dev-linux.jar) o junit.jar

Example
Writethecom.example.foo.client.FooTesttestcase.
public class FooTest extends GWTTestCase {

/* * Specifies a module to use when running this test case. The returned * module must cause the source for this class to be included. * * @see com.google.gwt.junit.client.GWTTestCase#getModuleName()

*/ public String getModuleName() { return "com.example.foo.Foo"; }

public void testStuff() { assertTrue(2 + 2 == 4); } }

Createthecom.example.foo.Foomodule.
<!--> <!-- Copyright 2007 Google Inc. -> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you -> <!-- may not use this file except in compliance with the License. You may -> <!-- may obtain a copy of the License at -> <!--> <!-- http://www.apache.org/licenses/LICENSE-2.0 -> <!--> <!-- Unless required by applicable law or agreed to in writing, software -> <!-- distributed under the License is distributed on an "AS IS" BASIS, -> <!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -> <!-- implied. License for the specific language governing permissions and -> <!-- limitations under the License. -> -

<module> <!-- Module com.example.foo.Foo -->

<!-- Standard inherit. <inherits name='com.google.gwt.user.User'/>

-->

<!-- implicitly includes com.example.foo.client package

-->

<!-- OPTIONAL STUFF FOLLOWS -->

<!-- It's okay for your module to declare an entry point. <!-- This gets ignored when running under JUnit. <entry-point class='com.example.foo.FooModule'/>

--> -->

<!-- You can also test remote services during a JUnit run.

-->

<servlet path='/foo' class='com.example.foo.server.FooServiceImpl'/> </module>

Tip Youdon'tneedtocreateaseparatemoduleforeverytestcase.Intheexampleabove,anytestcasesin com.example.foo.client(oranysubpackage)cansharethecom.example.foo.Foomodule.

Asynchronous Testing
GWT'sJUnitintegrationprovidesspecialsupportfortestingfunctionalitythatcannotexecuteinstraight linecode.Forexample,youmightwanttomakeanRPCcalltoaserverandthenvalidatetheresponse. However,inanormalJUnittestrun,theteststopsassoonasthetestmethodreturnscontroltothe caller,andGWTdoesnotsupportmultiplethreadsorblocking.Tosupportthisusecase,GWTTestCase hasextendedtheTestCaseAPI.

The two key methods are GWTTestCase.delayTestFinish(int) and GWTTestCase.finishTest(). Calling delayTestFinish() during a test method's execution puts that test in asynchronous mode, which means the test will not finish when the test method returns control to the caller. Instead, a delay period begins, which lasts the amount of time specified in the call to delayTestFinish(). During the delay period, the test system will wait for one of three things to happen:
1. IffinishTest()iscalledbeforethedelayperiodexpires,thetestwillsucceed. 2. Ifanyexceptionescapesfromaneventhandlerduringthedelayperiod,thetestwillerrorwith thethrownexception.

3. Ifthedelayperiodexpiresandneitheroftheabovehashappened,thetestwillerrorwitha TimeoutException.

The normal use pattern is to setup an event in the test method and call delayTestFinish() with a timeout significantly longer than the event is expected to take. The event handler validates the event and then calls finishTest().
Example
public void testTimer() { // Setup an asynchronous event handler. Timer timer = new Timer() { public void run() { // do some validation logic

// tell the test system the test is now done finishTest(); } };

// Set a delay period significantly longer than the // event is expected to take. delayTestFinish(500);

// Schedule the event and return control to the test system. timer.schedule(100); }

Tip Therecommendedpatternistotestoneasynchronouseventpertestmethod.Ifyouneedtotest multipleeventsinthesamemethod,hereareacoupleoftechniques:"Chain"theeventstogether. Triggerthefirsteventduringthetestmethod'sexecution;whenthateventfires,calldelayTestFinish() againwithanewtimeoutandtriggerthenextevent.Whenthelasteventfires,callfinishTest()as normal.Setacountercontainingthenumberofeventstowaitfor.Aseacheventcomesin,decrement thecounter.CallfinishTest()whenthecounterreaches0.

Benchmarking

GWT'sJUnitintegrationprovidesspecialsupportforcreatingandreportingonbenchmarks.Specifically, GWThasintroducedanewBenchmarkclasswhichprovidesbuiltinfacilitiesforcommonbenchmarking needs.Totakeadvantageofbenchmarkingsupport,takethefollowingsteps: 1. ReviewthedocumentationonBenchmark.Takealookattheexamplebenchmarkcode. 2. CreateyourownbenchmarkbysubclassingBenchmark.Executeyourbenchmarklikeyouwould anynormalJUnittest.Bydefault,thetestresultsarewrittentoareportXMLfileinyourworking directory. 3. RunbenchmarkViewertobrowsevisualizations(graphs/charts)ofyourreportdata.The benchmarkViewerisaGWTtoolintherootofyourGWTinstallationdirectorythatdisplays benchmarkreports.

1. Docs > 2. Internationalization

Internationalization
Easily support multiple locales with a single code base.

Contents

Overview Static String Internationalization Dynamic String Internationalization Specifying a Locale Localized Properties Files

Overview
GWT includes a flexible set of tools to help you internationalize your applications and libraries. GWT internationalization support provides a variety of techniques to internationalize strings, typed values, and classes.

Getting Started
Since GWT supports a variety of ways of internationalizing your code, begin by researching which approach best matches your development requirements. Are you writing code from scratch? If so, you'll probably want to read up on GWT's static string internationalization techniques. Do you want to internationalize mostly settings or end-user messages? If you have mostly settings (the kind of thing for which you'd normally use simple properties

files), consider Constants. If you have a lot a of end-user messages, then Messages is probably what you want. Do you have existing localized properties files you'd like to reuse? The i18nCreator tool can automatically generate interfaces that extend either Constants or Messages. Are you adding GWT functionality to an existing web application that already has a localization process defined? Dictionary will help you interoperate with existing pages without requiring you to use GWT's concept of locale. Do you really just want a simple way to get properties files down to the client regardless of localization? You can do that, too. Try using Constants without specifying a locale.

Internationalization Techniques
GWT offers multiple internationalization techniques to afford maximum flexibility to GWT developers and to make it possible to design for efficiency, maintainability, flexibility, and interoperability in whichever combinations are most useful. Static string internationalization refers to a family of efficient and type-safe techniques that rely on strongly-typed Java interfaces, properties files, and code generation to provide locale-aware messages and configuration settings. These techniques depend on the interfaces Constants and Messages. At the other end of the spectrum, dynamic string internationalization is a simplistic and flexible technique for looking up localized values defined in a module's host page without needing to recompile your application. This technique is supported by the class Dictionary. Using an approach similar to static string internationalization, GWT also supports internationalizing sets of algorithms using locale-sensitive type substitution. This is an advanced technique that you probably will not need to use directly, although it is useful for implementing complex internationalized libraries. For details on this technique, see Localizable.

The I18N Module


The core types related to internationalization reside in the com.google.gwt.i18n package:

Constants Useful for localizing typed constant values

Messages

Useful for localizing messages requiring arguments

ConstantsWithLookup Like Constants but with extra lookup flexibility for highly data-driven applications

Dictionary Useful when adding a GWT module to existing localized web pages

Localizable Useful for localizing algorithms encapsulated in a class

The GWT internationalization types are included in the module com.google.gwt.i18n.I18N. To use any of these types, your module must inherit from it:
<!--> <!-- Copyright 2007 Google Inc. -> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you -> <!-- may not use this file except in compliance with the License. You may -> <!-- may obtain a copy of the License at -> <!--> <!-- http://www.apache.org/licenses/LICENSE-2.0 -> <!--> <!-- Unless required by applicable law or agreed to in writing, software -> <!-- distributed under the License is distributed on an "AS IS" BASIS, -> <!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -> <!-- implied. License for the specific language governing permissions and -> <!-- limitations under the License. -> -

<module> <!-- other inherited modules, such as com.google.gwt.user.User --> <inherits name="com.google.gwt.i18n.I18N"/> <!-- additional module settings --> </module>

Static String Internationalization


Static string localization relies on code generation from properties files. GWT supports static string localization through two tag interfaces (that is, interfaces having no methods that represent a functionality contract) and a code generation library to generate implementations of those interfaces. For example, if you wanted to localize the constant strings "hello, world" and "goodbye, world" in your GWT application, you could define an interface that abstracts those strings by extending the built-in Constants interface:
public interface MyConstants extends Constants { String helloWorld(); String goodbyeWorld(); }

Now create an associated default properties file called MyConstants.properties in the same package:
helloWorld = hello, world goodbyeWorld = goodbye, world

You can also create a localized translation for each supported locale in separate properties file. In this case, we localize for Spanish:
helloWorld = hola, mundo goodbyeWorld = adis, mundo

To use the internationalized constants, you create an implementation of MyConstants using GWT.create(Class):
public void useMyConstants() { MyConstants myConstants = (MyConstants) GWT.create(MyConstants.class); Window.alert(myConstants.helloWorld()); }

The Benefits of Static String Internationalization


As you can see from the example above, static internationalization relies on a very tight binding between internationalized code and its localized resources. Using explicit method calls in this

way has a number of advantages. The GWT compiler can optimize deeply, removing uncalled methods and inlining localized strings -- making generated code as efficient as if the strings had been hard-coded. The value of compile-time checking becomes even more apparent when applied to messages that take multiple arguments. Creating a Java method for each message allows the compiler to check both the number and types of arguments supplied by the calling code against the message template defined in a properties file. For example, attempting to use this interface:
public interface ErrorMessages extends Messages { String permissionDenied(int errorCode, String username); }

with this properties file:


permissionDenied = Error {0}: User {1} does not have permission to access {2}

results in a compile-time error because the message template in the properties file expects three arguments, while the permissionDenied method can only supply two.

Which Interface to Use?


Extend Constants to create a collection of constant values of a variety of types that can be accessed by calling methods (called constant accessors) on an interface. Constant accessors may return a variety of types, including strings, numbers, booleans, and even maps. A compile-time check is done to ensure that the value in a properties file matches the return type declared by its corresponding constant accessor. In other words, if a constant accessor is declared to return an int, its associated property is guaranteed to be a valid int value -- avoiding a potential source of runtime errors.
ConstantsWithLookup is identical to Constants except that the interface also includes a

method to look up strings by property name, which facilitates dynamic binding to constants by name at runtime. ConstantsWithLookup can sometimes be useful in highly data-driven applications. One caveat: ConstantsWithLookup is less efficient than Constants because the compiler cannot discard unused constant methods, resulting in larger applications. Extend Messages to create a collection of formatted messages that can accept parameters. You might think of the Messages interface as a statically verifiable equivalent of the traditional Java combination of Properties, ResourceBundle, and MessageFormat rolled into a single mechanism.

Properties Files
All of the types above use properties files based on the traditional Java properties file format, although GWT uses an enhanced properties file format that are encoded as UTF-8 and can therefore contain Unicode characters directly.

Dynamic String Internationalization


The Dictionary class lets your GWT application consume strings supplied by the host HTML page. This approach is convenient if your existing web server has a localization system that you do not wish to integrate with the static string methods. Instead, simply print your strings within the body of your HTML page as a JavaScript structure, and your GWT application can reference and display them to end users. Since it binds directly to the key/value pairs in the host HTML, whatever they may be, the Dictionary class is not sensitive to the the GWT locale setting. Thus, the burden of generating localized strings is on your web server. Dynamic string localization allows you to look up localized strings defined in a host HTML page at runtime using string-based keys. This approach is typically slower and larger than the static string approach, but does not require application code to be recompiled when messages are altered or the set of locales changes. Tip The Dictionary class is completely dynamic, so it provides no static type checking, and invalid keys cannot be checked by the compiler. This is another reason we recommend using static string internationalization where possible.

Specifying a Locale
GWT represents locale as a client property whose value can be set either using a meta tag embedded in the host page or in the query string of the host page's URL. Rather than being supplied by GWT, the set of possible values for the locale client property is entirely a function of your module configuration. If that sounded like gibberish (and it probably did), a quick digression into the purpose of client properties is in order...

Client Properties and the GWT Compilation Process


Client properties are key/value pairs that can be used to configure GWT modules. User agent, for example, is represented by a client property. Each client property can have any number of values, but all of the values must be enumerable when the GWT compiler runs. GWT modules can define and extend the set of available client properties along with the potential values each property might assume when loaded in an end user's browser. At compile time, the GWT compiler determines all the possible permutations of a module's client properties, from which it produces multiple compilations. Each compilation is optimized for a different set of client properties and is recorded into a file ending with the suffix .cache.html.

In deployment, the end-user's browser only needs one particular compilation, which is determined by mapping the end user's client properties onto the available compiled permutations. Thus, only the exact code required by the end user is downloaded, no more. By making locale a client property, the standard startup process in gwt.js chooses the appropriate localized version of an application, providing ease of use (it's easier than it might sound!), optimized performance, and minimum script size.

The Default Locale


The com.google.gwt.i18n.I18N module defines only one locale by default, called default. This default locale is used when the locale client property goes unspecified in deployment. The default locale is used internally as a last-resort match between a Localizable interface and a localized resource or class.

Adding Locale Choices to a Module


In any real-world application, you will define at least one locale in addition to the default locale. "Adding a locale" means extending the set of values of the locale client property using the <extend-property> element in your module XML. For example, the following module adds multiple locale values:
<!--> <!-- Copyright 2007 Google Inc. -> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you -> <!-- may not use this file except in compliance with the License. You may -> <!-- may obtain a copy of the License at -> <!--> <!-- http://www.apache.org/licenses/LICENSE-2.0 -> <!--> <!-- Unless required by applicable law or agreed to in writing, software -> <!-- distributed under the License is distributed on an "AS IS" BASIS, -> <!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -> -

<!-- implied. License for the specific language governing permissions and -> <!-- limitations under the License. ->

<module> <inherits name="com.google.gwt.user.User"/> <inherits name="com.google.gwt.i18n.I18N"/>

<!-- French language, independent of country --> <extend-property name="locale" values="fr"/>

<!-- French in France --> <extend-property name="locale" values="fr_FR"/>

<!-- French in Canada --> <extend-property name="locale" values="fr_CA"/>

<!-- English language, independent of country --> <extend-property name="locale" values="en"/> </module>

Choosing a Locale at Runtime


The locale client property can be specified using either a meta tag or as part of the query string in the host page's URL. If both are specified, the query string takes precedence. To specify the locale client property using a meta tag in the host page, embed a meta tag for gwt:property as follows:
<meta name="gwt:property" content="locale=x_Y">

For example, the following host HTML page sets the locale to "ja_JP":
<html> <head> <meta name="gwt:module" content="com.google.gwt.examples.i18n.ColorNameLookupExample"> <meta name="gwt:property" content="locale=ja_JP"> </head> <body>

<script src="gwt.js"></script> </body> </html>

To specify the locale client property using a query string, specify a value for the name locale. For example,
http://www.example.org/myapp.html?locale=fr_CA

Localized Properties Files


Both Constants and Messages use traditional Java properties files, with one notable difference: properties files used with GWT should be encoded as UTF-8 and may contain Unicode characters directly, avoiding the need for native2ascii. See the API documentation for the above interfaces for examples and formatting details. Many thanks to the Tapestry project for solving the problem of reading UTF-8 properties files in Tapestry's LocalizedProperties class. 1. Docs > 2. JavaScript Native Interface (JSNI)

JavaScript Native Interface (JSNI)


Mix handwritten JavaScript into your Java classes to access low-level browser functionality.

Contents

Overview Writing Native JavaScript Methods Accessing Java Methods and Fields from JavaScript Sharing objects between Java source and JavaScript Exceptions and JSNI

Overview
The GWT compiler translates Java source into JavaScript. Sometimes it's very useful to mix handwritten JavaScript into your Java source code. For example, the lowest-level functionality of certain core GWT classes are handwritten in JavaScript. GWT borrows from the Java Native Interface (JNI) concept to implement JavaScript Native Interface (JSNI).

Writing JSNI methods is a powerful technique, but should be used sparingly. JSNI code is less portable across browsers, more likely to leak memory, less amenable to Java tools, and hard for the compiler to optimize. We think of JSNI as the web equivalent of inline assembly code. You can:

Implement a Java method directly in JavaScript Wrap type-safe Java method signatures around existing JavaScript Call from JavaScript into Java code and vice-versa Throw exceptions across Java/JavaScript boundaries Read and write Java fields from JavaScript Use hosted mode to debug both Java source (with a Java debugger) and JavaScript (with a script debugger, only in Windows right now)

Tip When accessing the browser's window and document objects from JSNI, you must reference them as $wnd and $doc, respectively. Your compiled script runs in a nested frame, and $wnd and $doc are automatically initialized to correctly refer to the host page's window and document.

Writing Native JavaScript Methods


JSNI methods are declared native and contain JavaScript code in a specially formatted comment block between the end of the parameter list and the trailing semicolon. A JSNI comment block begins with the exact token /*-{ and ends with the exact token }-*/. JSNI methods are be called just like any normal Java method. They can be static or instance methods.

Example
public static native void alert(String msg) /*-{ $wnd.alert(msg); }-*/;

Tip In hosted mode, you can set a breakpoint on the source line containing the opening brace of a JSNI method, allowing you to see invocation arguments.

Accessing Java Methods and Fields from JavaScript


It can be very useful to manipulate Java objects from within the JavaScript implementation of a JSNI method. There is a special syntax for this.

Invoking Java methods from JavaScript


Calling Java methods from JavaScript is somewhat similar to calling Java methods from C code in JNI. In particular, JSNI borrows the JNI mangled method signature approach to distinguish among overloaded methods. JavaScript calls into Java methods are of the form
[instance-expr.]@class-name::method-name(param-signature)(arguments)

where [instance-expr.] must be present when calling an instance method and must be absent when calling a static method class-name is the fully-qualified name of the class in which the method is declared (or a subclass thereof) param-signature is the internal Java method signature as specified here but without the trailing signature of the method return type since it isn't needed to choose the overload arguments the actual argument list to pass to the called method

Accessing Java fields from JavaScript


Static and instance fields can be accessed from handwritten JavaScript. Field references are of the form
[instance-expr.]@class-name::field-name

Example
public class JSNIExample {

String myInstanceField; static int myStaticField;

void instanceFoo(String s) { // use s }

static void staticFoo(String s) { // use s

public native void bar(JSNIExample x, String s) /*-{ // Call instance method instanceFoo() on this this.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s) ;

// Call instance method instanceFoo() on x x.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s);

// Call static method staticFoo() @com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s);

// Read instance field on this var val = this.@com.google.gwt.examples.JSNIExample::myInstanceField;

// Write instance field on x x.@com.google.gwt.examples.JSNIExample::myInstanceField = val + " and stuff";

// Read static field (no qualifier) @com.google.gwt.examples.JSNIExample::myStaticField = val + " and stuff"; }-*/;

Tip When writing JSNI code, it's helpful to occasionally run in web mode. The JavaScript compiler checks your JSNI code and can flag errors at compile time that you wouldn't catch until runtime in hosted mode.

Sharing objects between Java source and JavaScript


Parameters and return types in JSNI methods are declared as Java types. There are very specific rules for how values passing in and out of JavaScript code must be treated. These rules must be

followed whether the values enter and leave through normal method call semantics, or through the special syntax.

Passing Java values into JavaScript


Incoming Java type a Java numeric primitive
String boolean

How it appears to JavaScript code a JavaScript numeric value, as in var x = 42;

a JavaScript string, as in var s = "my string"; a JavaScript boolean value, as in var b = true; JavaScriptObject (see a JavaScriptObject that must have originated from notes) JavaScript code, typically as the return value of some other JSNI method Java array an opaque value that can only be passed back into Java code any other Java Object an opaque value accessible through special syntax

Passing JavaScript values into Java code


Outgoing Java type a Java numeric primitive
String

What must be passed a JavaScript numeric value, as in return 19;

a JavaScript string, as in return "boo"; boolean a JavaScript boolean value, as in return false; JavaScriptObject (see a native JavaScript object, as in return document.createElement("div") notes) any other Java Object a Java Object of the correct type that must have (including arrays) originated in Java code; Java objects cannot be constructed from "thin air" in JavaScript

Important Notes

A Java numeric primitive is one of byte, short, char, int, long, float, or double. You must ensure the value is appropriate for the declared type. Returning 3.7 when the declared type is int will cause unpredictable behavior. Java null and JavaScript null are identical and always legal values for any nonprimitive Java type. JavaScript undefined is not identical to null; never return undefined from a JSNI method or unpredictable behavior will occur. Violating any of these marshaling rules in hosted mode will generate a com.google.gwt.dev.shell.HostedModeException detailing the problem. This exception is not translatable and never thrown in web mode.

JavaScriptObject is a magical type that gets special treatment from the GWT compiler and hosted browser. Its purpose is to provide an opaque representation of native JavaScript objects to Java code.

Tip When returning a possibly undefined value from a JSNI method, we suggest using the idiom return (value == null) ? null : value; to avoid returning undefined.

Exceptions and JSNI


Exceptions can originate both in Java code and in handwritten JavaScript code. An exception that originates in a JSNI method and escapes into Java code can be caught as a JavaScriptException. Relying on this behavior is discouraged because JavaScript exceptions are not usefully typed. The recommended practice is to handle JavaScript exceptions in JavaScript code and Java exceptions in Java code. When a JSNI method invokes a Java method, a more complex call chain results. An exception thrown from the inner Java method can safely pass through the sandwiched JSNI method back to the original Java call site, retaining type fidelity. It can be caught as expected. For example, 1. Java method foo() calls JSNI method bar() 2. JavaScript method bar() calls Java method baz() 3. Java method baz() throws an exception The exception thrown out of baz() will propagate through bar() and can be caught in foo(). 1. Docs > 2. JRE Emulation

JRE Emulation Library


Google Web Toolkit includes a library that emulates a subset of the Java runtime library. The list below shows the set of JRE types and methods that GWT can translate automatically. Note that in some cases, only a subset of methods is supported for a given type.

Package java.lang
o o

ArrayStoreException ArrayStoreException(), ArrayStoreException(String) AssertionError

o o o o o o o o

AssertionError(), AssertionError(Object), AssertionError(boolean), AssertionError(char), AssertionError(int), AssertionError(long), AssertionError(float), AssertionError(double)

o o o o o o o o o

Boolean Boolean(boolean), Boolean(String), booleanValue(), equals(Object), hashCode(), toString(boolean), toString(), valueOf(boolean), valueOf(String)

Byte o Byte(byte), o Byte(String), o byteValue(), o compareTo(Byte), o compareTo(Object), o decode(String), o doubleValue(), o equals(Object), o floatValue(), o hashCode(), o intValue(), o longValue(), o parseByte(String), o parseByte(String, int), o shortValue(), o toString(byte), o toString(), o valueOf(String), o valueOf(String, int) CharSequence o charAt(int), o length(), o subSequence(int, int), o toString()

Character o Character(char), o charValue(), o compareTo(Character), o compareTo(Object), o digit(char, int), o equals(Object), o forDigit(int, int), o hashCode(), o isDigit(char), o isLetter(char), o isLetterOrDigit(char), o isLowerCase(char), o isSpace(char), o isUpperCase(char), o toLowerCase(char), o toString(char), o toString(), o toUpperCase(char) Class ClassCastException o ClassCastException(), o ClassCastException(String) Cloneable Comparable o compareTo(Object) Double Double(double), Double(String), byteValue(), compare(double, double), compareTo(Double), compareTo(Object), doubleValue(), equals(Object), floatValue(), hashCode(), intValue(), isInfinite(double), isInfinite(), isNaN(double), isNaN(),

o o o o o o o o o o o o o o o

o o o o o o

longValue(), parseDouble(String), shortValue(), toString(double), toString(), valueOf(String)

o o o o

Error Error(), Error(String, Throwable), Error(String), Error(Throwable)

Exception o Exception(), o Exception(String), o Exception(String, Throwable), o Exception(Throwable) Float o Float(float), o Float(String), o byteValue(), o compare(float, float), o compareTo(Float), o compareTo(Object), o doubleValue(), o equals(Object), o floatValue(), o hashCode(), o intValue(), o isInfinite(float), o isInfinite(), o isNaN(float), o isNaN(), o longValue(), o parseFloat(String), o shortValue(), o toString(float), o toString(), o valueOf(String) IllegalArgumentException o IllegalArgumentException(), o IllegalArgumentException(String) IllegalStateException

o o o o

IllegalStateException(), IllegalStateException(String), IllegalStateException(String, Throwable), IllegalStateException(Throwable)

IndexOutOfBoundsException o IndexOutOfBoundsException(), o IndexOutOfBoundsException(String) Integer o Integer(int), o Integer(String), o byteValue(), o compareTo(Integer), o compareTo(Object), o decode(String), o doubleValue(), o equals(Object), o floatValue(), o hashCode(), o intValue(), o longValue(), o parseInt(String), o parseInt(String, int), o shortValue(), o toBinaryString(int), o toHexString(int), o toString(int), o toString(), o valueOf(String), o valueOf(String, int) Long o Long(long), o Long(String), o byteValue(), o compareTo(Long), o compareTo(Object), o decode(String), o doubleValue(), o equals(Object), o floatValue(), o hashCode(), o intValue(), o longValue(), o parseLong(String), o parseLong(String, int),

o o o o o o o

shortValue(), toBinaryString(long), toHexString(long), toString(long), toString(), valueOf(String), valueOf(String, int)

Math o abs(double), o abs(float), o abs(int), o abs(long), o acos(double), o asin(double), o atan(double), o ceil(double), o cos(double), o exp(double), o floor(double), o log(double), o max(double, double), o max(float, float), o max(int, int), o max(long, long), o min(double, double), o min(float, float), o min(int, int), o min(long, long), o pow(double, double), o random(), o round(double), o round(float), o sin(double), o sqrt(double), o tan(double), o toDegrees(double), o toRadians(double) NegativeArraySizeException NegativeArraySizeException(), NegativeArraySizeException(String)

o o

NullPointerException o NullPointerException(), o NullPointerException(String)

Number o byteValue(), o doubleValue(), o floatValue(), o intValue(), o longValue(), o shortValue() NumberFormatException o NumberFormatException(), o NumberFormatException(String) Object equals(Object), hashCode(), toString() RuntimeException RuntimeException(), RuntimeException(String), RuntimeException(String, Throwable), RuntimeException(Throwable) Short Short(short), Short(String), byteValue(), compareTo(Object), compareTo(Short), decode(String), doubleValue(), equals(Object), floatValue(), hashCode(), intValue(), longValue(), parseShort(String), parseShort(String, int), shortValue(), toString(short), toString(), valueOf(String), valueOf(String, int) String String(), String(char[]),

o o o

o o o o

o o o o o o o o o o o o o o o o o o o

o o

o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o

String(char[], int, int), String(String), charAt(int), compareTo(Object), compareTo(String), concat(String), endsWith(String), equals(Object), equalsIgnoreCase(String), hashCode(), indexOf(int), indexOf(int, int), indexOf(String), indexOf(String, int), lastIndexOf(int), lastIndexOf(int, int), lastIndexOf(String), lastIndexOf(String, int), length(), matches(String), replace(char, char), replaceAll(String, String), replaceFirst(String, String), split(String), split(String, int), startsWith(String), startsWith(String, int), subSequence(int, int), substring(int), substring(int, int), toCharArray(), toLowerCase(), toString(), toUpperCase(), trim(), valueOf(boolean), valueOf(char), valueOf(char[], int, int), valueOf(char[]), valueOf(double), valueOf(float), valueOf(int), valueOf(long), valueOf(Object)

StringBuffer StringBuffer(),

o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o

StringBuffer(int), StringBuffer(String), append(boolean), append(char), append(char[]), append(char[], int, int), append(double), append(float), append(int), append(long), append(Object), append(String), append(StringBuffer), charAt(int), delete(int, int), deleteCharAt(int), getChars(int, int, char[], int), indexOf(String), indexOf(String, int), insert(int, boolean), insert(int, char), insert(int, char[]), insert(int, char[], int, int), insert(int, double), insert(int, float), insert(int, int), insert(int, long), insert(int, Object), insert(int, String), lastIndexOf(String), lastIndexOf(String, int), length(), replace(int, int, String), setCharAt(int, char), setLength(int), subSequence(int, int), substring(int), substring(int, int), toString()

o o o

StringIndexOutOfBoundsException StringIndexOutOfBoundsException(), StringIndexOutOfBoundsException(String), StringIndexOutOfBoundsException(int) System currentTimeMillis(),

o o o

identityHashCode(Object), setErr(PrintStream), setOut(PrintStream)

o o o o o o o o o o o o o o

Throwable Throwable(), Throwable(String), Throwable(String, Throwable), Throwable(Throwable), fillInStackTrace(), getCause(), getLocalizedMessage(), getMessage(), getStackTrace(), initCause(Throwable), printStackTrace(), printStackTrace(PrintStream), setStackTrace(StackTraceElement[]), toString()

UnsupportedOperationException o UnsupportedOperationException(), o UnsupportedOperationException(String)

Package java.util
o o o o o o o o o o o o o o

AbstractCollection add(Object), addAll(Collection), clear(), contains(Object), containsAll(Collection), isEmpty(), iterator(), remove(Object), removeAll(Collection), retainAll(Collection), size(), toArray(), toArray(Object[]), toString()

AbstractList o add(int, Object), o add(Object), o addAll(int, Collection),

o o o o o o o o o o o o o

clear(), equals(Object), get(int), hashCode(), indexOf(Object), indexOutOfBounds(int), iterator(), lastIndexOf(Object), listIterator(), listIterator(int), remove(int), removeRange(int, int), set(int, Object)

AbstractMap o clear(), o containsKey(Object), o containsValue(Object), o entrySet(), o equals(Object), o get(Object), o hashCode(), o isEmpty(), o keySet(), o put(Object, Object), o putAll(Map), o remove(Object), o size(), o toString(), o values() AbstractSet o equals(Object), o hashCode(), o removeAll(Collection) ArrayList o ArrayList(), o ArrayList(Collection), o ArrayList(int), o add(int, Object), o add(Object), o addAll(Collection), o clear(), o clone(), o contains(Object), o get(int),

o o o o o o o o o o o o

indexOf(Object), indexOf(Object, int), isEmpty(), lastIndexOf(Object), lastIndexOf(Object, int), remove(int), remove(Object), removeRange(int, int), set(int, Object), setSize(int), size(), toArray(Object[])

o o o o o o o o o o o o

Arrays asList(Object[]), binarySearch(byte[], byte), binarySearch(char[], char), binarySearch(double[], double), binarySearch(float[], float), binarySearch(int[], int), binarySearch(long[], long), binarySearch(Object[], Object), binarySearch(Object[], Object, Comparator), binarySearch(short[], short), sort(Object[]), sort(Object[], Comparator) Collection add(Object), addAll(Collection), clear(), contains(Object), containsAll(Collection), equals(Object), hashCode(), isEmpty(), iterator(), remove(Object), removeAll(Collection), retainAll(Collection), size(), toArray(), toArray(Object[]) Collections binarySearch(List, Object), binarySearch(List, Object, Comparator),

o o o o o o o o o o o o o o o

o o

o o o

reverse(List), sort(List), sort(List, Comparator)

o o

Comparator compare(Object, Object), equals(Object) ConcurrentModificationException ConcurrentModificationException(), ConcurrentModificationException(String)

o o

Date o Date(), o Date(int, int, int), o Date(int, int, int, int, int), o Date(int, int, int, int, int, int), o Date(long), o Date(String), o UTC(int, int, int, int, int, int), o __parse(String), o after(Date), o before(Date), o clone(), o compareTo(Date), o compareTo(Object), o equals(Object), o getDate(), o getDay(), o getHours(), o getMinutes(), o getMonth(), o getSeconds(), o getTime(), o getTimezoneOffset(), o getYear(), o hashCode(), o parse(String), o setDate(int), o setHours(int), o setMinutes(int), o setMonth(int), o setSeconds(int), o setTime(long), o setYear(int), o toGMTString(), o toLocaleString(),

toString()

EmptyStackException EventListener EventObject EventObject(Object), getSource() HashMap HashMap(), HashMap(int), HashMap(int, float), HashMap(Map), clear(), clone(), containsKey(Object), containsValue(Object), entrySet(), get(Object), isEmpty(), put(Object, Object), putAll(Map), remove(Object), size()

o o

o o o o o o o o o o o o o o o

HashSet o HashSet(), o HashSet(Collection), o HashSet(int), o HashSet(int, float), o add(Object), o clear(), o clone(), o contains(Object), o isEmpty(), o iterator(), o remove(Object), o size(), o toString() Iterator o hasNext(), o next(), o remove()

List o add(int, Object), o add(Object), o addAll(Collection), o addAll(int, Collection), o clear(), o contains(Object), o containsAll(Collection), o equals(Object), o get(int), o hashCode(), o indexOf(Object), o isEmpty(), o iterator(), o lastIndexOf(Object), o listIterator(), o listIterator(int), o remove(int), o remove(Object), o removeAll(Collection), o retainAll(Collection), o set(int, Object), o size(), o toArray() ListIterator o add(Object), o hasNext(), o hasPrevious(), o next(), o nextIndex(), o previous(), o previousIndex(), o remove(), o set(Object) Map clear(), containsKey(Object), containsValue(Object), entrySet(), equals(Object), get(Object), hashCode(), isEmpty(), keySet(), put(Object, Object),

o o o o o o o o o o

o o o o

putAll(Map), remove(Object), size(), values()

MissingResourceException o MissingResourceException(String, String, String), o getClassName(), o getKey() NoSuchElementException NoSuchElementException(), NoSuchElementException(String) RandomAccess Set add(Object), addAll(Collection), clear(), contains(Object), containsAll(Collection), equals(Object), hashCode(), isEmpty(), iterator(), remove(Object), removeAll(Collection), retainAll(Collection), size(), toArray()

o o

o o o o o o o o o o o o o o

Stack o clone(), o empty(), o peek(), o pop(), o push(Object), o search(Object) TooManyListenersException Vector Vector(), Vector(Collection), Vector(int), add(int, Object),

o o o o

o o o o o o o o o o o o o o o o o o o o o o o o o o o o o

add(Object), addAll(Collection), addAll(int, Collection), addElement(Object), clear(), clone(), contains(Object), copyInto(Object[]), elementAt(int), firstElement(), get(int), indexOf(Object), indexOf(Object, int), insertElementAt(Object, int), isEmpty(), iterator(), lastElement(), lastIndexOf(Object), lastIndexOf(Object, int), remove(int), removeAllElements(), removeElement(Object), removeElementAt(int), removeRange(int, int), set(int, Object), setElementAt(Object, int), setSize(int), size(), toArray()

Package java.io

Serializable

Packagescom.google.gwt.core.clientFundamentalclassesusedinclientsideGWTcode.
com.google.gwt.core.extClassesusedtoextendtheGWTcompiler. com.google.gwt.core.ext.typeinfoTypeintrospectionsupportclassesusedbygenerators. com.google.gwt.http.clientProvidestheclientsideclassesandinterfacesformakingHTTPrequestsand processingtheassociatedresponses. com.google.gwt.i18n.clientInternationalizationsupportforGWTapplications. com.google.gwt.json.clientClassesforparsingandcreatingJSONencodedvalues. com.google.gwt.junit.clientClassesandmodulesusedinbuildingJUnittests. com.google.gwt.user.clientFundamentaluserinterfaceclassesusedinclientsideGWTcode.

com.google.gwt.user.client.rpcClassesusedinclientsideimplementationofremoteprocedurecalls. com.google.gwt.user.client.uiWidgets,Panels,andotheruserinterfaceclasses. com.google.gwt.user.server.rpcClassesusedinserversideimplementationofremoteprocedurecalls. com.google.gwt.xml.clientBasicclassesusedinXMLDOMparsingandXMLdocumentgeneration.

Das könnte Ihnen auch gefallen