Monday, May 29, 2006

GWT Widget Library Has Moved

I am moving my news specific to the GWT Widget Library to http://gwtwidgets.blogspot.com/. I am doing this to make it easy to find the latest versions of the package. I do expect to make reference to the library here, but more in the respect of rants, comparisons, how-to's, and such.

So on that note, I would like to announce the release of GWT Widget Library 0.0.2.

Cheers.

Friday, May 26, 2006

GWT Widget Library Additions

The next release of the GWT Widget Library should be out by Tuesday. The main addition thus far are the ImageButton and ToggleButton widgets. Both of these support the usual JPEG and GIF, as well as PNG.

If you are unfamiliar with PNG it may be because IE6 does not have proper support for it, although there is a workaround. The new button widgets take advantage of the workaround and allow the use of PNG in IE 5.5 and IE6. The advantage of PNG is that it supports an alpha channel, allowing you to see through the image. This avoids having to deal with matting, and the image looks good no matter what background color is used behind it.

Here is a screenshot of an icon bar consisting of several ImageButton widgets using PNG images from the Tango Project.

Icon Bar

Wednesday, May 24, 2006

ANNOUNCE: GWT Widget Library

The GWT Widget Library is a library of widgets and wrappers for the Google Web Toolkit. Currently this is a very short list, which will expand in time.

This is being distributed under the GNU-LGPL.

Version 0.0.1 Features:
Download:
Examples:

Example of using an effect with options:

Effect.highlight(widget, new EffectOption[]{
new EffectOption("startcolor", "#ff0000")
});


Example of using an effect with no options:

Effect.fade(widget);


Example of using an effect on a specific element id:

Effect.switchOff(RootPanel.get("leftNav"));

Tuesday, May 23, 2006

How to Package GWT Components

This is a response I sent to the Google Web Toolkit group in response to questions about how to package user created components into a JAR file for reuse. The full message thread can be found in Google Groups.

I created a widget called "Heading" which wraps the text in the appropriate
<h1></h1> HTML tag.

The contents of the JAR file look like this:

 META-INF/
META-INF/MANIFEST.MF
org/
org/hanson/
org/hanson/gwt/
org/hanson/gwt/client/
org/hanson/gwt/client/Heading.class
org/hanson/gwt/client/Heading.java
org/hanson/gwt/Components.gwt.xml

The widget class AND source must be in the "client" package (you can change
this in the gwt.xml file if needed). The source must be present for the
compiler to generate the JavaScript.

The structure of the JAR, in general, should be like this:

some.package.MyName.gwt.xml (project properties)
some.package.client.* (code to be compiled to JavaScript)
some.package.public.* (images or other files)
some.package.xyz.* (anything else)

==== The source for the Heading widget ====


package org.hanson.gwt.client;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Widget;

