Why there are so many way to set CSS for Widgets in GWT or GWTP, I am confused? Can someone clarify this? - gwt

Ok, to set a Css for a widget in Gwt or Gwtp, we can do following:
-1. directly from gwt code. Ex: label1.getElement().getStyle().setBackground("blue");
-2. include "ui:style" in UiBinder xml file, but this css only visible to that UiBinder
-3. include "ui:width" in UiBinder xml file, it will visible to all UiBinder
- and there r many way to set the Css directly to the widget in UiBinder.
The one that made me confused is that if i used , ex
<ui:with field='res' type="com.myproj.client.MyResource" />
& if myResource.css has .gwt-TabLayoutPanel then i don't need to use "addStyleNames", ex <g:TabLayputPanel />, it can recognized CSS perfectly.
However, if i add .gwt-ScrollPanel into myResource.css & use <g: ScrollPanel /> then nothing happened.
So I have to create public interface MyCssResource extends CssResource, then add String gwt-ScrollPanel(); to MyCssResource. But Java eclipse do not allow hyphen - in the method name, so I have to change to String gwtScrollPanel();.
Finally, i have to add addStyleNames into <g: ScrollPanel />, ex <g: ScrollPanel addStyleNames="{res.css.gwtScrollPanel}" /> then it will work.
That also means if i want to use .gwt-TabLayoutPanel in MyCssResource, then i need to remove the hyphen - & this will cause inconsistency in my code.
So, can someone explain to me what is going on here? I am confused?

The only think you should be aware about, is that GWT obfuscates class names when you use then in ui-binders. For instance:
<ui:style>
.gwtTabLayoutPanel {}
</ui:style>
<g:TabLayoutPanel addStyleNames="{style.gwtTabLayoutPanel}" />
.gwtTabLayoutPanel will be renamed to something like .AB in the final injected style-sheet.
But most GWT widgets, are styled with un-obfuscated class names, so for using them in ui-binders files, you have to define as external in order to prevent GWT compier to obfuscate the class name:
<ui:style>
#external .gwt-TabLayoutPanel;
.gwt-TabLayoutPanel {}
</ui:style>
<g:TabLayoutPanel />

That's because when you create a TabLayoutPanel, it has a default class called .gwt-TabLayoutPanel. So you don't need to add that class manually in to your TabLayoutPanel.Just create a TabLayoutPanel and you will see the class ".gwt-TabLayoutPanel" is already there.
But ScrollPanel doesn't comes with a default class called .gwt-ScrollPanel. It is just a div. Try creating a ScrollPanel and see. It doesn't have any classes added initially.see the screenshot
If you want to add a class called .gwt-ScrollPanel you will have to do it manually.

Related

Using non-CSS constants in GWT UiBinder

I'm trying to use constants or defines in GWT's UiBinder XML. All the questions and answers I find are related to CSS constants, using #def annotations in a elements, but that's not what I need. Take this example:
<g:Button width="60" height="24">Hello</g:Button>
If I have 50 buttons on my page, all with the same dimensions, I don't want to have to set each button's dimension as indicated above. If I want to change the width, I have to do this for all buttons on the page. So, what I'm looking for is something like this:
<g:Button width="{myWidth}" height="{myHeight}">Hello</g:Button>
The constants "myWidth" and "myHeight" being specified somewhere at the beginning of the UiBinder XML file. I tried doing this with and but I cannot get it to work.
Any ideas?
A. This is how you do it:
<ui:with field="styleConstants" type="...constants.StyleConstants" />
<g:Button width="{styleConstants.myWidth}" height="{styleConstants.myHeight}">Hello</g:Button>
Obviously, StyleConstants should have myWidth() and myHeight() methods.
B. Setting the same size to 50 buttons is wrong. This is what CSS classes are for. Define a CSS class and assign it to each button:
<g:Button styleName="button">Hello</g:Button>
You can use an external CSS file or a CSS Resource for this purpose.

GWT i18n and images

