воскресенье, 28 сентября 2008 г.

Adding custom styles to odd/even rows in a GWT table

For the sake of better UI we decided to implement a table like gmail one that has differnt colors for even/odd rows. This seems to be quite a simple task, but I had to try several approaches before I managed to implement it.

1. Use custom RowFormatter 
RowFormatter interface defines a getElement method which is supposed to be called for every row. I believed that if you override it you can attach special style to a row object based on it's number.
Wrong guess =)
The specific table implementation - FixedWidthGrid - I was using from the gwt incubator project is using some custom/native logic inside prepareCell method so it doesn't call the getElement method =(

2. Directly override prepareCell method - doesn't seem correct, cuz would be called much more often then you need it

3. Finally I got the idea that I'm not able to find any OO way of introducing this functionality and went with a brute force approach: implement a method that applies some special formatting to all the rows and call it every time the table content is updated. 

Now I faced a new problem: there is no explicit "onContentUpdate" callback method I could use.
The only way my application now allows the content to be updated is by sorting it, so I implemented an appropriate callback. Here is the final source code packed into a class:
    public static class StripedTable extends FixedWidthGrid {
private static final String EVEN_STYLE = "even_row";
private static final String ODD_STYLE = "odd_row";

public StripedTable() {
super();
addSortableColumnsListener(new SortableColumnsListener() {
public void onColumnSorted(TableModel.ColumnSortList sortList) {
applyStripes();
}
});
}

public StripedTable(int rows, int columns) {
this();
resize(rows, columns);
}

private void applyStripes() {
for (int i = 0; i < getRowCount(); i++) {
this.getRowFormatter().setStyleName(i, getRowStyle(i));
}
}

private static String getRowStyle(int row) {
return row % 2 == 0 ? EVEN_STYLE : ODD_STYLE;
}
}

1 комментарий:

Stanislav комментирует...

Well, technically, this should be addressed by CSS as this link suggests. The only problem is that among the browsers I have (IE 7, Firefox 3.0.3, Chrome 0.2) only Chrome renders it correctly, which is kinda sad. :(