public class Heading extends Widget
{
public Heading ()
{
setElement(DOM.createElement("h1"));
setStyleName("rhw-heading");
}

public void setText (String s)
{
DOM.setInnerText(getElement(), s);
}


==== contents of Components.gwt.xml ====

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


NOTE: If you have your client code somewhere other than the "client" Java
package, you need to speficify that here. Same goes for the "public"
package. (See http://makeashorterlink.com/?G4332572D)

To use this JAR in your project you need to make a few changes:

1. Alter your *gwt.xml project file to reference the project file in the
JAR.

Example:

<module>
<!-- Inherit the core Web Toolkit stuff -->
<inherits name="'com.google.gwt.user.User'/">

<!-- ** ADD THIS ** -->
<inherits name="'org.hanson.gwt.Components'/">

<!-- Specify the app entry point class. -->
<entry-point
class="'org.hanson.gwt.client.MyApplication/">
</module>


2. Edit the MyApplication-shell.cmd and MyApplication-compile.cmd scripts,
add the jar to the classpath.

That should be it.

You should take a look at the gwt-user jar. You will find several project
files in there, including com.google.gwt.user.User. You will see that this
file references other projects, some of which use some currently
undocumented tags. Note that for each project in the gwt-user.jar file
there is a "client" package, and optionally a "local" package. You will see
that the images for the Tree widget are in one of the "local" packages.

Anyway, let me know if that helps.

Sunday, May 21, 2006

Google Web Toolkit: We Got Bugs

I was bit by a few bugs myself when trying out Google's Web Toolkit. If you are unfamiliar with it, you can check out my recent post on it. In this entry I want to list the problems that I found in the hopes that it will help others, and as a reminder to myself.

Internet Explorer 7 Issue

If you try to run or debug an app with IE7 installed, you will see this error:

"Failed to load module ... .
Please see the log in the development shell for details."
[ERROR] Unable to load module entry point class


The solution is to uninstall IE7, and all will be well. Miguel from Google had this to say about it.

Yes the problem is related to IE7. When you run <your application>-shell.cmd or when you try to debug from eclipse, we will use the currently installed version of IE to host the web page. We will add support for IE7
but until we do it is better to use IE6. I apologize for the inconvenience. If we come up with a resonable work around I'll ping you with it. - Miguel Méndez

Packaging of RPC Service Interfaces

When you try out the RPC mechanism you may get some of the following errors, depending on what package you put your services interfaces in:

The import org.hanson.gwt.server cannot be resolved
MyService cannot be resolved to a type

The problem may be that the two interfaces required for RPC are not in the "client" package. There seems to be a common issue where developers are wanting to create a new Java package to store the single RPC class and two interfaces, and this is what cases the problem.

The solution is to place the two interfaces in the same package as your main application class, in the "client" package. The RPC class though can be placed in any package.

Nested Anonymous Classes Error

If you find that you can run the application in "hosted" mode, but can't compile the code to JavaScript, then this may be your problem. Here are some of the associated error messages you will see when compiling:

Analyzing permutation #1
[ERROR] Unexpected internal compiler error


The problem is that the compiler which is generating the JavaScript code is getting hung up on a reference to a variable inside of a doublely nested anonymous class.

Below is an example of code that will throw this error. The point of failure is marked with an arrow.

public class MyApplication implements EntryPoint
{

public void onModuleLoad ()
{

final Button button = new Button("Click me");
final Label label = new Label();

button.addClickListener(new ClickListener()
{
public void onClick (Widget sender)
{
MyServiceAsync svc = (MyServiceAsync) GWT.create(MyService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) svc;
endpoint.setServiceEntryPoint("/myService");

AsyncCallback callback = new AsyncCallback() {

public void onSuccess (Object result)
{
====> label.setText(result.toString());
}

public void onFailure (Throwable caught) {}
};

svc.myMethod(text.getText(), callback);
}
});

RootPanel.get("slot1").add(button);
RootPanel.get("slot2").add(label);
}
}


The problem occurs because the variable label lies within a doubly nested anonymous class, and it can't see the label declaration.

The fix is to declare label as an instance variable of the class instead of declaring it inside the method.


public class MyApplication implements EntryPoint
{

final Label label = new Label();

public void onModuleLoad ()
{
...
}
}

Arggg... Blogger!

I have a simple request for Blogger, Wordpress, and other blog providers. When I edit the HTML for an entry, don't modify it!

Both of these services will alter your HTML after you save it. This causes a problem for example, when you want to post code in a <textarea> tag. In Blogger it will place a <br> tag after each newline in the entry, and fills your textarea with line break tags. In Wordpress it just places all of the content in the textarea on one line.

Tthe funny thing is that one of my blogs uses a four year olf version of Movable Type, which has no WYSIWYG editor, but DOES NOT alter my HTML code.

To both of these blog providers I ask, please don't touch my HTML!

Saturday, May 20, 2006

News: Google Web Toolkit

At Java One one of the big announcements was a Google Web Toolkit (GWT). The toolkit allows a programmer to write Java code and compile that code to JavaScript. This allows the programmer to leverage the abilities of their IDE, unit test their client side code, and easily create RPC services.

Here is a sample Java class which adds some elements to the page when the page is loaded.


package org.hanson.gwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
public class MyApplication implements EntryPoint
{
// executed on load
public void onModuleLoad ()
{
final Button button = new Button("Click me");
final Label label = new Label();

button.addClickListener(new ClickListener()
{
public void onClick (Widget sender)
{
if (label.getText().equals("")) {
label.setText("Hello World!");
}
else {
label.setText("");
}
}
});

// add the objects to HTMl elements in the web page
RootPanel.get("div1").add(button);
RootPanel.get("div2").add(label);
}
}

This code creates a button with the text "Click me", and a blank label, and adds them to the HTML page. It then adds an event handler to the button to detect when the button is clicked. The event will trigger the text of the label to change to say "Hello World". This is a trivial example, but it shows how you can create objects an behaviours on the HTML page without directly writing any HTML of JavaScript code.

The question is, how big is this. I think it is BIG with a capital B. As long as Google maintains this tool, making sure that the code works across all browsers, this tool will save tremendous amouts of development time.

technorati tags:

Monday, May 15, 2006

Will CSS Libraries Lower Dev Costs?

Yahoo! recently launched a developer site which has a slightly different offering than the usual "Web 2.0" widget libraries. One of these offerings is a CSS library which consists of a set of three CSS files. Here is a list of the different files, and what they are for.
Fonts CSS
Offers cross-browser typographical normalization and control.


Reset CSS
Offers cross-browser normalization of the default rendering of HTML elements.


Grids CSS
A suite of seven web page templates and the ability to nest grids of one to four columns within the content area of those templates.


With three very small files you have the ability to normalize rendering between browsers and set up a table-less layout within minutes.

I think that these libraries are useful in their own right, but the idea itself is even more important. The practice of programming thrives because of prebuilt libraries that allow developers to worry about the business at hand instead of the details of the platform. I think that CSS libraries can do the same thing, allowing developers to build bigger applications in less time.