Grid with inline editing of Beans

I’m trying to construct a Grid with a custom IndexedContainer and inline editing of some of the fields of the container. My container contains a String column followed my multiple User columns. I’d like the user to be able to input the username of a User which is then queried from the database (using my custom UserDAO) and if valid the change should be comitted to the container.

So far I’ve got the Grid to display my data but I’m stuck with editing. I tried the following:

dutyPlanContainer = new DutyPlanContainer();
dutyGrid = new Grid(dutyPlanContainer.getContainer());
dutyGrid.setEditorEnabled(true);
TextField field = new TextField();
field.setConverter(new UserConverter());
for (int i = 1; i < dutyGrid.getColumns().size(); i++) {
  dutyGrid.getColumns().get(i).setConverter(new MyConverter());
  dutyGrid.getColumns().get(i).setEditorField(field);
}
dutyGrid.setFrozenColumnCount(1);

My UserConverter invokes the UserDAO in the convertToModel method and on invalid users returns null (else a User object is returned). Using the setup as described above, upon double clicking a cell, the editor opens in the header of the grid, doesn’t show any “Save”, “Cancel” links and only the first and the third column can be typed into (the second column being just blank and the rest still showing the header).
19052.png

One huge issue: you are setting the same TextField object as the editor of every column. That is not allowed; they have to be separate instances.

The editor indeed seems to have some serious problem. Maybe it’s because of the above mentioned problem, but could be something else as well.

I hope your converters don’t have any problems there, as you have two different converter classes there. At least if you use TextFields for the column editors, both the column and the editor converters should probably be a Converter<String,User>. Note that you do not need to create a different instance of the converter for every column or editor, as they are anyhow required to be stateless, so any party needing such conversion service can use the same one.

PS. You could consider using ComboBox instead of TextField for the purpose of selecting a user from a database.

Thank you very much for your input! Indeed the problem was that I shared the TextEditor among all columns which is of course a bad idea.

I also like your idea about the ComboBox, however I can’t get it to work exactly the way I’d like to to. First of all, the ComboBox allows me to edit the value, but upon opening the editor, all ComboBoxes are empty with no value set (instead the expected value found in the editor). I think this might be related to some converter issue. As you’ve pointed out my converter for the Grid is a Converter<String, User>, I don’t have converter for the ComboBox - do I need one?

List<User> users = userDAO.getUsers(); for (int i = 1; i < dutyGrid.getColumns().size(); i++) { ComboBox field = new ComboBox(); field.setContainerDataSource(new BeanItemContainer<>(User.class, users)); field.setFilteringMode(FilteringMode.CONTAINS); field.setItemCaptionMode(AbstractSelect.ItemCaptionMode.PROPERTY); field.setItemCaptionPropertyId("username"); field.setNullSelectionAllowed(false); field.setNewItemsAllowed(false); dutyGrid.getColumns().get(i).setEditorField(field); } Also I do not share the Container with the grid / between the ComboBoxes, good idea?

The other issue I have (with both the Version using TextFields as well as the version using ComboBoxes), is that the Grid doesn’t seem to be very keyboard friendly. I didn’t find a way to edit a field and especially SAVE my changes using the keyboard. Any suggestions on how to implement a shortcut for Ctrl+S to save changes or something like that?

Indeed Grid isn’t very keyboard-friendly, there’s at least some tickets about that, such as saving changes with keyboard.

You can probably use Vaadin’s keyboard shortcut handling features to implement some keyboard functionality for Grid. I don’t know of an example for Grid, but for the old Table there’s at least
this example
, which should demonstrate what sort of trickery you can do.

You should be able to bind ComboBox in your case. Just remember that its value is the selected item ID, not the item. (Although in some containers like BeanItemContainer or JPAContainer the bean/entity reference is used as the item ID…)