What Ecko proposes, actually sets the non-standard default, but all rows are still of the same height. No setCellStyleGenerator is needed for that, neither any other logic in Grid, except
grid.addStyleName()
(which is preferred over
grid.setSTyleName()
to avoid accidental overriding). CSS rule is sufficient.
What I meant was to be able to set
different height for particular rows
(eg. based on data in items).
The solution I used:
Imagine you have in your items special property, telling you what the row height should be. Let’s name it
extraHeight
. Let’s assume, all heights will be multiplication of standard height (eg. if default is 20px, we want to have rows of 20, 40, 60, say - up to 200px height). Then:
setRowStyleGenerator(rowReference -> {
int extraHeight = (Integer) rowReference.getItem().getItemProperty("specialHeight").getValue() + 1;
int shift = calculateRowShift(container.indexOfId(rowReference.getItemId()));
String style = "";
if (extraHeight > 1) style += "v-special-height-row-" + extraHeight + " ";
if (shift > 0) style += "v-special-positioned-row-" + shift;
return style.equals("") ? null : style.trim();
});
Let’s explain this:
int shift = calculateRowShift(container.indexOfId(rowReference.getItemId()));
extraHeight
says what extra height (over standard height) a row gets. In other words, if default row height is 20px and we want to have a row for this particular Item of 60px heright, this property should be set to 2 (which value we’ll use later in CSS, setting actual height to 20px +
2
x 20px).
The main problem, however, is that even if you set a row to anything heigher than default 20px, the subsequent rows
will not move down automatically
. The Grid bases on absolute positioning. In effect - you’ll get rows overlapped. That’s what the
calculateRowShift
is for. The implementaion could be like that:
private int calculateRowShift(int index) {
int sum = 0;
for (int i = 0; i < index; i++) {
sum += (Integer) container.getItem(container.getIdByIndex(i)).getItemProperty("specialHeight").getValue();
}
return sum;
}
It’s just iteration over preceeding rows, getting their (eventual) extra height and calculating the overall value this particular row should be lowered. What this method returns is - again - number of extra 20px “pieces” we should lower the row by.
As you can see, those two calculated variables (
extraHeight
and
shift
) are used to set the style name in the RowStyleGenerator. Some rows will be set for instance something like that:
v-special-height-row-2 v-special-positioned-row-20
This means the row will have the height of 60px and will be located 400px lower than it would, if all rows had the same height. Then CSS rules are needed. Lets assume the default (miimum) height is 20px and the maximum could be 200px (that means
extraHeight
should not exceed the value of
9
).
Here we come to the main disadvantage of this workaround.
Let’s say our container brings us 1000 records (1000 rows in the Grid). So, in extreme cases the last row can be moved down by 0 x 20px (no change) or by 9 x 1000 x 20px (all subsequent rows have the maximum height). Thus, we’ll have to prepare nearly 9000 selectors for rows’ proper positioning:
v-special-positioned-row-0
v-special-positioned-row-1
...
v-special-positioned-row-9000
Of course this does not need to be done manually. We’ll compile .scss file, which will include the mixim:
@mixin my-rows {
$baseHeight: 20px;
@for $i from 2 through 10 {
.mygrid .v-grid-row.v-special-height-row-#{$i} .v-grid-cell {
height: $baseHeight * $i !important;
}
}
@for $i from 1 through 8991 {
.mygrid .v-grid-row.v-special-positioned-row-#{$i} {
margin-top: $baseHeight * $i;
}
}
}
And finally in our own main mixim:
@include my-rows;
Such a huge number of selectors will make generated css files quite heavy, but this was not a big issue in my case. What may cause problems, however, is Internet Explorer 9, which accepts the limited number of selectors in one file. In such a case I’d recommend using a specialized tool (such as
blessed
) for splitting the
styles.css
file into parts.