Using Columngenerator, the table cells are not updated instantly

Hello,

I have not access to create a ticket for this issue, but here is some code that enlightens my problem:


Table table = new Table();
table.addContainerProperty("quantity", Integer.class, null, "Quantity", null, null);
table.addGeneratedColumn("quantity", new ValueColumnGenerator("%d pcs"));
table.setImmediate(true);
		
for (int i = -1000; i<1000; i++) {
	Item item = table.addItem(i);
	item.getItemProperty("quantity").setValue(i);
}

mainWindow.addComponent(table);
Button b;
mainWindow.addComponent(b = new Button("click") );
b.addListener(new Button.ClickListener() {
	@Override
	public void buttonClick(ClickEvent event) {
		table.getItem(5).getItemProperty("quantity").setValue("555");
		// table.refreshCurrentPage(); // This doesn't work either
	}
});



private static class ValueColumnGenerator implements Table.ColumnGenerator {
   String format;

    public ValueColumnGenerator(String format) {
        this.format = format;
    }
    public Component generateCell(Table source, Object itemId,
                                  Object columnId) {
        Property prop = source.getItem(itemId).getItemProperty(columnId);
        if (prop.getType().equals(Integer.class)) {
            Label label = new Label(String.format(format, new Object[] { (Integer) prop.getValue() }));
            return label;
        }
        return null;
    }
}

When clicking the button, the table cell containing the visible value “5 pcs” should be replaced by “555 pcs” instantly - but nothing happens. If one scrolls the table a bit, and a page load for the table is issued, the expected value is shown. Using table.refreshCurrentPage() will not be of any help. So I guess this is a bug… Right?

If I remove the column generator, the value 5 is updated to 555 instantly as it should.

Hello,

Well - the simple answer (for me) is that No, it’s not a bug. At no point did you bind your component to the property, so it is no surprise that the component didn’t change. I would look at using a PropertyFormatter wrapped around the property in your #generateCell

However, I personally think you are probably using a sledgehammer to crack a nut : do you really want to use a column generator here? Or, rather, are you simply trying to format the text?

In which case, overriding Table#formatProperty is much, much easier. Get rid of the column generator, and try this

 final Table table = new Table() { 
 @Override
 protected String formatPropertyValue(Object rowId, Object colId, Property property) {
    if(colId.equals("quantity")) {
       return String.format("%d pcs", property.getValue());
     }
     return super.formatPropertyValue(rowId, colId, property);
   }
 };
 table.addContainerProperty("quantity", Integer.class, null, "Quantity", null, null);

One could, of course, come up with a generic way of doing this, but the above shows the intent.

Cheers,

Charles

Hi Charles!

Yes, you are right. I forgot to bind the property of the label, so the change wasn’t reflected immediately. I tested the PropertyFormatter and it worked well. The reason why I was trying to crack a nut with a sledgehammer, is that I wanted to style the labels. However, I then decided to remove the ColumnGenerator and override the formatPropertyValue method as you suggested. Instead of styling the labels, i added a CellStyleGenerator, which in fact is a much better idea. Having labels in the cells may also cause some troubles with the widths and speed. Your answers were highly appreciated!

Best regards,
Johan

Hi,

Glad to help : for general informations sakes, another advantage of overriding Table#formatPropertyValue is that your data can be sorted - if I remember correctly, this is not possible using a ColumnGenerator.

Cheers,

Charles.