There are a number of tools available for styling UiBinder templates:
styleName
attribute of a widget binder tag.addStyleNames
attribute.ui:style
tag defining local styles.ui:style
tag with a src
attribute for accessing CSS files
from your source directories.ui:with
tag, used to access client
bundles, which may
include CSS resources (instances
of
CssResource
within a ClientBundle
).styleName
and addStyleNames
Attributes The styleName
attribute sets the primary style for the element,
replacing any primary style built into the widget.
addStyleNames
accepts a space-separated list of style names,
which wil automatically be added as if you had called the addStyleName
method
for each word in the list.
Without using the ui:style
element described below, the styles
will come from your CSS files in the war folder
(or from a CSS file in your source tree under the public
folder and included
in your gwt.xml
file using a stylesheet
tag).
These two approaches are recommended in favor of invoking setStyleName
and addStyleName
in
the associated Java file, since they provide a better separation of styling
from programming code, and also simply help minimize the Java code you need
to write. They're particularly useful for container elements for which you
don't need any other programmatic access, so that you can apply styling to
the element without making them a UI field in your Java class.
ui:style
and ui:with
ElementsThis provides for local styles, defined within the bounds of the ui:style
tag, whose names are obfuscated within the local scope. The tag accepts a field
attribute,
whose default value is "style"
.
For each ui:style
element, the compiler wil generate a ClientBundle
and CssResource
.
This means that you will get a compiler error if you misspell a class name (in
fact, if you wait long enough in Eclipse, you should see the offending name
flagged with an error marker).
Each individual field name gets obfuscated separately, so multiple style tags
can define the same style class name without a name collision (however, you
would need field
attributes for the style
tags).
The class names you define can be used for a class
attribute
in an HTML binder, and styleName
and addStyleNames
in
a widget binder.
You reference these names within the styleName
and addStyleNames
attributes
by enclosing the style name in a pair of curly braces.
Note that the curly brace syntax will actually be applied for any attribute,
not just CSS-related ones. To avoid parsing of an attribute (like text
)
that might contain curly-braces, the opening brace can be escaped by doubling
up: {{
.
CSS files can be retrieved from your source tree using a src
attribute
on a ui:style
tag. These would be plain CSS files, not in a ClientResource
/CssResource
.
They would be located under your source tree, not under the war directory.
To reference and create a CssResource
from the file NoBundle.css
in
the css
subpackage of the this binder's packge:
CssResource
You can also obtain a CssResource
to use within a binder template,
by using the ui:style
element.
The type
attribute specifies the fully-qualified name of the CSS
resource class. GWT's code generator will create a client bundle for you, where
the CSS resource style rules are supplied by the content of the tag, instead
of a file referenced with an @Source
annotation. This feature opens
up possibilites for separate skinning of different binders.
To use the resource:
ClientBundle
You can also obtain a ClientBundle
to use within a binder template,
but using the ui:with
element instead of ui:style
.
The type
attribute specifies the fully-qualified name of the resource
bundle class.
Here's the bundle Java class:
And the CSS resource class:
To access a CSS resource from the bundle, and a style name, treat the bundle method to retrieve the CSS resource as a property, and also treat the method to retrieve the class name as a property:
Note that there's no requirement that the resource values used be CSS. Anything
that can be created with GWT.create
can be used this way. In the code fragment
below, we access a text resource from the same client bundle:
Note that we need to "invoke" the getText
method by its name,
instead of treating the get
part as implied. (As opposed to how
the text
attribute causes the widget's setText
method
to be invoked in a widget tag.)
But wait, there's more! It turns out that you can even access an ordinary
class using ui:with
. The same treat methods as properties approach can be used
to retrieve values from the class.
If you need to pass values to the class, either as constructor parameters
or using set methods, you can provide a ui:attributes
child tag,
using the same approach that you would use with widget tags - a tag attribute
that matches a constructor parameter name, or an attribute that matches a set
method.
Here's an arbitrary class we'll pull into a binder. It stores a set of image
resources which can be referenced by a string name, as well as by the index
of that string in an array. Note the annotated constructor, which defines the
constructor that a UiBinder will use to create an instance, and also the method
setExplicitDefaultIndex
:
Here are two different ways to create an instance of the class within a UiBinder:
The first element creates an instance of the class using the constructor parameter to set the default index to 3. An unfortunate side-effect of the UI constructor concept is that we must always supply the default index to it, even if we are going to replace it with an explicit value, as in the second case.
And here's how we can use those items:
Here is an Eclipse project that demonstrates a number of different aspects of UiBinder styling, including the above examples.
Note that in order to minimize the file size, the gwt-servlet.jar
file is not included. After unzipping and importing into an Eclipse workspace,
you can usually reinstate it by going to the project's properties, under the
Google ... Web Toolkit sections, removing the check from Use Google Web Toolkit,
then OK. Then go back through the same process to put the check back and OK again.