Append custom style to a GWT CellTable (in this case all cells) - gwt

I have a case where I want to append
white-space: nowrap;
to the style of each cell in my CellTable. Currently it applies to all tables, but it would be nice to know both have to apply it for a specific CellTable, and all CellTables.

CellTables have their own CssResource. To override this style applied to all cells in a cellTable, create a new css file :
/* Incremental changes from CellTable.css */
.cellTableCell {
white-space: nowrap;
}
Then create your own CellTable.Resources interface :
public interface TableResources extends CellTable.Resources {
/**
* The styles applied to the table.
*/
interface TableStyle extends CellTable.Style {
}
#Override
#Source({ CellTable.Style.DEFAULT_CSS, "MyOwnCellTableStyleSheet.css" })
TableStyle cellTableStyle();
}
Finally, when creating your cellTable, use the constructor that lets you specify which Resources to use
CellTable<Object> myCellTable = new CellTable<Object>(15, GWT.create(TableResources.class));
For a working example, look at the Expenses sample provided in the GWT SDK.

Or you could do this the easy way:
CellTable<YourObj> yourTable = new CellTable<YourObj>();
yourTable.getElement().getStyle().setWhiteSpace(WhiteSpace.NOWRAP);
No css files, no weird boilerplate code.

Related

How to set CSS Resource for DataGrid in UIBinder?

