The GWT community is full of activity; so much so that it sometimes becomes difficult to keep track of! I thought it would be a good idea to try and gather some of this action in one place, so without further ado, here's what's going on in the GWT community!
Restlet 1.1.0 released: Using REST APIs with Servlets used to require wasted hours writing custom code. Fortunately, Restlet came along to take that pain away. Even more fortunately, Restlet integrates with GWT to make dealing with REST APIs a breeze. The team has recently announced their 1.1.0 release, might be worth a spin if you've exhausted yourself writing custom code and need some REST.
Hibernate4GWT (Gilead) 1.2 RC1: Hibernate is an extremely powerful ORM framework for the Java programming language. It has proven itself as an invaluable tool for those with tight data-to-domain mapping, and thanks to Hibernate4GWT, has become easily accessible to GWT application developers. Hibernate 1.2 RC1 (aka Gilead) is now available to download.
SmartGWT 1.0 released: SmartClient is a framework that allows you to not only utilize its widget library for your application UI, but also tie these widgets in with your server-side for data management. SmartGWT 1.0, combining both GWT and SmartClient, has been released thanks to the efforts of Sanjiv Jivan. Read more about it in Sanjiv's release announcement.
GWT Maven heaven: The gwt-maven project developed by Charlie Collins and fellow project members provides a way for developers using a Maven to easily integrate GWT into their build system. We also have Nicolas De loof who has been working on a GWT Maven plug-in in the Mojo project. We're happy to say that Charlie Collins and Nicolas De loof are now going to form GWT Maven heaven by integrating the functionality of both plugin together and hosting them on the Mojo project.
Jared Jacobs is the frontend lead at kaChing, a marketplace for investing talent. He had a chance to stop by and give us the lowdown on his team's successful port of their GWT application onto the Facebook platform. If you're looking to socialize your application on Facebook, read on for the steps to make it happen.
As you may know, social networks like Facebook, LinkedIn, and MySpace can be an excellent place to grow a new business. Most of the kaChing community first discovered us through friends using our Fantasy Stock Exchange Facebook app.
In this post, I'll help you get your GWT app running as a Facebook app. Believe it or not, it can be done in just two easy steps.
And you're done! Visit the Canvas Page URL that you chose, and you'll see your GWT app running in Facebook. The rest of this post will suggest a couple of ways to integrate more fully, to better leverage the Facebook platform.
If your GWT app is too wide for the containing Facebook iframe and you can't stomach a horizontal scrollbar, then you need to make your app slimmer - at least when it's running inside Facebook. Facebook's width limit (currently 760px) is a hard limit.
If your GWT app is too tall, it'll be clipped and you'll see a vertical scrollbar along the right side. To fix this, you can specify a large fixed canvas height for your app using the CanvasUtil feature of Facebook's JavaScript Client Library. You can read the docs for more detail, but in practice it boils down to adding the following snippet to the body of your app's main HTML page:
<script type="text/javascript" src="http://static.ak.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"> </script> <div id='FB_HiddenContainer' style='display:none;position:absolute;left:-100px;top:-100px;width:0;height:0'> </div> <script type="text/javascript"> window.onload = function(){ FB_RequireFeatures(['CanvasUtil'], function(){ FB.XdComm.Server.init('some/path/to/xd_receiver.html'); FB.CanvasClient.setCanvasHeight('2000px'); }); }; </script>
You should customize the highlighted parts. Here's a description of what's going on in the snippet above:
FB.CanvasClient.setCanvasHeight('2000px', function(){FB.CanvasClient.startTimerToSizeToContent()});
For more info on the CanvasUtil feature, including how to make the containing Facebook window scroll to a desired location, see this demo iframe app.
If a Facebook user is logged into Facebook when accessing your Facebook app, the app URL will include the user's Facebook ID in the query string as the fb_sig_user or fb_sig_canvas_user parameter, depending on whether the user has authorized your application. (See Authorizing Applications for more on the various request parameters.) You can use this Facebook ID, in conjunction with your app's ID and secret key, to request information about the user from Facebook using any of Facebook's various APIs. As a GWT app author, you are likely to be using a Java server, so consider using one of these Java Facebook clients. We use this open-source Facebook Java API.
For a high-level overview of Facebook's various APIs and their relative merits, I'd recommend a recent blog post by Facebook Platform engineer Charlie Cheever.
I hope this article helps you get your snazzy, snappy GWT apps to larger audiences. If you can afford the time investment, be sure to utilize social network integration points that can spur viral growth, such as invitations, profile boxes, and activity streams.
One of the best resources for developers looking for tips on building applications or learning about a new technology is to hear from other developers who have already been through the experience and built world-class applications. That's why we're happy to share videos of a few developers who used the Google Web Toolkit to build rich, sophisticated Ajax applications that have wowed audiences, won prestigious awards and are pushing the boundaries of what we've come to expect from a web application.
Check them out in our new Who's Using GWT page. In these videos, the developers explain how they used GWT to build their apps, their opinions on GWT overall, and tips and learnings from working with GWT. These videos include the developers behind:
We'd love to hear from others in the community. If you would like to share your experience developing GWT applications with the rest of the community, let us know in the forum.
A lot of discussion occurs in the Google Web Toolkit contributors forum about development progress, feature requests, and the roadmap. We realize that many of you are very busy and would like to see a simple roadmap on the website, so we've updated "Making GWT Better" with our current plans.
As with any development work, its hard to exactly predict when things will land, so we've stayed away from specific dates and releases past the next one. You'll be happy to know that release 1.6 is well underway and on target for Q1 of 2009.
You can check for future updates in the Making GWT Better section of our website.
Anticipated Time Frame - Q1 2009
The following are features that are on our roadmap for releases post 1.6, but are in various states of development. As we reach the end of the 1.6 cycle, we'll update the roadmap with which features we are targeting for the next release.
For those of you interested in creating visualizations in your Google Web Toolkit applications, we're happy to announce the Google Visualization API Library for Google Web Toolkit (GWT). This adds another library of Java language bindings for JavaScript APIs provided by Google, collectively known as the suite of Google API Libraries for Google Web Toolkit.
We're also releasing a General Availability build of the Google Maps API Library for GWT. This build contains a few bug fixes that contributors have reported. Thank you for reporting those, and please continue to report them in the issue tracker.
You can read more about the new Visualization API in the announcement on the Google Code blog.
StudyBlue is an academic social networking application, built with GWT, that helps students study smarter, faster. StudyBlue has done a great job with their application styling and design, so much so that they are shooting for a Crunchie Award on Tech Crunch for Best Design 2008.
We're fortunate to have StudyBlue President Chris Klundt and Eric Wuebben, Creative Director for StudyBlue, share their experience styling their potentially award-winning application using GWT and well-planned CSS techniques. If you've ever wondered how you can turn your GWT project into the next most styling application on the block, read on below.
We've been approached by many programmers and designers alike that question how we got such a custom look using GWT. Our response is simple, "Use GWT to build the house, not to paint it." When you build a new house, you don't have your building contractor pick out the furniture, choose the color palette, or stencil the walls. Similarly, you shouldn't use GWT to inject all the "style" into your website. Instead, you rough it out with GWT and push the design to CSS.
Whether you're building a small widget to embed in an existing site, or you're building an entire web-application from scratch (that's us :-) ), we recommend the following three tenants to ensure maximum design efficiency and flexibility:
Sticking with our home construction analogy, you might go about building a home by first having an architect envision a space, then having his apprentice detail the blueprints, before finally having a contractor build the house. Similarly, you should assemble a good design team before diving into the construction of your site with GWT. Chances are, if you are a strong Java programmer (i.e. "the GWT Programmer"), you are not as strong at CSS design and image slicing. You need to know what team members you have at your disposal, and what their strengths are. Once you're set with a Designer and a CSS Stylist (they may be the same person), we recommend you follow this general workflow:
Let's elaborate a bit on points 2, 3 and 4.
Part of knowing your team means understanding what your Web Designer's preferences are when it comes to using Tables or DIVs. GWT offers widgets that encompass both Tables (HorizontalPanel, FlexTable, etc.) and DIVs (FlowPanel, HTML, etc.). There are benefits and drawbacks to using each of them. For example, Tables might be good for vertical/horizontal centering or adding stability to a grid. They are poor for dynamic positioning, hover states, "rounded corners", etc. Whatever the case, both the GWT Programmer and the Web Designer should have an agreed understanding on which layouts (Tables or DIVs) are to be used and when it's appropriate to make exceptions. We prefer to do use DIVs, using FlowPanel much more often than HorizontalPanel or VerticalPanel.
Creating a "blueprint" is important for three reasons. First, it helps eliminate guess work from the GWT Programmer. An HTML "blueprint" can quickly be tested on all browsers to prove that the style renders to the structure as expected. Secondly, "blueprints" are an easy way to communicate between GWT Programmer and Web Designer without both parties having to be in the same room at the same time. Plus it makes it easy to assign blame when things don't look right :-). Finally, creating the "blueprint" will help you realize what looks in the original artwork are impossible to recreate on the site (hopefully none).
Note: Using the WebDeveloper plugin (or Firebug's Inspect) for Mozilla Firefox is a great way to inspect your final layout as a GWT Programmer, to make sure you match the "blueprint". More on this later.
Finally, when you start creating the layout in GWT, remember to break down each piece into a Composite class. Not every Composite you create will be reusable. Sometimes you have to make your widgets so specific that they can't be reused. That's OK, it's a common occurrence in UI programming. However, many widgets you can design to be reusable. One obvious example is "buttons" on your website.
We can't stress this point enough: PUSH YOUR STYLING TO A CASCADING STYLE SHEET (CSS). Just about everything you can do style wise can be done with CSS, so keep it that way.
HTML randomText = new HTML("This is some random text in a DIV"); DOM.setElementProperty(randomText.getElement(), "color", "green"); DOM.setElementProperty(randomText.getElement(), "fontSize", "16px");
HTML randomText = new HTML("This is some random text in a DIV"); randomText.setStyleName("sb-TextWidgets-RandomText");
.sb-TextWidgets-RandomText{ color: green; font-size: 16px; }
So let's look at a more complex example, a navigation bar with "hover" and "selected" states. Below you'll notice we've created reusable code for our "hover" and "selected" state that can be used by any widget that we want to implement "hover" or "selected".
Hover Class:
public class Hover { private static MouseListenerAdapter mla; public static MouseListenerAdapter getHoverMla(){ if(mla == null){ mla = new MouseListenerAdapter(){ public void onMouseEnter(Widget hoverableWidget){ hoverableWidget.addStyleDependentName("hover"); } public void onMouseLeave(Widget hoverableWidget){ hoverableWidget.removeStyleDependentName("hover"); } }; } return mla; } . . . }
public class Selected { private List<HTML> itemList; private ClickListener cl; public Selected(){ itemList = new ArrayList<HTML>(); cl = new ClickListener(){ public void onClick(Widget selectedItem) { for(HTML item : itemList){ if(item.equals(selectedItem)){ item.addStyleDependentName("selected"); } else{ item.removeStyleDependentName("selected"); } } } }; } public ClickListener getSelectedCL(){ return cl; } public void addItem(HTML item){ itemList.add(item); item.addClickListener(cl); } public void removeItem(HTML item){ itemList.remove(item); item.removeClickListener(cl); } }
public class NavBar extends Composite{ public static String BLOG_HOME="http://blog.studyblue.com/"; private int ID=1; private Selected selector; public NavBar(){ super(); selector = new Selected(); FlowPanel holder = new FlowPanel(); holder.setStyleName("NavBar-Holder"); holder.add(link("Blog","")); holder.add(link("About Us","about")); holder.add(link("Jobs","about/jobs")); setWidget(holder); } private HTML link(String text, String location){ HTML ret = new HTML(text); ret.setStyleName("nav-item-"+ID); ret.addStyleName("nav-item"); selector.addItem(ret); ret.addMouseListener(Hover.getHoverMla()); ret.addClickListener(new ClickListener(){ public void onClick(Widget sender){ ///Open popup with blog page location } }); ID++; return ret; } }
.nav-item { background-image: url(images/nav.png); background-repeat: no-repeat; background-position: 0 0; display: block; height: 0px; padding: 30px 0 0 0; overflow: hidden; } .nav-item-1 { background-position: 0 0; width: 65px; } .nav-item-2 { background-position: -65px 0; width: 90px; } .nav-item-3 { background-position: -155px 0; width: 65px; } .nav-item-1-hover { background-position: 0 -30px; } .nav-item-2-hover { background-position: -65px -30px; } .nav-item-3-hover { background-position: -155px -30px; } .nav-item-1-selected { background-position: 0 -60px; } .nav-item-2-selected { background-position: -65px -60px; } .nav-item-3-selected { background-position: -155px -60px; }
So, let's break down what is going on here. The NavBar is a Composite which is holding a FlowPanel ("holder"). This FlowPanel is a DIV which is going to hold our 3 links: "blog", "about us", and "jobs". Each one of these links is an HTML widget (i.e. a DIV). Inside the method "link" we first are creating each HTML with the appropriate text, setting its style name with a unique integer, adding an additional style name. From there, we add the link to our "selector" as well as add a "hover" listener. Finally, we add a ClickListener which initiates an action (in this case taking the user to the blog).
Some things to note:
Without our CSS, the result would simply look like this:
Blog About Us Jobs
However, by adding a few style names, we are able to achieve a look like this:
We also streamlined our development by standardizing the use of stand-alone buttons on the site. That way, the GWT Programmer can create a button widget that can be reused depending on the size and color button needed. The widget uses DEPENDENT style names to produce small, medium, or large buttons colored with green, white, blue, or red that are preset in the style sheet and work for flexible content lengths.
It is really important to have a test environment for your Web Designer to mess with. As a GWT Programmer, you can't expect that your Web Designer will be able to run Hosted Mode. Also, until the GWT guys implement Out-of-Process Hosted Mode (OOPHM), you will definitely want to take a look at your product in all the major browsers before deploying to production. We run a Tomcat instance on a powerful box over at Amazon Web Services. Using SVN and Ant, we update all our code to the test machine, compile it, create a WAR and deploy it using one command. The key here is that this process takes over 6 minutes every time we want to deploy new code. Six minutes may not seem like that long, but when your Web Developer is waiting 6 minutes every time you need to make a small change to the layout, it gets annoying. So we implemented two ideas to help ease the pain.
First, if you take one thing away from this post, don't style using the GWT DOM class. Set your style names and let the CSS do the work. If we had put all the styles in the GWT code, it would take us 6 minutes to change the color of some trivial text, only to find out that we liked it better the old way (another 6 minutes).
Second, pull out your CSS files and images directory to some location outside your WAR. The idea here is that the Web Designer can manipulate the CSS and imagery without ever getting inside your WAR. This way, when its time to deploy new code, you don't overwrite the Web Designer's changes by replacing the CSS file and/or images on accident. This also helps with remote collaboration. The Web Designer gives the GWT Programmer the "blueprints", the GWT Programmer builds the app and deploys it to the test server, the Web Designer is free to make changes to the CSS and images while checking compatibility across all the browsers. Theoretically, you'd never have to be in the same room (although we don't prefer it that way).
Now get out there and build an awesome GWT house!
By Sumit Chandel, Google Web Toolkit Team
A couple weeks ago, I talked about On-demand widget creation in GWT, a technique you can use to improve the performance of your own GWT applications. What we detailed there was how to apply the technique and what benefits it yields, however we only briefly touched on when and where to apply the pattern.
Applying on-demand widget creation in your application requires a measured understanding of your GWT application's performance. Profiling your application is key to identifying performance hot spots that could be improved using the lazy load pattern or other performance tune-up techniques.
The two key data points to consider when profiling your application are slowdowns and memory usage. Here the term slowdown relates to how slow your application performs in terms of the JavaScript and DOM manipulations that are being processed to run the application. Obviously slowdowns are bad because they lead to sluggish user experiences and less users on your site. Memory usage is equally important as an application that leaks or consumes large amounts of memory is likely to slowdown or crash the user's browser, which also leads to users leaving your site, most likely preceded by profuse cursing.
In this post I wanted to share some tips you could use to profile your own GWT application to help plan your on-demand creation strategy or apply other performance improving code fixes.
One of the tools that I usually use to profile GWT applications is the FireBug plugin for Firefox. It has great support for profiling JavaScript performance, which you can use to help find hotspots in your code where certain widget creation calls are taking up too much time and would be better loaded on demand.
Don't try this out just yet! The GWT compiler takes care of optimizing and obfuscating the JavaScript generated from your GWT source, therefore if you tried to run the FireBug profiler over your application without first compiling your application with the -style PRETTY flag, you'll have a really hard time figuring out what you're profiling.
To re-compile your GWT application in PRETTY mode, simply tweak the MyApplication-compile script if you used the applicationCreator or change your GWT compile run configuration to pass the -style PRETTY mode flag to the compiler (e.g. for Linux -compile script shown below):
#!/bin/sh APPDIR=`dirname $0`; java -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$APPDIR/../../gwt-user.jar:$APPDIR/../../gwt-dev-linux.jar" com.google.gwt.dev.GWTCompiler -style PRETTY -out "$APPDIR/www" "$@" com.google.gwt.sample.mail.Mail;
Once you've compiled in PRETTY mode, you should be able to use FireBug's JavaScript performance profiler with ease to help identify spots where you would want to load your widgets on demand rather than all at once. You can look forward to something like the screenshot below:
Yet another way to profile your application is to do it manually by setting start / finish timestamps before and after the component you care about profiling, respectively. For example, let's say I wanted to determine the initial load time for the phone book application we developed as an example in the last blog post. I would first set a timestamp in my host HTML page, way up in the <head> of the document to make sure that the timestamp is recorded right when the first resource is picked up.
<title>Phonebook</title> <script language="javascript"> window.startTime = new Date().getTime(); </script> <iframe src="javascript:''" id="__gwt_historyFrame" style="border: 0pt none ; position: absolute; width: 0pt; height: 0pt;"></iframe>
Then I would add the finish timestamp right at the end of the onModuleLoad() method, which should allow me to get a good indication of how long it took to load the application from start to finish.
public void onModuleLoad() { ... displayLoadTime(); } private native void displayLoadTime() /*-{ $wnd.alert("Load time: " + (new Date().getTime() - $wnd.startTime)); }-*/;
A note about what's being measured here - there are some elements that are not included in this measuring technique that affect load time performance. For example, any external scripts that are required to load your application will not be factored into this measure by default; nor will any references to other external resources such as stylesheets. You can include these resources in your load time measurement by adding the corresponding tag in your module XML file so that they are loaded synchronously. Also, image fetches are not included in this load time measure (although you can use the ImageBundle to gather your images in a single download that you can time individually). What's more, any code that is executed in a DeferredCommand or an IncrementalCommand will not be picked up with this measuring technique.
Also, this measure captures the time it takes to execute code to load and display the widget, but not actually render it on the browser DOM with styles applied. Capturing that kind of measure would require far from trivial browser instrumentation.
That said, this measuring technique is still a good way to profile parts of your application and compare them to other implementations since you can accurately measure the time it takes to execute the code responsible for loading your widgets. You could set up the same load time measurement around any other widget creation method that you want to evaluate for on-demand loading. If you feel that setting up alerts to display the load time measurements is a little silly, you may want to take a look at Fred Sauer's gwt-log project, which allows you to log timestamps among other things while developing your GWT application.
Another note about manual timer measurements - there is a slight difference in timer resolution depending in which browser you're running the code above. However, the delta between browsers is usually less than 15ms, and not a humanly noticeable delay. Therefore this difference should be negligible as you collect data points to plan out your on-demand widget creation strategy.
Another thing to keep in mind is that aside from timer resolution differences, browsers do have different load times in general, so it's important to profile your application for each major browser you intend on supporting for your users.
Aside from the profiling techniques described above, there is always the old fashioned way of doing things - just trying it out and seeing how it feels. When something feels sluggish, chances are that it is and needs to be fixed. If you want to drill down to numbers, typically a delay greater than 0.8 seconds in load time is perceived by the user as a full second delay, and starts to qualify an application as sluggish.
Hopefully this post gave you some guidance on how to go about collecting data points about your application in order to plan strategies and fixes to improve performance. While some of the profiling techniques listed above should go a long way, the state of profiling tools around Ajax is still evolving and will take some time before becoming the rich environment developers may remember from days of old (desktop development).
A good place to get more tips about profiling and performance tune up techniques is on our very own GWT developer forum. We have tons of developers posting up there who have developed their own tricks to profile their GWT applications and improve performance, and they'd be happy to share their insights if you're looking for more ways to improve your own applications.