GWT: Is it ok to call ensureInjected() in onModuleLoad?
What matters is that ensureInjected()
is called at least once before you display anything referencing the CssResource
, otherwise the stylesheet won't be present, and there would be no style to apply matching the class names.
So yes, it's OK to call ensureInjected()
only once inonModuleLoad
.
And you don't have to use a singleton, all instances of a given ClientBundle
will share the same resource instances (they'll be generated as singletons).
gwt using CssResource throw exception no source code is available did you forget inherit a required module
Thee might be some unused import in your project.
java.util.ResourceBundle
find it in the project and remove it from client side code.
-- EDIT --
Sample code: (All files are placed in same package)
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface LoginResources extends ClientBundle {
public interface MyCss extends CssResource {
String blackText();
String redText();
String loginButton();
String box();
String background();
}
@Source("Login.css")
MyCss style();
}
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.VerticalAlign;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
public class Login extends Composite {
private static LoginUiBinder uiBinder = GWT.create(LoginUiBinder.class);
/*
* @UiTemplate is not mandatory but allows multiple XML templates to be used for the same
* widget. Default file loaded will be <class-name>.ui.xml
*/
@UiTemplate("Login.ui.xml")
interface LoginUiBinder extends UiBinder<Widget, Login> {
}
@UiField(provided = true)
final LoginResources res;
public Login() {
this.res = GWT.create(LoginResources.class);
res.style().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
completionLabel1.getElement().getStyle().setVerticalAlign(VerticalAlign.BOTTOM);
}
@UiField
TextBox loginBox;
@UiField
TextBox passwordBox;
@UiField
Label completionLabel1;
@UiField
Label completionLabel2;
}
Login.css
.blackText {
font-family: Arial, Sans-serif;
color: #000000;
font-size: 11px;
text-align: right;
}
.redText {
font-family: Arial, Sans-serif;
color: #ff0000;
font-size: 11px;
text-align: left;
}
.loginButton {
border: 1px solid #3399DD;
color: #FFFFFF;
background: #555555;
font-size: 11px;
font-weight: bold;
margin: 0 5px 0 0;
padding: 4px 10px 5px;
text-shadow: 0 -1px 0 #3399DD;
}
.box {
border: 1px solid #AACCEE;
display: block;
font-size: 12px;
margin: 0 0 5px;
padding: 3px;
width: 203px;
}
.background {
background-color: #999999;
border: 1px none transparent;
color: #000000;
font-size: 11px;
margin-left: -8px;
margin-top: 5px;
padding: 6px;
}
Login.ui.xml
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:gwt='urn:import:com.google.gwt.user.client.ui' xmlns:res='urn:with:com.gwt.test.client.LoginResources'
xmlns:p='urn:import:com.gwt.test.client'>
<ui:with type="com.gwt.test.client.LoginResources" field="res">
</ui:with>
<gwt:HTMLPanel>
<div align="center">
<gwt:VerticalPanel res:styleName="{res.style.background}">
<gwt:Label text="Login" res:styleName="{res.style.blackText}" />
<gwt:TextBox ui:field="loginBox" res:styleName="{res.style.box}" />
<gwt:Label text="Password" res:styleName="{res.style.blackText}" />
<gwt:PasswordTextBox ui:field="passwordBox"
res:styleName="{res.style.box}" />
<gwt:HorizontalPanel verticalAlignment="middle">
<gwt:Button ui:field="buttonSubmit" text="Submit"
res:styleName="{res.style.loginButton}" />
<gwt:CheckBox ui:field="myCheckBox" />
<gwt:Label ui:field="myLabel" text="Remember me"
res:styleName="{res.style.blackText}" />
</gwt:HorizontalPanel>
<gwt:Label ui:field="completionLabel1" res:styleName="{res.style.blackText}" />
<gwt:Label ui:field="completionLabel2" res:styleName="{res.style.blackText}" />
</gwt:VerticalPanel>
</div>
</gwt:HTMLPanel>
</ui:UiBinder>
Snapshot
How to remove the injected CSS Resource in GWT?
You can inject your css bundle using directly StyleInjector
utility class, instead of the ensureInjected()
method
Then you will have a reference of the injected element which you can remove when you want.
// Equivalent to MyClass.INSTANCE.ensureInjected()
StyleElement e = StyleInjector.injectStylesheet(MyClass.INSTANCE.css().getText());
// Remove the injected css element
e.removeFromParent();
GWT Initialize ClientBundle With Multiple CssResources
That code looks exactly right, but might not function the way you expect - instead of each ensureInjected()
causing a new <style>
block to be created, instead they just enqueue the styles that they need to be made available, and at the end of the current event loop a single <style>
is added with all of the various collected styles. This limits the number of times that the document potentially needs to be restyled, and also helps reduce the number of style tags (old IE had a bug where there was a max number of tags possible).
To confirm this, check the entire contents of the <style>
tag, you should see that both css files are appended there, one after the other.
GWT ClientBundle: Using DataResource in CssResource file
@url
defines a variable (in your case named test1
). The value of background
in your code is a string literal, not a reference to the variable: remove the quotes.
@url test1 image;
.myImage {
background: test1;
width: 50px;
}
See https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#References_to_Data_Resources
GWT shared CSS styles doesn't work
You probably forgot to call ensureInjected()
on a Resources.Style
instance.
This is done automatically for a <ui:style>
(because you don't code the ClientBundle
and CssResource
interfaces, they are generated for you by UiBinder), but not for any other CssResource
.
You can use @UiField Resources res
though, that will be injected with the value of the <ui:with field="res">
, and thus call res.style().ensureInjected()
just after the call to createAndBindUi
.
IMO, you'd however better inject a Resources
instance into your view and use @UiField(provided=true)
, and thus either make sure ensureInjected()
is called before the instance is injected into your view, or choose to call ensureInjected()
in each of your views. As in https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder#Share_resource_instances
How to apply proper CSS with GWT components?
why not try simply with menuBar.setStyleName("menuBar"); I'm sure this will work.
How to override GWT obfuscated style for DataGrid header
Just like with any ClientBundle
and CssResource
: create an interface that extends Datagrid.Resources
and overrides the dataGridStyle
method with a @Source
annotation pointing to your own CSS file (or possibly to both the original file and your own file, so they'll be combined together).
Doing it that way will override the style for all DataGrid
s in your app though (it actually depends on which CssResource
instance gets ensureInjected()
first: the one from the original DataGrid.Resources
or the one from your sub-interface): because you use the same return type (DataGrid.Style
), the obfuscated class names will be the same.
If you want to change the style on a case-by-case basis then, in addition, declare an interface that extends DataGrid.Style
and use that as the return type to your dataGridStyle
override: because the obfuscated class name is based on both the interface fully-qualified name and the method name, your DataGrid.Style
sub-interface will generate different obfuscated class names than the original DataGrid.Style
interface.
Then of course, GWT.create()
your DataGrid.Resources
sub-interface and pass it as an argument to the DataGrid
constructor.
See also http://code.google.com/p/google-web-toolkit/issues/detail?id=6144
Related Topics
Creating a Fuzzy Border in CSS 3
How to Get My Page Headers to Resize Using Responsive Layout
Webpack - Require('Node_Modules/Leaflet/Leaflet.CSS')
Wordpress Admin Menu Display Glitch in Google Chrome
Whats The CSS to Make Something Go to The Next Line in The Page
Positioning a Mapbox/Leaflet Map Inside a Container Div
Styling: :-Webkit-Scrollbar-Track Not Working
Body { Font-Size: 100.01%; } Vs Body { Font-Size: 100%; }
Keep Bootstrap Columns in Same Row When Changing Size
2-Column CSS Responsive Layout with a Responsive Image
Background Center with Chrome (Bug)
Add Delayed Time in CSS3 Animation
Overriding Styles in Semantic UI React
Customize CSS of Google Docs Viewer
CSS for a Sidebar Menu That Folds in and Out