Use ClientBundle image as background-image
Asked Answered
M

2

9

I'm trying to use an image from a ClientBundle as a background-image in a UIBInder template. I used this discussion as a guide, but was unable to get it to work.

In my Java class I have:

public static interface PriceButtonStyles extends ClientBundle
{
    String paidIcon();

    @ClientBundle.Source("paid_button_53x31.png")
    DataResource paid_buttonAsDataResource();
}

@UiField
PriceButtonStyles priceButtonStyle;

And then in the corresponding template file I reference it like:

<ui:style field="priceButtonStyle" type="com.example.client.PriceButton.PriceButtonStyles">

    @url paidIconUrl paid_buttonAsDataResource;

    .paidIcon {
        background: paidIconUrl 0 0 no-repeat;

    }
</ui:style>

Already at this point my IDE is showing the "paidIconUrl" string in red, indicating that something's not quite right:

ide shows red

And indeed, when I try to run it I get:

    ERROR: Type com.ecample.client.PriceButton.PriceButtonStyles does not extend com.google.gwt.resources.client.CssResource Element <ui:style field='priceButtonStyle' type='com.example.client.PriceButton.PriceButtonStyles'> (:7). 
ERROR: Uncaught exception escaped. com.google.gwt.event.shared.UmbrellaException: One or more exceptions caught, see full set in UmbrellaException#getCauses

Further on in the Google Groups discussion it is suggested that this might work with <ui:data> rather than <ui:style>, so I tried to make that work. But it seems like you can't include both CSS styles (e.g. my paidIcon() method) and DataResources in <ui:data> resources. I wasn't able to find much documentation on <ui:data>, so I'm really just grasping at straws with this.

Mush answered 18/3, 2011 at 15:39 Comment(0)
M
6

In addition to Images, where you want to set the src property, you have to set

<g:Image url="{res.minimize.getSafeUri.asString}" ....>

res is instantiated like this:

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui">

    <ui:with field="res"
        type="xxx.myRes"></ui:with>
....

and the client bundle looks like this:

package xxx;

import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;

public interface myRes extends ClientBundle {

    @Source("minimize.png")
    ImageResource minimize();

}

Creating the ClientBundle (with e.g. GWT.<TitleBarBundle>create(myRes.class);) wasn't necessary in my case.

Thanks for your answer Chris Boesing, but I felt like I had to share my experiences with you too.

Regards, Stefan

Mcferren answered 29/3, 2012 at 9:14 Comment(0)
R
4

Here is how I do it. It is a little different than your approach but has worked great for me in this type of situation. Your ClientBundle would look like this:

public static interface PriceButtonStyles extends ClientBundle
{
     @Source("PriceButtonStyles.css")
     Styles priceButtonStyles();

     @Source("paid_button_53x31.png")
     ImageResource paidButtonPNG();

     interface Styles extends CssResource {
         String buttonBackground();
     }
}

Then you would need the PriceButtonStyles.css from the first @Source:

.buttonBackground {
    gwt-image:'paidButtonPNG';
    background-repeat:no-repeat;
}

Your *.ui.xml would look like this:

<ui:with field="res" type="com.ecample.client.PriceButton.PriceButtonStyles"></ui:with>
<g:Label styleName="{res.priceButtonStyles.buttonBackground}"><g:Label>

Even though your styles are in a css file it still gets minimized and obfuscated by the compiler.
Edit: Don't forget to call
GWT.<PriceButtonStyles> create(PriceButtonStyles.class).priceButtonStyles().ensureInjected(); Best place for this is your EntryPoint method

Romeliaromelle answered 18/3, 2011 at 16:26 Comment(5)
Hmm tried that, but it errors with "ERROR: Deferred binding result type 'com.example.client.PriceButton.Styles.PriceButtonStyles' should not be abstract." At the top of my EntryPoint I'm calling GWT.<PriceButton.Styles.PriceButtonStyles> create(PriceButton.Styles.PriceButtonStyles.class).ensureInjected().I have PriceButtonStyles.css in the same package as the Java code. Also, I had to rename the upper-level interface to "Styles", since it didn't like having an embedded interface with the same name.Mush
Sorry for given the two interfaces the same name. I think your error comes from the call to inject the style. You need to put the upper-level interface between < > and ( )Romeliaromelle
You should probably add an @ImageOptions(repeatStyle=RepeatStyle.Both) annotation to your ImageResource method to make sure the image isn't sprited in some browsers (namely, IE6/7)Strident
Still doesn't seem to work. The style does get applied, because if I add "border: 1px solid red;" to the .buttonBackground, I get a nice red border around the label. But the image doesn't work.Mush
Your remark about calling ensureInjected() was very helpful!! Thanks!Commune

© 2022 - 2024 — McMap. All rights reserved.