How to enable row selection on a Table's Generated Column?

Hi,

I have 2 questions re. using tables (in read-only mode). I’m using Vaadin 6.4.3.

  1. One of the columns is a boolean, which Table displays by default simply as strings ‘true’ / ‘false’. I’d like to display it as a read-only Checkbox. Is adding a generated column the best way to do that, or is there a simpler way to show the boolean as a checkbox?

My current code is as follows:

table.addGeneratedColumn(columnId, new Table.ColumnGenerator() {
   @Override
   public Component generateCell(Table source, Object itemId, Object columnId) {
      CheckBox checkBox = new CheckBox();
      checkBox.setValue(source.getItem(itemId).getItemProperty(columnId).getValue());
      checkBox.setReadOnly(true);
      checkBox.setImmediate(true);

      return checkBox;
   }
});
  1. Row selection doesn’t work when I click on any of the generated column’s cells:

Normally to select a row on the Table, I just click any cell on the required row and the row gets selected. However, I can’t do that on cells on the generated column: clicking on them doesn’t select their corresponding row. I can only select the required row by clicking the other non-generated cells of that row.

Did I do something wrong here? Is there a way to enable row selection (by clicking) on generated column cells as well?

thanks a lot, cheers.

Update: Vaadin 6.4.4 also exhibits the same problem with not being able to select a table row when clicking on a cell that belongs to a generated column.

Any ideas how I can fix that? I need to allow users to select rows even if they click on a cell that belongs to a generated column.

thanks again, regards.

I believe this has nothing to do with the fact that the column is generated, but the component you put in the column “eats” the events before the table sees them.

Maybe someone else has an idea on how to best get around this? Somehow make the component not fill the whole cell? Add some listeners to the component, or to the layout containing the table, or elsewhere (not really an ideal solutions)? Other?

Hi Henri,

Thanks for the response.

If this is the case, what event should the generated cell listen for?

I’ve tried adding a ClickListener, FocusListener and a generic Component.Listener to each generated cell (see code below), but none of them gets invoked when the cell (outside the actual tick-box) is clicked.

I did notice that if I leave the checkbox in the default readwrite mode (which I don’t want), clicking on the actual tick-box (of the checkbox) inside the cell will invoke Component.Listener and ClickListener.

In other words, with the checkbox in readonly mode, I can’t find the event that gets triggered when the cell area outside the actual tickbox is clicked.

Any suggestions?

thanks again.

public static class CheckBoxColumnGenerator implements Table.ColumnGenerator
{
   private HashMap<Object, CheckBox> generators = new HashMap();

   @Override
   public Component generateCell(Table source, Object itemId, Object columnId)
   {
      CheckBox checkBox = generators.get(itemId);
      if(checkBox == null) {
         checkBox = new CheckBox();
         checkBox.setReadOnly(true);
         checkBox.setEnabled(true);
         checkBox.setImmediate(true);

         generators.put(itemId, checkBox);
      }

      // must use setPropertyDataSource():
      // - setValue() not allowed when in readOnly mode.
      checkBox.setPropertyDataSource(source.getItem(itemId).getItemProperty(columnId));

      checkBox.addListener(new ClickListener() {
         @Override
         public void buttonClick(ClickEvent event) {
            System.out.println("Click listener invoked.");
         }
      });

      checkBox.addListener(new FocusListener() {
         @Override
         public void focus(FocusEvent event) {
            System.out.println("Focus listener invoked.");
         }
      });

      checkBox.addListener(new Component.Listener() {
         @Override
         public void componentEvent(Event event) {
            System.out.println("Component Listener invoked.");
         }
      });

      return checkBox;
   }
}

See
this post
for a solution. The solution has a minor flicker problem, see ticket
#6469
.