File Upload Widget for the Google Web Toolkit

It’s been a while but now that school is done kicking my ass I’ve turned my attention back to my beautiful web applications. Recently I’ve been doing a lot of work with the Google Web Toolkit []. It’s turned my hatred of Javascript and AJAX into a renewed love affair with Java and Google.

Basically, the toolkit let’s me write complicated, messy Javascript in beautiful Java that will work on any browser (99.9% of the time). The toolkit is full of awesome feature including easy to use RPC classes, GUI widgets that look and work the same across browsers, and even a native interface to work with Javascript (if you absolutely have to).

Enough with the details and praise, check the GWT website if you have more questions, it’s time for some useful code. I plan on writing a bunch of articles on some classes I’ve written, but today I’m going to start with something simple: a file upload widget. The GWT has a widget for just about every HTML element except file upload. It’s totally understandable because a well written widget would require the creation of some sort of complicated backend (script or applet) and that would ruin some of the purity of the GWT solution.

OK, time for some code:

import*; import*;

public class FileUpload extends Widget {

private class UploadFrame extends Frame {

public UploadFrame(String name) { this(name, null); }

public UploadFrame(String name, String url) { super(url); DOM.setAttribute(getElement(), "name", name); DOM.setStyleAttribute(getElement(), "width", "0"); DOM.setStyleAttribute(getElement(), "height", "0"); DOM.setStyleAttribute(getElement(), "border", "0"); }


private Element form = DOM.createElement("form"); private Element fileUpload = DOM.createElement("input");

public FileUpload(String name, String action) { setElement(form); DOM.setAttribute(form, "action", action); DOM.setAttribute(form, "method", "POST"); DOM.setAttribute(form, "enctype", "multipart/form-data"); DOM.setAttribute(form, "target", name); DOM.setAttribute(fileUpload, "name", name); DOM.setAttribute(fileUpload, "type", "file"); DOM.appendChild(form, fileUpload); DOM.appendChild(RootPanel.getBodyElement(),(new UploadFrame(name)).getElement()); }

public FileUpload(String name) { this(name, ""); }

public void setAction(String action) { DOM.setAttribute(form, "action", action); }

public String getAction() { return DOM.getAttribute(form, "action"); }

public Element getElement() { return form; }

public native void upload() /*-{ this.@com.application.client.FileUpload::getElement()().submit(); }-*/;


A few caveats:

  1. This widget offers no feedback to the GWT application of the upload status. This could be remedied by some sort of RPC to the backend. I only used this class to upload some batch data and give back a processed file.
  2. Any references to com.application should be changed to reflect your own application hierarchy.

Just append this widget to some container in your application and execute the upload() method when it’s time to upload (most likely after pushing some sort of upload button).

Piece of cake right? Please email me with suggestions and other solutions while I fix/update my last posting.