Showing boolean values with checkbox in a non-editable table

If you have a non-editable table, my understanding is that it is the formatPropertyValue() method that is the place where I can configure what value should be shown, given a specific property value.

This method returns a String. If I have a boolean value and want to do something else than the default string of “true” or “false”, what can I do? Is it possible to show this with a non-editable checkbox instead?

I think you can return any component you like from formatPropertyValue : so, you could return a non-editable checkbox.

You could also use a ColumnGenerator - but I think formatPropertyValue is better…

Cheers,

Charles

The formatPropertyValue() returns a String, so you can’t have it return components.

The getPropertyValue() could return components and you could otherwise override it, but there’s elsewhere a prevention of rendering a component unless either in the editable mode or the column (property) type is a component.

You can put components in a column also in non-editable table, as
described in the Book
or shown in
this example
.

Using a column generator is also a good solution.

It is possible to show Images / CheckBox in a table for boolean fields.

In the code below is assumed to be a column called “boolean-column”

It will show an imange (a check mark like sign) in non edit node. In edit mode it will show a CheckBox (as default)


    /**
     * Formats a boolean column - so true shows an image, and false shows nothing
     */
    class BooleanColumnGenerator implements Table.ColumnGenerator {
        /**
         * Generates the cell containing an open image when boolean is true
         */
        public Component generateCell(Table source, Object itemId, Object columnId) {
            Property prop = source.getItem(itemId).getItemProperty(columnId);
            if (source.isEditable()) {
                return new CheckBox(null, prop);
            } else {
                if (prop.getValue()!=null && (Boolean) prop.getValue()) {
                    return new Embedded("", new ThemeResource("../image/open.png"));
                }
                return null;
            }
        }
    }
....
     table.addGeneratedColumn("boolean-column", new BooleanColumnGenerator());

It is assumed that web resource src/main/webapp/VAADIN/themes/image/open.png exists (Maven style)

I’m sure I must be making a very basic mistake, but I can’t get the BooleanColumnGenerator to work. My class is almost identical, apart for the path to the icon which works elsewhere in my code:

public class BooleanColumnGenerator implements Table.ColumnGenerator {

	@Override
	public Object generateCell( Table source, Object itemId, Object columnId ) {
		Property prop = source.getItem( itemId ).getItemProperty( columnId );
		if ( source.isEditable() ) {
			return new CheckBox( null, prop );
		} else {
			if ( prop.getValue() != null && (Boolean) prop.getValue() ) {
				return new Embedded( "", new ThemeResource( "icons/16/ok.png" ) );
			}
			return null;
		}
	}
}

And here’s how I use it in a class that’s derived from Table:

		setEditable( true );
		
		addContainerProperty( setColumn,	 Boolean.class, null );
		addContainerProperty( nameColumn,  String.class, null );
		addContainerProperty( valueColumn, String.class, null );
		addContainerProperty( unitsColumn, String.class, null );
		
		addGeneratedColumn( setColumn, new BooleanColumnGenerator() );
		
		setVisibleColumns( new Object[] { setColumn, nameColumn, valueColumn, unitsColumn } );

Nothing appears in the table if I use this code. But if I comment out the addGeneratedColumn line, the data appears with “true” of “false” in the setColumn.

Denis

I use a generic column generator helper class to display all boolean values in my tables without bothering about setting the table itself to editable.


table.addGeneratedColumn("myNewColId", new CheckBoxColumnGenerator("myValueColId", true, null));

public class CheckBoxColumnGenerator implements ColumnGenerator {

	private String originId = "";
	private boolean output = true;
	private String capt = null;
	
	public CheckBoxColumnGenerator(String originPropId, boolean readOnly, String caption){
		originId = originPropId;
		output = readOnly;
		capt = caption;
	}
	
	public Object generateCell(Table source, Object itemId, Object columnId) {	
		Property prop = source.getItem(itemId).getItemProperty(originId);
		boolean val = (Boolean)prop.getValue();
		
		CheckBox ret = new CheckBox(capt, val);
		ret.setReadOnly(output);
		
		return ret;
	}
}

Hey Anders, Henrik and Denis,

Just had a quick question? I tried images for the boolean rows. But the problem I am facing is, that this images dont get updated when I edit them, like when I swap it from true to false, through a form, which has the setItemDataSource as this table.

How do I do immediate updates for this generated Column? Any help will be very much appreciated.

Thanks,
Harsh

Another solution is to use checkbox characters, such as ☒, :ballot_box_with_check:, and ☐, or simple tick characters ✓ or :heavy_check_mark:. Then you can use
formatPropertyValue
again:

    @Override
    protected String formatPropertyValue(Object rowId, Object colId, Property property) {
        if (property.getType() == Boolean.class) {
            if (property.getValue() == null) {
                return "";
            } else
            if ((Boolean) property.getValue()) {
                return "☒";
            } else {
                return "☐";
            }
        } else {
            return super.formatPropertyValue(rowId, colId, property);
        }
    }

This solution works for me: (with checkbox characters, such as ☒, :ballot_box_with_check:, and ☐ from previous post)

table.setConverter("column_name", new StringToBooleanConverter() {
   @Override
   protected String getTrueString() {
      return "☒";
   }
   @Override
   protected String getFalseString() {
      return "☐";
   }
});

This is a nice workaround. Just notice that not all browsers or operating systems have the font that supports the symbols in the browser. Perhaps most have, but nevertheless. Using FontIcons is perhaps a more cross-platform compatible solution and it also allows better selection of the icons.