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!