Since my application got larger, I decided that each "module" of my application, will have its own resource file, style file and GSS file. Also styling of for example buttons will be in a different, global GSS file as it is more of an application style, used through the application.
This is not a problem, but when I wanted to do something like this:
.buttonGroup>.button.active{ background-color: red}
in one of the modules, it does not match anything.
Since the button style(buttonGroup, button, active) and behavior (add "active" class on click) is specified in different (global) GSS file, I am not able to change the style of the "active" class.
Here is a simplified example:
public interface AppResources extends ClientBundle {
public static AppResources INSTANCE = GWT.create(AppResources.class);
#Source({"style.gss"})
AppStyle appStyle();
}
Style file:
public interface AppStyle extends CssResource {
String buttonGroup();
String button();
String active();
}
Module:
public interface ModuleResources extends AppResources{
public static ModuleResources INSTANCE = GWT.create(ModuleResources.class);
#Source({"style.gss","module.gss"})
ModuleStyle moduleStyle();
}
Style file:
public interface ModuleStyle extends AppStyle {
}
In GSS files I tried to use #provide and #require (it would not compile without it as it would have missing identifiers or classes).
It then compiles fine, but the buttonGroup, button and even the active class is treated as it belongs to the AppStyle, therefore style.gss styles are used and the rule:
.buttonGroup>.button.active{ background-color: red}
in module.gss is not matching anything as it is probably looking for .hash-ModuleStyle-buttonGroup, .hash-ModuleStyle-button and .hash-ModuleStyle-active classes, whereas the actual styles on the button are .hash-AppStyle-buttonGroup etc.
In the end I solved it by using #external on the classes I wanted to use in different GSS stylesheets.
By using #external all the classes from widgets, which had their own stylesheets, keep their class names unobfuscated, so that they can be overridden in any module stylesheet.
I didn't want to do it before, but that was the only solution that I could think off.
This is actually exactly what #Import is meant to solve!
Related
it's very difficult to find a complete step-by-step guidelines of How to properly use CSS in GWTP on internet.
I am using eclipse & GWTP to build my app & I want to set some simple Css styles for my widgets (button, textbox...).
Ok, here is what I got: a TestPresenter.java, TestView.java & TestView.ui.xml
-In TestView.ui.xml:
<ui:UiBinder .....>
<ui:style src='myStyle.css' />
<g:HTMLPanel>
<g:Button text="My But 1" addStyleNames="{style.myBut}" ui:field="myBut1"/>
<g:Button text="My But 2" ui:field="myBut2"/>
</g:HTMLPanel>
</ui:UiBinder>
myStyle.css is in the same folder that houses TestPresenter.java, TestView.java & TestView.ui.xml
-TestPresenter.java (has 2 buttons- myBut 1 & myBut 2): I added "myBut" for myBut2
getView().getMyBut2().addStyleName("myBut");
After running, it shows 2 buttons, the first myBut1 got the correct CSS but myBut2 still show the default Css. I changed to getView().getMyBut2().setStyleName("myBut"); but it still didn't work.
So i think probably i'm missing some classes here & that is why eClipse couldn't recognize "myBut" CSS so that it can apply for myBut2.
So, How to let myBut2 show the correct Css in eClipse?
the reason is that adding a CSS style sheet as a source to the uibinder causes the gwt compiler to generate a CssResource class for it, and therefore obfuscating the CSS class name to SHA1 hash.
That mean that in the final compiled version, instead of ".myBut" you actually end up with something like ".XYZXYZ".
this is purely GWT uibinder behavior that you can read about here
Specifically for GWTP, the textbook solution is:
in TestView.java add:
public TestView extends SomeGWTPViewClass implements TestPresenter.MyView
{
public interface MyStyle extends CssResource
{
String myBut();
}
#UiField MyStyle style;
#Override
MyStyle getStyle()
{
return style;
}
//rest of code here......
.....
...
}
in TestView.ui.xml change ui:style to:
<ui:style src='myStyle.css' type="fully.qualified.package.name.TestView.MyStyle"/>
in TestPresenter.MyView interface add:
MyStyle getStyle();
now you can access the myBut style in TestPresenter by:
getView().getMyBut2().addStyleName(getView().getStyle().myBut());
I'm trying to figure out how to override the dataGridHeader style defined in DataGrid.css! GWT core. The GWT style name is obfuscated with adler32 so I can't simply use .dataGridHeader in my css. In my case I wish a simple change of white-space:normal.
I've seen may articles here about injecting css but they all appear to be class level rather than a sub style used within a component like DataGrid.
How do I override a header style used within a component like DataGrid?
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 DataGrids 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
Thanks Thomas.
Just to make it easier for the readers...
Create a new Interface
public interface GwtCssDataGridResources extends DataGrid.Resources {
#Source({Style.DEFAULT_CSS, "gwtDataGrid.css"})
Style dataGrid();
}
Use a static reference
public static final GwtCssDataGridResources gwtCssDataGridResources = GWT.create(GwtCssDataGridResources.class);
static {
gwtCssDataGridResources.dataGrid().ensureInjected();
}
Finally create a new CSS file gwtDataGrid.css. Note that if you need to override a style, you have to use !important on each definition.
.dataGridHeader {
color: #FF0000 !important;
}
.dataGridFirstColumnHeader {
-moz-border-radius-topleft: 5px;
-webkit-border-top-left-radius: 5px;
}
.dataGridLastColumnHeader {
-moz-border-radius-topright: 5px;
-webkit-border-top-right-radius: 5px;
}
That's it
I'm trying mightily to style my GWT 2.4 DataGrid, and hit roadblocks at every turn. I've added the following row styling to my DataGrid:
dataTable.setRowStyles(new RowStyles<IntegrityItem>() {
#Override
public String getStyleNames(IntegrityItem row, int rowIndex) {
if (row.getSomeValue() >= 100) {
return MyResources.INSTANCE.mystyles().alertRow();
} else {
return "";
}
}
});
The style alertRow is simply this:
.alertEntry {
font-weight: bold;
color: #00ff00;
background-color: #ff0000;
}
More information: I've made a local copy of DataGrid.css and removed ALL "background" elements from all the styles, and I've used this to construct a ClientBundle:
public interface MyDataGridResources extends DataGrid.Resources {
public static final FmeaDataGridResources INSTANCE = GWT.create(MyDataGridResources.class);
#Override
#Source({"../resources/styling/mydatagridstyles.css"})
Style dataGridStyle();
}
I've used this (MyDataGridResources.INSTANCE) in my DataGrid constructor.
When I try it out, the rows that meet the criteria contained green (#00ff00) text, but the background colour remains white or grey depending on whether it is an even row or an odd row. How is it that background-color is ignored the way it is? Where is it getting those colors in the first place?! I've removed background color information from the css file completely.
You can create a custom CSS file and provide this to the DataGrid through defining a new style resource. This is done by creating a type that extends DataGrid.Resources, which knows about your CSS file. You then pass this to the constructor of the datagrid.
To provide a fairly complete example, first create a new type for the DataGrid style. (Defining a new type like this just uniquely identifies your style within GWT).
public interface MyStyle extends DataGrid.Style {
}
Then, define an interface which overrides the dataGridStyle() method stub in DataGrid.Resources. The dataGridStyle method should return the previously defined MyStyle.
Note the two elements given to the #Source annotation - you can just override any of the class names in the default CSS (DataGrid.css) in the second file you provide ("DataGridOverride.css" here).
public interface DataGridResource extends DataGrid.Resources {
#Source({ DataGrid.Style.DEFAULT_CSS, "DataGridOverride.css" })
MyStyle dataGridStyle();
};
To construct your newly-styled datagrid all you need to do is:
DataGridResource resource = GWT.create(DataGridResource.class);
dataGrid = new DataGrid<T>(pageSize, resource)
One subtlety is as you're increasing the precedence of the overridden styles, you may need to override any other styles that require higher precedence, for example the row hover rules need to come after the row styling rules.
See http://code.google.com/p/google-web-toolkit/issues/detail?id=6144#c3 (which is not a bug!)
In short extend the DataGrid.Style (the goal is only to have a new type, you don't have to add anything to it) and have your dataGridStyle overridden method return your own subtype rather than DataGrid.Style (and it'll work because of return-type covariance)
Using GWT 2.1, I am trying to create a CSS file that contains numerous constants and common styles. I would like to use the ui:style tag to include it in the UiBinder template:
<ui:UiBinder
xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
<ui:style field="css" src="constants.css" />
</ui:UiBinder>
I can easily utilize the styles for elements:
<g:FlowPanel styleName="{css.panel}">...</g:FlowPanel>
But attempting to use the constants in another Style block fails:
<ui:Style>
.templateSpecificStyle {
background-color: {css.royalBlue};
padding: 1em;
}
</ui:Style>
Oddly I do not receive a compile error. The obfuscated CSS class is created; however, the content is empty. Is there any way to access these CSS constants within another Style block? Is it possible using the older ResourceBundle / CssResource pattern?
After re-reading https://stackoverflow.com/questions/3533211/need-app-wide-css-constants-in-gwt/4143017#4143017 I see that the constants work if you add the template specific style within the style block:
<ui:Style src="constants.css">
.templateSpecificStyle {
background-color: royalBlue;
padding: 1em;
}
</ui:Style>
This is perfect for my needs.
It may be in your best interest to define these constants in some class, then use runtime substitution to include this constant in each CSS resource you intend to use.
CSSConstants.java
package com.foo.client;
public final class CSSConstants {
public static final String ROYAL_BLUE = "#4169E1";
}
Style block in UiBinder template
<ui:style>
#eval royalBlue com.foo.client.ROYAL_BLUE
.templateSpecificStyle {
background-color: royalBlue
}
</ui:style>
Note that even the name of the technique is "runtime substitution", the GWT compiler will replace royalBlue with a string literal because the value of royalBlue can be evaluated at compile time.
For more cool stuff that you can do in CSS resources, take a look at http://code.google.com/webtoolkit/doc/latest/DevGuideClientBundle.html#CssResource
I am using a TabBar and I want to style the component in different ways. So one time this style, another time that style. I thought this will work but it didn't:
TabBar t = new TabBar();
t.addTab( "1" );
t.addTab( "2" );
t.addStyleName( MyResources.INSTANCE.css().slickTab() );
And:
public interface MyResources extends ClientBundle
{
public static final MyResources INSTANCE = GWT.create(MyResources.class);
#Source("style.css") MyCssResource css();
}
public interface MyCssResource extends CssResource
{
String slickTab();
}
In the CSS
.slickTab .gwt-TabBar .gwt-TabBarItem {
background-color: #ff0000;
font-weight: normal;
}
But the appearance don't change. What I am doing wrong?
You might be able to force this in CSS.
.slickTab .gwt-TabBar .gwt-TabBarItem {
background-color: #ff0000 !important;
font-weight: normal !important;
}
Also, since you're adding a style which is subject to the parent style. If this is the case, you might need to set 'setStylePrimaryName' instead of adding it and toggle between style changes with handlers.
Change your CSS. .slickTab .gwt-TabBar .gwt-TabBarItem will match a TabBarItem inside a TabBar inside a slickTab. However, since the TabBar is the slickTab, and is not inside it, you need to do something like this (note .gwt-TabBar.slickTab):
.gwt-TabBar.slickTab .gwt-TabBarItem {
background-color: #ff0000;
font-weight: normal;
}
The interface MyCssResource need to be inside MyResources.
Here's an exemple :
public interface Resources extends ClientBundle
{
public static final Resources INSTANCE =
GWT.create( Resources.class );
/***********************************************
* Home
***********************************************/
#Source( "./css/home.css" )
public HomeCss getHomeCss();
public interface HomeCss extends CssResource
{
String loginBtn();
}
/***********************************************
* Another Page
***********************************************/
#Source( "./css/AnotherPage.css" )
public AnotherPage getAnotherPageCss();
public interface AnotherPage extends CssResource
{
String title();
}
}
This is the way I use all kind of Resource and it work really well.
Whenever you need to use it many time in the same method or function, you can do this :
HomeCss homeStyle = Resource.INSTANCE.getHomeCss();
yourPanel.setStyleName( homeStyle.yourPanel() );
Don't hesitate to ask if there's anything you didn't understand.
.slickTab .gwt-TabBar .gwt-TabBarItem is going to match something with class gwt-TabBarItem inside something with class gwt-TabBar inside something with class slickTab. I think you just want .slickTab .gwt-TabBarItem for the CSS selector.
I highly recommend using FireBug to inspect the HTML structure generated by GWT and how your CSS selectors are applied to it.
The line:
t.addStyleName( MyResources.INSTANCE.css().slickTab() );
Modifies the class element attribute. And INSTANCE.css().slickTab() does not do what you think. These methods without annotations bring back to java the #def's in the css. To make what you want add to MyCssResource:
#ClassName("slickTab")
String slickTab();
So, when GWT garbles the css upside down that method will return the corect class, ej "awEs". These GWT guys are obsessive about squeezing stuff :)
And remember, firebug & chrome-inspector are your friends.