-
Notifications
You must be signed in to change notification settings - Fork 8
06_Editing
NatTable supports the following editing features:
- Inline cell editing via a text box, combobox or a checkbox
- Multiple values can be edited simultaneously via a popup on pressing F2
- 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.
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:
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).
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 ofTextCellEditor
)
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:
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.
//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");
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.
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).
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.
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).
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 aTextCellEditor
. 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.
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
.
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:
This is very simple to achieve (snippet from EditableGridExample
):
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.
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.
If you want to execute a custom action when the user edits a cell you will have to:
- Deregister the
UpdateDataCommandHandler
- Register your custom command handler for handling the
UpdateDataCommand
The code will look something like this
bodyDataLayer.unregisterCommandHandler(UpdateDataCommand.class);
bodyDataLayer.registerCommandHandler(new MyUpdateDataCommandHandler());