Home Tutorials Training Consulting Products Books Company Donate Contact us









NOW Hiring

Quick links

Share

Nebula NatTable - Editing Tutorial. This tutorial explains the edit mechanisms in NatTable. After this tutorial you should be able to configure the edit behavior in NatTable. This tutorial is based on Nebula NatTable 2.0.

1. Exercise: Add simple editing support to a NatTable

1.1. Target

In this exercise editing support will be provided for a simple first name and last name table.

1.2. Creating a part with a NatTable

Add another part called Simple Edit to the application model.

In an SimpleEditor class a simple table with first name and last name is created.

For the sake of practicing you could try to create such an NatTable on your own, by using the PersonService, a ReflectiveColumnPropertyAccessor, a ListDataProvider, a header data provider, e.g., a PersonHeaderDataProvider, and the DefaultGridLayer.

Now for simple text editing purposes only a EditConfigAttributes.CELL_EDITABLE_RULE config attribute has to be registered to the IConfigRegistry.

natTable.addConfiguration(new AbstractRegistryConfiguration() {
    @Override
    public void configureRegistry(IConfigRegistry configRegistry) {
        configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE,
                IEditableRule.ALWAYS_EDITABLE);
    }
});

The complete implementation of the SimpleEditor would look like this:

package com.vogella.nattable.parts.edit;

import java.util.List;

import javax.annotation.PostConstruct;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultGridLayer;
import org.eclipse.swt.widgets.Composite;

import com.vogella.model.person.Person;
import com.vogella.model.person.PersonService;
import com.vogella.nattable.data.PersonHeaderDataProvider;

public class SimpleEditor {

    @PostConstruct
    public void postConstruct(Composite parent, PersonService personService) {
        List<Person> persons = personService.getPersons(10);
        ReflectiveColumnPropertyAccessor<Person> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<>(
                "firstName", "lastName");
        ListDataProvider<Person> dataProvider = new ListDataProvider<>(persons, columnPropertyAccessor);

        PersonHeaderDataProvider headerDataProvider = new PersonHeaderDataProvider();

        DefaultGridLayer gridLayer = new DefaultGridLayer(dataProvider, headerDataProvider);

        NatTable natTable = new NatTable(parent, gridLayer, false);
        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
        natTable.addConfiguration(new AbstractRegistryConfiguration() {

            @Override
            public void configureRegistry(IConfigRegistry configRegistry) {
                configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE,
                        IEditableRule.ALWAYS_EDITABLE);
            }
        });

        natTable.configure();
    }

}

1.3. Validate

When running the application the Simple Editor part should look similar to this:

simple editor

2. Exercise: Add more advanced editing support to a NatTable

2.1. Target

In this exercise editing support will be provided for a table, which contains different data than only strings. So different cell editors have to be applied for different columns.

2.2. Creating a part with a NatTable

Add another part called Advanced Edit to the application model.

In an AdvancedEditor class a default Person table with first name, last name, gender, married, and birthday is created.

You can reuse the code from the SimpleEditor of a former exercise.

For the SimpleEditor an anonymous inner class of an AbstractRegistryConfiguration was used to apply basic editing capabilities.

Now that the configuration becomes more complex it is better to encapsulate it in another class:

package com.vogella.nattable.parts.edit;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Locale;

import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultBooleanDisplayConverter;
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultDateDisplayConverter;
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
import org.eclipse.nebula.widgets.nattable.edit.editor.CheckBoxCellEditor;
import org.eclipse.nebula.widgets.nattable.edit.editor.ComboBoxCellEditor;
import org.eclipse.nebula.widgets.nattable.edit.editor.DateCellEditor;
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.painter.cell.CheckBoxPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.ComboBoxPainter;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;

import com.vogella.model.person.Person.Gender;

public class EditConfiguration extends AbstractRegistryConfiguration {

    @Override
    public void configureRegistry(IConfigRegistry configRegistry) {
        configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.ALWAYS_EDITABLE);