I have two questions.
Question #1. this question (post title) comes directly from the last comment from #Cataclysm on the first answer from here:
dataGrid = new DataGrid<T>(pageSize, resource), how to set CSS
Resource for UIBinder ?
I am attempting to style a DataGrid defined in a UIBinder:
<g:south size="400">
<c:DataGrid ui:field="documentDataTable" />
</g:south>
With this ClientBundle interface code:
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.cellview.client.DataGrid.Resources;
import com.google.gwt.user.cellview.client.DataGrid.Style;
/**
* Resources = "DataGrid.Resources"
* Style = "DataGrid.Style"
*
* http://federico.defaveri.org/?p=157
* https://code.google.com/p/google-web-toolkit/issues/detail?id=6144#c3
* https://stackoverflow.com/questions/7394151/datagrid-celltable-styling-frustration-overriding-row-styles/7395175#comment26605442_7395175
*/
public interface CustomDataGridResource extends Resources {
#Source({Style.DEFAULT_CSS, "css/CDD_DataGridStyle.css"})
CustomStyle dataGridStyle();
interface CustomStyle extends Style {
String dataGridHeader();
}
}
And CDD_DataGridStyle.css:
.dataGridHeader {
background-color: purple;
}
Using these references:
DataGrid / CellTable styling frustration -- overriding row styles
http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/cellview/client/DataGrid.html
http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/cellview/client/DataGrid.Style.html
http://crazygui.wordpress.com/2011/11/01/how-to-skin-a-gwt-celltable/
https://code.google.com/p/google-web-toolkit/issues/detail?id=6144#c3
From what I have understood from the answer to Reference 1, this resource style sheet is not "injected" like an ordinary client bundle, but rather should be passed in as a resource to a programmatically-instantiated data grid:
"To construct your newly-styled datagrid all you need to do is:
DataGridResource resource = GWT.create(DataGridResource.class);
dataGrid = new DataGrid<T>(pageSize, resource)"
Oddly, although I have a reference to the DataGrid #UIField, there does not appear to be any method in the DataGrid.java API documentation to "set" the resource (Hence the question as a repost of the last comment on this question about a DataGrid already defined in UIBinder -- DataGrid / CellTable styling frustration -- overriding row styles).
Question #2: What is the difference between DataGrid vs. CellTable, and which is the correct implementation syntax?
Why does the Google GWT API documentation for DataGrid.java (Reference 2) only detail a CellTable instantiation programmatically? I understand that DataGrid.java extends AbstractCellTable.java but why not use any of the seven DataGrid constructors in the API Example code?
To make matters more confusing, References 4 and 5 suggest that my client bundle interface should be extending CellTable.Resources, while Reference 1 suggests extending DataGrid.Resources (see also this link: http://federico.defaveri.org/?p=157).
I tried adapting the the "After" code example from the last post (#13) from Reference 5 but the nested interfaces threw an error:
public interface NxoCellTableResources extends CellTable.Resources {
public interface NormalStyle extends CellTable.Style {}
#Source({ CellTable.Style.DEFAULT_CSS, "NxoCellTable.css" })
public NormalStyle cellTableStyle();
}
public interface NxoCellTableThinResources extends CellTable.Resources {
public interface ThinStyle extends CellTable.Style {}
#Source({ CellTable.Style.DEFAULT_CSS, "NxoCellTable.css", "NxoCellTableThin.css" })
public ThinStyle cellTableStyle();
}
In summary, I am looking for the simplest way to style all elements in a DataGrid defined in a UIBinder with a clear explanation of which Resource syntax to use (DataGrid vs. CellTable). I am open to removing the reference from UIBinder and inserting programmatically into the view if necessary, thanks in advance!
Question 1:
Everything you said, is correct.
Make sure you pass provided=true to your DataGrid's UiField:
#UiField(provided = true)
DataGrid<MyDTO> dataGrid;
Then in the constructor you would create the DataGrid like this:
public MyView() {
CustomDataGridResource resource = GWT.create(CustomDataGridResource.class);
resource.dataGridStyle().ensureInjected();
dataGrid = new DataGrid<MyDTO>(pageSize, resource)"
binder.createAndBindUi(this);
}
Make sure you call ensureInjected() on the style.
Also if you have an Inject on your constructor.
You can pass the CustomDataGridresource and GWT.create() will be automatically called:
#Inject
public MyView(CustomDataGridResource resource) {
resource.dataGridStyle().ensureInjected();
dataGrid = new DataGrid<MyDTO>(pageSize, resource)"
binder.createAndBindUi(this);
}
Question 2:
Regarding the difference between CellTable and DataGrid refer to this thread:
https://groups.google.com/forum/#!topic/google-web-toolkit/PBhu6RtP4G8
Basically if you use LayoutPanels DataGrid is a good fit as it contains fixed headers and a scrollable content area. CellTable will also work with FlowPanel and normal Panels.
GWT has this documented here.
A good example can be found here.

how to disable mouse over highlighting of rows in celltable gwt

I want to disable the mouse highlighting of rows of a celltable.
This celltable is not a selectionmodel so I dont want the rows to get highlighted while mouse over event.
We are basically extending the CellTable Resources which contain the CssStyles of the CellTable so that we can custom define our own css styles. for more css classes check this link
public interface IMyResources extends CellTable.Resources {
interface IMyStyle extends CellTable.Style {
}
#Override
#Source({ CellTable.Style.DEFAULT_CSS, "MyStyleSheet.css" })
IMyStyle cellTableStyle();
}
MyStyleSheet.css CSS :
.hoveredRow {
background-color: none; //or just remove this but keep the class declaration
}
JAVA //dont forget add the resource.
CellTable<dataType> myCellTable = new CellTable<dataType>(15, GWT.create(IMYResources.class));

GWT: Two CellList style overlapped even with different css resource

In my GWT application I have two CellLists. Each with a different style, like below:
public interface MyResources extends Resources
{
/**
* The styles used in this widget.
*/
#Override
#Source( "com/example/CellList.css" )
Style cellListStyle();
}
MyResources CELLLIST_RESOURCES = GWT.create( MyResources.class );
......
mylist=new CellList<MyProxy>( myCell, CELLLIST_RESOURCES );
Both CellLists have different css files. But when loaded I found, the style of both lists was same. This is strange, any ideas?
Just found this issue 6144, the solution is simple, just use different interface name each, i.e.
interface TableResources extends CellTable.Resources
{
#Source({"myCellTable.css"})
TableStyle cellTableStyle();
}

Using a DataGrid in a HeaderPanel

Edit
Since no one has responded to my original question I think it is worthwhile adding a description of what I am attempting to accomplish, in addition to the existing description of how I have attempted to achieve my goal:
My objective is to create a DataGrid that will resize according to any change in size of its container. This is not difficult to do, but I have an additional requirement, which is to have Panel widgets above and below the DataGrid; these two Panel widgets will contain widgets that are fixed in size (e.g., a row of buttons or text input widgets). My expectation was that a HeaderPanel would be perfect for this, but this doesn't seem to work (as can be seen in my original question, below). So ... an alternative to my original question ("why doesn't this work") is: what is the best way to implement this requirement?
My original question:
I have a DataGrid in the content area of a HeaderPanel, but the detail lines in the DataGrid are not being displayed (the DataGrid column headings are showing, however). Is there an issue with using a DataGrid in the content area of a HeaderPanel? Or is this a simple misuse of the widgets? I'm adding the HeaderPanel to the RootLayoutPanel, which should provide the necessary resize notification (I think). Here is my UiBinder code:
<ui:UiBinder
xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:c='urn:import:com.google.gwt.user.cellview.client'>
<g:HeaderPanel>
<g:SimplePanel/>
<g:ResizeLayoutPanel>
<c:DataGrid ui:field='dataGrid'/>
</g:ResizeLayoutPanel>
<g:HorizontalPanel>
<g:Button
ui:field='addRecordButton'
text='Add Record'/>
<g:Label ui:field='numberOfRecordsLabel'/>
</g:HorizontalPanel>
</g:HeaderPanel>
</ui:UiBinder>
and here is the Java code:
public class TempGWT implements EntryPoint {
#UiField
Button addRecordButton;
#UiField
DataGrid<Record> dataGrid;
#UiField
Label numberOfRecordsLabel;
private ArrayList<Record> _recordList;
interface TempGWTBinder extends UiBinder<Widget, TempGWT> {
}
private static class Record {
private String _field1;
}
#Override
public void onModuleLoad() {
_recordList = new ArrayList<Record>();
TempGWTBinder binder = GWT.create(TempGWTBinder.class);
Widget widget = binder.createAndBindUi(this);
Column<Record, String> field1Column = new Column<Record, String>(new TextInputCell()) {
#Override
public String getValue(final Record record) {
return record._field1;
}
};
dataGrid.addColumn(field1Column, "Field 1");
RootLayoutPanel.get().add(widget);
}
#UiHandler("addRecordButton")
public void onAddRecordButtonClick(final ClickEvent event) {
Record record = new Record();
record._field1 = "Record " + (_recordList.size() + 1);
_recordList.add(record);
dataGrid.setRowData(_recordList);
numberOfRecordsLabel.setText("Records:" + _recordList.size());
}
}
I've attempted to trace the execution and, although I'm not certain, it looks as though the following happens when I change the size of the browser window and the "resize" request is received by the DataGrid (I've skipped some of the "unimportant" methods):
DataGrid#onResize
HeaderPanel#forceLayout
ScrollPanel#onResize
The DataGrid object contains a HeaderPanel, which contains the headings for the DataGrid and a ScrollPanel. I don't know whether this is the key to the problem, but the ScrollPanel in the DataGrid's HeaderPanel contains a DataGrid$TableWidget object, and TableWidget does not implement RequiresResize; the ScrollPanel#onResize method only sends the resize to its child if the child implements RequiresResize.
The Tables and Frames section of the GWT Developer's Guide makes it clear that I just needed to use a width/height of 100% for the DataGrid! Like so:
<c:DataGrid
ui:field='dataGrid'
width='100%'
height='100%'/>

GWT: TabLayoutPanel with custom tabs does not display correctly

I have a TabLayoutPanel where I am putting custom widgets in for the tabs to be able to display some images next to the text. I originally worked with TabPanel and using custom HTML for the tab text, but custom tab widgets allows me to modify the image on the fly as needed.
My tab widget is essentially a HorizontalPanel, a number of small images, and a line of text. The problem I'm having is that the tab doesn't want to stick to the bottom of the tab bar like normal. The tab is getting positioned at the top of the space reserved for the tab bar, and there's a gap between it and the bottom of the tab bar. I uploaded an image of the problem to http://imgur.com/fkSHd.jpg.
Is there some style that I need to apply to custom widget tabs to make them appear correctly?
In my brief experience, the newer standards mode panels (they all end in "LayoutPanel") don't get along with the older ones (the ones that just end in "Panel"). So you might consider trying a DockLayoutPanel instead of the HorizontalPanel, and it may be more cooperative.
See https://developers.google.com/web-toolkit/doc/latest/DevGuideUiPanels, particularly the section called "What won't work in Standards Mode?":
HorizontalPanel is a bit trickier. In some cases, you can simply
replace it with a DockLayoutPanel, but that requires that you specify
its childrens' widths explicitly. The most common alternative is to
use FlowPanel, and to use the float: left; CSS property on its
children. And of course, you can continue to use HorizontalPanel
itself, as long as you take the caveats above into account.
After a bit more research, I found the answer here: https://groups.google.com/d/msg/google-web-toolkit/mq7BuDaTNgk/wLqPm5MQeicJ. I had to use InlineLabel or InlineHTML widgets instead of normal Label or HTML widgets. I've tested this solution and it does exactly what I want. I pasted the code of the class below for completeness. Note two things here:
The "float" attribute cannot be set on the last element (the InlineLabel) or the incorrect drawing condition occurs again.
The code could be cleaned up a bit further by having the class extend directly from FlowPanel instead of making it a composite containing a FlowPanel.
package com.whatever;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
public class StatusTab extends Composite
{
public interface StatusImages extends ClientBundle
{
public static StatusImages instance = GWT.create(StatusImages.class);
#Source("images/status-green.png")
ImageResource green();
#Source("images/status-red.png")
ImageResource red();
}
private final ImageResource greenImage;
private final ImageResource redImage;
private final FlowPanel flowPanel;
public LinkStatusTab(String text, int numStatuses) {
greenImage = StatusImages.instance.green();
redImage = StatusImages.instance.red();
flowPanel = new FlowPanel();
initWidget(flowPanel);
for (int i = 0; i < numStatuses; i++)
{
Image statusImg = new Image(redImage);
statusImg.getElement().getStyle().setMarginRight(3, Unit.PX);
statusImg.getElement().getStyle().setFloat(Float.LEFT);
flowPanel.add(statusImg);
}
flowPanel.add(new InlineLabel(text));
}
/**
* Sets the image displayed for a specific status entry.
*/
public void setStatus(int which, boolean status)
{
Image image = (Image)flowPanel.getWidget(which);
if (status)
image.setResource(greenImage);
else
image.setResource(redImage);
}
}