Is there some way to easily internationalize images (using g:Image and ImageResource) in GWT?
From what I can see, it is possible to internationalize the src attribute of a img element, using:
<img src="http://www.images.com/englishVersionOfImage.png" alt="">
<ui:attribute name="src" description="Image to be internationalized"/>
</img>
and by changing the src value in the appropriate LocalizableResource_xxxx.properties file.
However, this technique does not seem to be applicable to
<g:Image resource="{resources.MyImageResource}"/> elements.
Should be as simple as with all other source types (https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#I18N).
In simple words, if you use something like this for text labels:
Messages.properties
Messages_fr.properties
Messages_de.properties
, then try the same technique with images:
logo.jpg
logo_fr.jpg
logo_de.jpg
The proper file should have been chosen depending on current locale.
So, considering the example from https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder#Using_an_external_resource use:
<g:Image resource='{res.logo}'/>
and then have a class
/**
* Resources used by the entire application.
*/
public interface Resources extends ClientBundle {
#Source("Logo.jpg")
ImageResource logo();
...

Setting styles on different faces of a GWT CustomButton using UiBinder

I'm trying to set style names on different faces of ToggleButton (i.e. upFace, downFace, ...). It looks like setting styleName on a face doesn't work. For example the following won't work:
<g:ToggleButton>
<g:upFace styleName='{style.myToggleButton-up}' />
</g:ToggleButton>
But I noticed when setting the style name on ToggleButton itself...
<g:ToggleButton styleName='{style.myToggleButton}' />
... the generated HTML will look something like this:
<div class="GPAKHSCBGG GPAKHSCBGG-up" role="button" aria-pressed="false">...</div>
However, even if I have {style.myToggleButton-up} defined, it is not populated to GPAKHSCBGG-up. So I'm wondering how can I do this without having to mock the global .gwt-ToggleButton-up stylesheet. Please help.
http://examples.roughian.com/index.htm#Widgets~ToggleButton
All GWT components have predefined CSS Class definitions, what you tried didn't override the definitions.
Solution:
Add #external myToggleButton, myToggleButton-up; to ui:binder file.

Custom tags in UiBinder files

When using a <g:LayoutPanel> in UiBinder.ui.xml files, you can specify <g:layer> tags. Some other Google-built widgets have special tags like that as well - <g:tab> even has a sub-tag, <g:header>.
How can I specify these for my own widgets?
The new answer to this question, after some GWT improvements, is at https://stackoverflow.com/a/11785903/439317 . Copied below to avoid moderator deletion (maybe?).
You can use #UiChild to declare special functions in your widgets accessible in UiBinders.
for example,
class MyPanel extends AbsolutePanel {
#UiChild
public void addAt(Widget w, String parameter1, String parameter2) {
....
Then, in your uiBinder, you can say
<custom:MyPanel>
<custom:at parameter1="HI" parameter2="Anything you like!">
<g:AnySingleWidget />
</custom:at>
</custom:MyPanel>
See #UiChild at http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/uibinder/client/UiChild.html
What you're looking for is a custom element parser for UiBinder. See this issue. Unfortunately it's not supported yet.
You might be interested in this post for some guidance on how to extend the current parser on your own.

GWT - How to define a Widget outside layout hierarchy in uibinder xml file

this is my first post. I hope someone could help me.
I'm looking for a way to define a widget in UiBinder XML layout file separately, without being part of the layout hierachy.
Here's a small example:
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:Label ui:field="testlabel" text="Hallo" />
<g:HTMLPanel>
...
</g:HTMLPanel>
The compile fails since the ui:UiBinder element expects only one child element.
In Java Code i will access and bind the Label widget as usual:
#UiField Label testlabel;
For example, this could be useful when you define a Grid or FlexTable - i want to define the Labels for the table header within the XML layout file, not programmatically within the code.
Many thanks in advance
Sorry, no can do, UiBinder just doesn't support this sort of syntax. Think about it - where would this Widget go? Should it be added to the DOM tree? It also makes it hard for the compiler to tell if this code should be pruned as unused.
You'll have to wait for the GWT team to create custom tags for Grid (like they did with, for example, DockLayoutPanel). I wouldn't expect such functionality for the FlexTable though, since it's meant by design for dynamic content, meaning adding it programmatically anyway.
Understanding the UiBinder Dev Guide is the key to figuring out how to structure your UiBinder templates cleanly.
So, if all you want to do is create a widget and not have it initially in the DOM, then don't mention it at all in the UiBinder template. Instead, in the Java file that goes with your UiBinder template, create it and add it to a panel that's defined in your template.
For instance, put this in your template:
<g:HTMLPanel ui:field='container'>
...
And put this in your Java file:
#UiField HTMLPanel container;
public MyWidget() {
initWidget(uiBinder.createAndBindUi(this));
Label testLabel = new Label("hallo");
// Do whatever you want to testLabel
container.add(testLabel);
}
I am not certain if you and have the same unusual motivation to place more than two root widgets under the uibinder tag. Anyway, this is how I do it.
Since uibinder tag allows only one root widget, I place an HTML ui tag as the root widget, and then pile up my multiple pseudo-root widgets within that tag.
In the following example, notice that the actual root widget does not have ui:field name, because we don't intend to use it. As far as we are concerned, the effective root widgets are "tabLayout" and "content".
File Hello.ui.xml:
<ui:UiBinder
xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTML>
<g:TabLayoutPanel ui:field="tabLayout" ... >
blah ... blah
</g:TabLayoutPanel>
<g:VerticalPanel ui:field="content">
blah .. blah
</g:VerticalPanel>
</g:HTML>
</ui:UiBinder>
Do not extend composite as your java code behind the template.
Create a class imported by your module entrypoint or use the template directly on your module.
I have various reasons why I need more than one root widget. In this example, I attach the "effective root widget" conditionally:
public class Hello
implements EntryPoint{
private static HelloUiBinder uiBinder = GWT.create(HelloUiBinder.class);
interface HelloUiBinder
extends UiBinder<Widget, Hello>{}
#UiField TabLayoutPanel tabLayout;
#UiField VerticalPanel content;
#Override public void onModuleLoad() {
uiBinder.createAndBindUi(this);
if (condition1)
RootPanel.get().add(tabLayout);
else
RootPanel.get().add(content);
blah ... blah
}
}
So, the trick is not to use the actual root widget at all.