# Editing NatTable supports the following editing features: 1. Inline cell editing via a text box, combobox or a checkbox 2. Multiple values can be edited simultaneously via a popup on pressing F2 3. Editing updates the underlying list data structure There is no special layer needed to enable editing in NatTable. Everything is done via configuration. The default cell editing configuration is provided by the `DefaultEditConfiguration` that is used by the `DefaultGridLayerConfiguration`. This default configuration tells the NatTable to be not editable and sets the `TextCellEditor` as default editor in case editing is turned on for specific cells. It also adds the validation error style to render the content of a cell red on validation errors. To enable editing on user interactions, several bindings need to be configured. The default bindings are configured in the `DefaultEditBindings` configuration, which is also part of the `DefaultGridLayerConfiguration`. The `EditableGridExample` and `EditErrorHandlingExample` are the best places to look at. ## Making cells editable Editing is turned _off_ by default. To enable editing an `IEditableRule` has to be registered. Usually you will register an `IEditableRule` against a cell label if you only want to enable editing for specific conditions like shown in the code below: ```java configRegistry.registerConfigAttribute( EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.ALWAYS_EDITABLE, DisplayMode.EDIT, "myCellLabel"); ``` The above snippet sets cells with label _myCellLabel_ to be always editable You can also create your own `IEditableRule` if you need to decide whether a cell should be editable or not. Just ensure that `IEditableRule.isEditable()` returns true if your cell should be editable. Creating your own `IEditableRule` is useful if you want to register an `IEditableRule` globally (instead of only for a specific cell label) that reacts on a global flag (like enable/disable editing in the UI). ## Cell editor This is the widget which gets activated when a cell is put into edit mode. A cell editor needs to implement the ICellEditor interface. The following editors are provided out of the box: * `TextCellEditor` * `CheckBoxCellEditor` * `ComboBoxCellEditor` * `PasswordCellEditor` (as a specialization of `TextCellEditor`) Note that there is only one instance of a cell editor active at any time. The editor must be registered against the cell label as follows: ```java configRegistry.registerConfigAttribute( EditConfigAttributes.CELL\_EDITOR, new CheckBoxCellEditor(), DisplayMode.EDIT, "myCheckboxLabel"); ``` The above code configures the usage of a `CheckBoxCellEditor` for cells with label _myCheckboxLabel_ While `TextCellEditor` and `CheckBoxCellEditor` can be created without additional information, the `ComboBoxCellEditor` needs the list of values contained within the combobox. As editing and rendering in different display modes are separated tasks you should check which cell painter is used for your editable cell. There are predefined cell painters for the existing cell editors in NatTable. * `TextCellEditor` - `TextPainter` * `CheckBoxCellEditor` - `CheckBoxPainter` * `ComboBoxCellEditor` - `ComboBoxPainter` * `PasswordCellEditor` - `PasswordTextPainter` As `TextCellEditor` and `TextPainter` are configured by default, you only have to check the cell painter for `CheckBoxCellEditor` and `ComboBoxCellEditor` if this is intended. ```java //register a checkbox editor for DisplayMode.EDIT configRegistry.registerConfigAttribute( EditConfigAttributes.CELL_EDITOR, new CheckBoxCellEditor(), DisplayMode.EDIT, "myCheckboxLabel"); //register the checkbox painter DisplayMode.NORMAL configRegistry.registerConfigAttribute( CellConfigAttributes.CELL_PAINTER, new CheckBoxPainter(), DisplayMode.NORMAL, "myCheckboxLabel"); //register a combobox editor for DisplayMode.EDIT configRegistry.registerConfigAttribute( EditConfigAttributes.CELL_EDITOR, new ComboBoxCellEditor(Arrays.asList(new String[] {"Value1", "Value2"} )), DisplayMode.EDIT, "myComboBoxLabel"); //register the combobox painter for DisplayMode.NORMAL configRegistry.registerConfigAttribute( EditConfigAttributes.CELL_PAINTER, new ComboBoxPainter(), DisplayMode.EDIT, "myComboBoxLabel"); ``` ## Data conversion NatTable renders every information that should be showed within a cell as Strings. To support other data types, conversion is needed. This is done by registering a `IDisplayConverter` against a cell label. ```java configRegistry.registerConfigAttribute( CellConfigAttributes.DISPLAY_CONVERTER, new DefaultBooleanDisplayConverter(), "myCheckboxLabel"); ``` The above snippet configures the `DefaultBooleanDisplayConverter` for cells with label _myCheckboxLabel_ There are several default converter shipped with the NatTable: * `DefaultDisplayConverter` * `DefaultCharacterDisplayConverter` * `DefaultBooleanDisplayConverter` * `DefaultByteDisplayConverter` * `DefaultShortDisplayConverter` * `DefaultIntegerDisplayConverter` * `DefaultLongDisplayConverter` * `DefaultFloatDisplayConverter` * `DefaultDoubleDisplayConverter` * `DefaultBigIntegerDisplayConverter` * `DefaultBigDecimalDisplayConverter` * `DefaultDateDisplayConverter` * `PercentageDisplayConverter` Note that the provided default converter are simple default implementations. If you need a more specific conversion, e.g. convert double values via `NumberFormat`, you'll have to create your own. Feel free to contribute any generic converter that fits into the NatTable. To create your own `IDisplayConverter` you should choose one of the existing abstract implementations dependent on your requirements: * `DisplayConverter` extend this class to support simple value conversion. * `ContextualDisplayConverter` extend this class to support value conversion dependent on additional context information. If you want to use specialized conversion failure messages, you need to throw a `ConversionFailedException` that will be evaluated by the configured error handling strategy (see below). ## Data validation You can configure data validation rules for the editable cells of the NatTable instance. Model updates will only be applied to the underlying list if if they pass the validation check. To add data validation to the NatTable you have to register a `IDataValidator` against a cell label. ```java configRegistry.registerConfigAttribute( EditConfigAttributes.DATA_VALIDATOR, getSecurtityIdValidator(), DisplayMode.EDIT, "myCellLabel"); ``` The above snippets shows how to configure using the data validator returned by `getSecurtityIdValidator()` on commiting values for cells with label _myCellLabel_ To create your own `IDataValidator` you should choose one of the existing abstract implementations dependent on your requirements: * `DataValidator` extend this class to support simple data validation. * `ContextualDataValidator` extend this class to support data validation dependent on additional context information. If you want to use specialized validation failure messages, you need to throw a `ValidationFailedException` that will be evaluated by the configured error handling strategy (see below). ## Error handling Conversion and validation errors will always result in not updating the values of the underlying list. How these errors are handled within the UI can be configured in NatTable. Currently the following error handling strategies are supported: * `LoggingErrorHandling` Will only write a log entry with the conversion/validation error message. Default if no other error handling is registered. * `DiscardValueErrorHandling` Will only close the open editor which discards the entered value without updating the values of the underlying list. * `DialogErrorHandling` Will show a dialog with the conversion/validation error message and the option to discard or change the entered value. Discard will close the editor without updating the values of the underlying list, Change will leave the editor open to allow corrections. * `RenderErrorHandling` Used to visualize errors on entering them into a `TextCellEditor`. It is set by default to render entered values with a red font color for handling conversion and validation errors. It is also possible to wrap those handlers, for example to open a dialog and write a log entry the same time. The following code snippet from the `EditErrorHandlingExample` shows how to add `DialogErrorHandling` for conversion and validation errors. ```java configRegistry.registerConfigAttribute( EditConfigAttributes.CONVERSION_ERROR_HANDLER, new DialogErrorHandling(), DisplayMode.EDIT, EditErrorHandlingExample.COLUMN_FOUR_LABEL); configRegistry.registerConfigAttribute( EditConfigAttributes.VALIDATION_ERROR_HANDLER, new DialogErrorHandling(), DisplayMode.EDIT, EditErrorHandlingExample.COLUMN_FOUR_LABEL); ``` If you want to change the error handling while editing within the `TextCellEditor` you need to set your customized `IEditErrorHandler` as inputConversionErrorHandler or inputValidationErrorHandler. It is not allowed to set those handlers to `null`. ## Text editor control decoration If you want to present the user with some more contextual information in a non-intrusive manner then you can use a ControlDecoration. This allows you to show a small icon, e.g. an error or info/warning icon, to one side of the editor and when the mouse is hovered over it then a tooltip is shown with a text info message. If you're not familiar with ControlDecorations you'll almost definitely have seen them in action in Eclipse as it's how some content-assist info is presented! For example, here's a text editor with a control decoration set to show on the top, left of the editor, with the mouse hovering over the icon hence showing the tooltip: ![Text editor control decoration](images/control_decoration_during_editing.png) This is very simple to achieve (snippet from `EditableGridExample`): ```java TextCellEditor textCellEditor = new TextCellEditor(); textCellEditor.setErrorDecorationEnabled(true); textCellEditor.setErrorDecorationText( "Security Id must be 3 alpha characters optionally followed by numbers"); textCellEditor.setDecorationPositionOverride(SWT.LEFT | SWT.TOP); configRegistry.registerConfigAttribute( EditConfigAttributes.CELL_EDITOR, textCellEditor, DisplayMode.NORMAL, SECURITY_ID_EDITOR); ``` This works in tandem with the cells `ICellValidator` (and internally with the `TextCellEditors` `RenderErrorHandling` instances). You can get further access for customization by calling `TextCellEditor.getDecorationProvider()` e.g. to force the hover text to be shown immediately rather than on hover. The returned `ControlDecorationProvider` can also be reused in your own custom editors. ## How are cell values commited A cell editor fires an `UpdateDataCommand` to commit the new value for a cell. This command is handled by the `DataLayer` via the `UpdateDataCommandHandler`. Ultimately the `IDataProvider` will update the underlying data structure. ![Update data command handling](images/updateDataCommandHandling.png) ## Handling the data update differently If you want to execute a custom action when the user edits a cell you will have to: 1. Deregister the `UpdateDataCommandHandler` 2. Register your custom command handler for handling the `UpdateDataCommand` The code will look something like this ```java bodyDataLayer.unregisterCommandHandler(UpdateDataCommand.class); bodyDataLayer.registerCommandHandler(new MyUpdateDataCommandHandler()); ```