How can I make Table selection follow input focus?

I have a Table with both editable Fields and plain Labels.
When I click on the Labels, the row is selected.
When I click inside an editable field, the row is not selected.

If I then have a list with only editable Fields it actually becomes difficult to select the row…

Do I need to add a Focus listener to each Field and set the Table selection from there?

Yes, I think so.

You could see the
on-demand editing example
, which actually does that selection-setting in the focus/blur listeners. Well, the behavior in the example is a bit odd, as deselecting an item is possible, but it does not close the editing… (The example is also broken - the generated column is not refreshed properly.)

That worked. Unsure how suitable it is, since it means a round-trip to the server each time the user tabs to a new field in my table row.

Discovered something interesting; addFocusListener comes from FieldEvents.FocusNotifier which AbstractTextField implements. Many other classes implement this interface, but not CheckBox. It does have the methods though…
I ended up with code like this:

if(field instanceof FieldEvents.FocusNotifier) {
    FieldEvents.FocusNotifier tf = (FieldEvents.FocusNotifier) field;
    
    tf.addFocusListener(new FieldEvents.FocusListener() {
        @Override
        public void focus(com.vaadin.event.FieldEvents.FocusEvent focusEvent) {
            // ensure this row is selected
            ArrayList<Object> selection = new ArrayList<>();
            selection.add(itemId);
            EcosTable.this.setValue(selection);
        }
    });
}
else if(field instanceof CheckBox) {
    CheckBox checkBox = (CheckBox) field;
    
    checkBox.addFocusListener(new FieldEvents.FocusListener() {
        @Override
        public void focus(com.vaadin.event.FieldEvents.FocusEvent focusEvent) {
            // ensure this row is selected
            ArrayList<Object> selection = new ArrayList<>();
            selection.add(itemId);
            EcosTable.this.setValue(selection);
        }
    });
    
}

Still not ideal though; When I click inside a checkbox I get focus, but not when I click in the large area outside the checkbox.

Oh, I just noticed that the
guys in this thread
solved the exactly same problem with a LayoutClickListener. If the entire table was wrapped inside a layout, you would have trouble knowing which item was clicked, but wrapping each cell content in a CssLayout seems to be a way. Well, unless there components are bound to data, which makes it trickier…

I suppose there are client-side solutions as well, for example to catch and propagate the mouse events in the client-side widgets, which allow more possibilities. The HTML click events are actually propagated to parent elements by default in event bubbling, and have to be explicitly stopped, but that’s probably done somewhere deep in the GWT widgets, not quite sure where.

That actually worked.

But, as you say, to get this to work I need a Layout around each Field.

Unfortunately TableFieldFactory.createField must return a Field.
I got around that by writing my own CustomField wrapper class that has a CssLayout which contains the original Field.

My wrapper class also needs to override most methods from the parent class of CustomField, and forward them to the wrapped field.

The code is not exactly pretty, but it works like a charm.