        registerEditors(configRegistry);
    }

    private void registerEditors(IConfigRegistry configRegistry) {
        registerLastNameEditor(configRegistry, 1);
        registerGenderEditor(configRegistry, 2);
        registerMarriedEditor(configRegistry, 3);
        registerBirthdayEditor(configRegistry, 4);
    }

    private void registerLastNameEditor(IConfigRegistry configRegistry, int columnIndex) {
        // register a TextCellEditor for column two that commits on key up/down
        // moves the selection after commit by enter
        configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new TextCellEditor(true, true),
                DisplayMode.NORMAL, ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);

        // configure to open the adjacent editor after commit
        configRegistry.registerConfigAttribute(EditConfigAttributes.OPEN_ADJACENT_EDITOR, Boolean.TRUE,
                DisplayMode.EDIT, ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);
    }

    private void registerGenderEditor(IConfigRegistry configRegistry, int columnIndex) {
        ComboBoxCellEditor comboBoxCellEditor = new ComboBoxCellEditor(Arrays.asList(Gender.FEMALE, Gender.MALE));
        configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, comboBoxCellEditor, DisplayMode.EDIT,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);

        configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new ComboBoxPainter(),
                DisplayMode.NORMAL, ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);
    }

    private void registerMarriedEditor(IConfigRegistry configRegistry, int columnIndex) {
        configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new CheckBoxCellEditor(),
                DisplayMode.EDIT, ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);

        // The CheckBoxCellEditor can also be visualized like a check button
        configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new CheckBoxPainter(),
                DisplayMode.NORMAL, ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);

        // using a CheckBoxCellEditor also needs a Boolean conversion to work
        // correctly
        configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER,
                new DefaultBooleanDisplayConverter(), DisplayMode.NORMAL,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);
    }

    private void registerBirthdayEditor(IConfigRegistry configRegistry, int columnIndex) {
        DateCellEditor dateCellEditor = new DateCellEditor();
        configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, dateCellEditor, DisplayMode.EDIT,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);

        DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
        String pattern = ((SimpleDateFormat) formatter).toPattern();

        // using a DateCellEditor also needs a Date conversion to work correctly
        configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER,
                new DefaultDateDisplayConverter(pattern), DisplayMode.NORMAL,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex);
    }

}

In the EditConfiguration class different cell editors are applied and configured for the different columns.

In the AdvancedEditor implementation this EditConfiguration has to be added to the NatTable configuration.

natTable.addConfiguration(new EditConfiguration());

And since the columns in the EditConfiguration class are references by labels like this ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + columnIndex a ColumnLabelAccumulator has to be applied to the body data layer.

DefaultGridLayer gridLayer = new DefaultGridLayer(dataProvider, headerDataProvider);

ColumnLabelAccumulator columnLabelAccumulator = new ColumnLabelAccumulator(dataProvider);
((DataLayer) gridLayer.getBodyDataLayer()).setConfigLabelAccumulator(columnLabelAccumulator);

So the final AdvancedEditor class should look similar to this:

package com.vogella.nattable.parts.edit;

import java.util.List;

import javax.annotation.PostConstruct;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultGridLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnLabelAccumulator;
import org.eclipse.swt.widgets.Composite;

import com.vogella.model.person.Person;
import com.vogella.model.person.PersonService;
import com.vogella.nattable.data.PersonDataProvider;
import com.vogella.nattable.data.PersonHeaderDataProvider;

public class AdvancedEditor {

    @PostConstruct
    public void postConstruct(Composite parent, PersonService personService) {
        List<Person> persons = personService.getPersons(10);
        PersonDataProvider dataProvider = new PersonDataProvider(persons);

        PersonHeaderDataProvider headerDataProvider = new PersonHeaderDataProvider();
        DefaultGridLayer gridLayer = new DefaultGridLayer(dataProvider, headerDataProvider);

        // Apply a ColumnLabelAccumulator to address the columns in the
        // EditConfiguration class
        ColumnLabelAccumulator columnLabelAccumulator = new ColumnLabelAccumulator(dataProvider);
        ((DataLayer) gridLayer.getBodyDataLayer()).setConfigLabelAccumulator(columnLabelAccumulator);

        NatTable natTable = new NatTable(parent, gridLayer, false);
        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
        // add the EditConfiguration to enable editing support
        natTable.addConfiguration(new EditConfiguration());

        natTable.configure();
    }

}

2.3. Validate

When running the application the Advanced Editor part should look similar to this:

advanced editor

3. About this website

4.1. vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.

The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.

Copyright © 2012-2017 vogella GmbH. Free use of the software examples is granted under the terms of the EPL License. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.