@Override
  public Control createExampleControl(Composite parent) {
    Composite panel = new Composite(parent, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    panel.setLayout(layout);
    GridDataFactory.fillDefaults().grab(true, true).applyTo(panel);

    Composite gridPanel = new Composite(panel, SWT.NONE);
    gridPanel.setLayout(layout);
    GridDataFactory.fillDefaults().grab(true, true).applyTo(gridPanel);

    Composite buttonPanel = new Composite(panel, SWT.NONE);
    buttonPanel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonPanel);

    // property names of the Person class
    String[] propertyNames = {"firstName", "lastName", "gender", "married", "birthday"};

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("firstName", "Firstname");
    propertyToLabelMap.put("lastName", "Lastname");
    propertyToLabelMap.put("gender", "Gender");
    propertyToLabelMap.put("married", "Married");
    propertyToLabelMap.put("birthday", "Birthday");

    IDataProvider bodyDataProvider =
        new DefaultBodyDataProvider<Person>(PersonService.getPersons(100), propertyNames);
    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
    SelectionLayer selectionLayer = new SelectionLayer(bodyDataLayer);
    ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

    // add the PrintCommandHandler to the ViewportLayer in order to make
    // printing work
    viewportLayer.registerCommandHandler(new PrintCommandHandler(viewportLayer));

    final NatTable natTable = new NatTable(gridPanel, viewportLayer, false);

    // adding this configuration adds the styles and the painters to use
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(new DefaultPrintBindings());

    natTable.configure();

    GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);

    Button addColumnButton = new Button(buttonPanel, SWT.PUSH);
    addColumnButton.setText("Print");
    addColumnButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            natTable.doCommand(new PrintCommand(natTable.getConfigRegistry(), natTable.getShell()));
          }
        });

    return panel;
  }
  @Override
  public Control createExampleControl(Composite parent) {
    Composite container = new Composite(parent, SWT.NONE);
    container.setLayout(new GridLayout());

    // create a new ConfigRegistry which will be needed for GlazedLists handling
    ConfigRegistry configRegistry = new ConfigRegistry();

    // property names of the Person class
    String[] propertyNames = {"lastName", "firstName", "gender", "married", "birthday"};

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("lastName", "Lastname");
    propertyToLabelMap.put("firstName", "Firstname");
    propertyToLabelMap.put("gender", "Gender");
    propertyToLabelMap.put("married", "Married");
    propertyToLabelMap.put("birthday", "Birthday");

    IColumnPropertyAccessor<PersonWithAddress> columnPropertyAccessor =
        new ReflectiveColumnPropertyAccessor<PersonWithAddress>(propertyNames);

    final BodyLayerStack<PersonWithAddress> bodyLayerStack =
        new BodyLayerStack<PersonWithAddress>(
            PersonService.getPersonsWithAddress(50),
            columnPropertyAccessor,
            new PersonWithAddressTreeFormat());

    // build the column header layer
    IDataProvider columnHeaderDataProvider =
        new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    ILayer columnHeaderLayer =
        new ColumnHeaderLayer(
            columnHeaderDataLayer, bodyLayerStack, bodyLayerStack.getSelectionLayer());

    // build the row header layer
    IDataProvider rowHeaderDataProvider =
        new DefaultRowHeaderDataProvider(bodyLayerStack.getBodyDataProvider());
    DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    ILayer rowHeaderLayer =
        new RowHeaderLayer(rowHeaderDataLayer, bodyLayerStack, bodyLayerStack.getSelectionLayer());

    // build the corner layer
    IDataProvider cornerDataProvider =
        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);

    // build the grid layer
    GridLayer gridLayer =
        new GridLayer(bodyLayerStack, columnHeaderLayer, rowHeaderLayer, cornerLayer);

    // turn the auto configuration off as we want to add our header menu configuration
    final NatTable natTable = new NatTable(container, gridLayer, false);

    // as the autoconfiguration of the NatTable is turned off, we have to add the
    // DefaultNatTableStyleConfiguration and the ConfigRegistry manually
    natTable.setConfigRegistry(configRegistry);
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());

    natTable.addConfiguration(
        new AbstractRegistryConfiguration() {

          @Override
          public void configureRegistry(IConfigRegistry configRegistry) {
            // register a CheckBoxPainter as CellPainter for the married information
            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                new CheckBoxPainter(),
                DisplayMode.NORMAL,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + 3);

            configRegistry.registerConfigAttribute(
                CellConfigAttributes.DISPLAY_CONVERTER,
                new DefaultDateDisplayConverter("MM/dd/yyyy"),
                DisplayMode.NORMAL,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + 4);
          }
        });

    natTable.configure();

    GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);

    Composite buttonPanel = new Composite(container, SWT.NONE);
    buttonPanel.setLayout(new RowLayout());
    GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonPanel);

    Button collapseAllButton = new Button(buttonPanel, SWT.PUSH);
    collapseAllButton.setText("Collapse All");
    collapseAllButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            natTable.doCommand(new TreeCollapseAllCommand());
          }
        });

    Button expandAllButton = new Button(buttonPanel, SWT.PUSH);
    expandAllButton.setText("Expand All");
    expandAllButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            natTable.doCommand(new TreeExpandAllCommand());
          }
        });

    return container;
  }
  @Override
  public Control createExampleControl(Composite parent) {
    // property names of the Person class
    String[] propertyNames = {"firstName", "lastName", "gender", "married", "birthday"};

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("firstName", "Firstname");
    propertyToLabelMap.put("lastName", "Lastname");
    propertyToLabelMap.put("gender", "Gender");
    propertyToLabelMap.put("married", "Married");
    propertyToLabelMap.put("birthday", "Birthday");

    // build the body layer stack
    // Usually you would create a new layer stack by extending
    // AbstractIndexLayerTransform and setting the ViewportLayer
    // as underlying layer. But in this case using the ViewportLayer
    // directly as body layer is also working.
    IDataProvider bodyDataProvider =
        new DefaultBodyDataProvider<Person>(PersonService.getPersons(10), propertyNames);
    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
    SelectionLayer selectionLayer = new SelectionLayer(bodyDataLayer);
    ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

    // build the column header layer
    IDataProvider columnHeaderDataProvider =
        new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    HoverLayer columnHoverLayer = new HoverLayer(columnHeaderDataLayer, false);
    ColumnHeaderLayer columnHeaderLayer =
        new ColumnHeaderLayer(columnHoverLayer, viewportLayer, selectionLayer, false);

    // add ColumnHeaderHoverLayerConfiguration to ensure that hover styling
    // and resizing is working together
    columnHeaderLayer.addConfiguration(new ColumnHeaderHoverLayerConfiguration(columnHoverLayer));

    // build the row header layer
    IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
    DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    HoverLayer rowHoverLayer = new HoverLayer(rowHeaderDataLayer, false);
    RowHeaderLayer rowHeaderLayer =
        new RowHeaderLayer(rowHoverLayer, viewportLayer, selectionLayer, false);

    // add RowHeaderHoverLayerConfiguration to ensure that hover styling and
    // resizing is working together
    rowHeaderLayer.addConfiguration(new RowHeaderHoverLayerConfiguration(rowHoverLayer));

    // build the corner layer
    IDataProvider cornerDataProvider =
        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);

    // build the grid layer
    GridLayer gridLayer =
        new GridLayer(viewportLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);

    // turn the auto configuration off as we want to add our header menu
    // configuration
    NatTable natTable = new NatTable(parent, gridLayer, false);

    // as the autoconfiguration of the NatTable is turned off, we have to
    // add the DefaultNatTableStyleConfiguration manually
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());

    natTable.addConfiguration(
        new AbstractUiBindingConfiguration() {
          @Override
          public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
            uiBindingRegistry.registerMouseMoveBinding(
                new MouseEventMatcher(GridRegion.BODY), new ClearHoverStylingAction());
          }
        });

    // add the style configuration for hover
    natTable.addConfiguration(
        new AbstractRegistryConfiguration() {

          @Override
          public void configureRegistry(IConfigRegistry configRegistry) {
            Style style = new Style();
            style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_RED);

            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_STYLE, style, DisplayMode.HOVER, GridRegion.ROW_HEADER);

            Image bgImage =
                GUIHelper.getImageByURL(
                    "columnHeaderBg",
                    getClass()
                        .getResource(
                            "/org/eclipse/nebula/widgets/nattable/examples/resources/column_header_bg.png"));

            Image hoverBgImage =
                GUIHelper.getImageByURL(
                    "hoverColumnHeaderBg",
                    getClass()
                        .getResource(
                            "/org/eclipse/nebula/widgets/nattable/examples/resources/hovered_column_header_bg.png"));

            Image selectedBgImage =
                GUIHelper.getImageByURL(
                    "selectedColumnHeaderBg",
                    getClass()
                        .getResource(
                            "/org/eclipse/nebula/widgets/nattable/examples/resources/selected_column_header_bg.png"));

            TextPainter txtPainter = new TextPainter(false, false);

            ICellPainter bgImagePainter =
                new BackgroundImagePainter(txtPainter, bgImage, GUIHelper.getColor(192, 192, 192));

            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                bgImagePainter,
                DisplayMode.NORMAL,
                GridRegion.COLUMN_HEADER);
            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                bgImagePainter,
                DisplayMode.NORMAL,
                GridRegion.CORNER);

            ICellPainter hoveredHeaderPainter =
                new BackgroundImagePainter(
                    txtPainter, hoverBgImage, GUIHelper.getColor(192, 192, 192));

            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                hoveredHeaderPainter,
                DisplayMode.HOVER,
                GridRegion.COLUMN_HEADER);

            ICellPainter selectedHeaderPainter =
                new BackgroundImagePainter(
                    txtPainter, selectedBgImage, GUIHelper.getColor(192, 192, 192));

            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                selectedHeaderPainter,
                DisplayMode.SELECT,
                GridRegion.COLUMN_HEADER);
          }
        });
    natTable.configure();

    return natTable;
  }
  @Override
  public Control createExampleControl(Composite parent) {
    // property names of the Person class
    String[] propertyNames = {"firstName", "lastName", "gender", "married", "birthday"};

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("firstName", "Firstname");
    propertyToLabelMap.put("lastName", "Lastname");
    propertyToLabelMap.put("gender", "Gender");
    propertyToLabelMap.put("married", "Married");
    propertyToLabelMap.put("birthday", "Birthday");

    // build the body layer stack
    // Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
    // setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
    // directly as body layer is also working.

    // first wrap the base list in a GlazedLists EventList and a FilterList so it is possible to
    // filter
    EventList<Person> eventList = GlazedLists.eventList(PersonService.getPersons(10));
    FilterList<Person> filterList = new FilterList<Person>(eventList);

    // use the GlazedListsDataProvider for some performance tweaks
    final IRowDataProvider<Person> bodyDataProvider =
        new GlazedListsDataProvider<Person>(
            filterList, new ReflectiveColumnPropertyAccessor<Person>(propertyNames));
    // create the IRowIdAccessor that is necessary for row hide/show
    final IRowIdAccessor<Person> rowIdAccessor =
        new IRowIdAccessor<Person>() {
          @Override
          public Serializable getRowId(Person rowObject) {
            return rowObject.getId();
          }
        };

    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);

    // add a DetailGlazedListsEventLayer event layer that is responsible for updating the grid on
    // list changes
    DetailGlazedListsEventLayer<Person> glazedListsEventLayer =
        new DetailGlazedListsEventLayer<Person>(bodyDataLayer, filterList);

    GlazedListsRowHideShowLayer<Person> rowHideShowLayer =
        new GlazedListsRowHideShowLayer<Person>(
            glazedListsEventLayer, bodyDataProvider, rowIdAccessor, filterList);

    SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
    ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

    // build the column header layer
    IDataProvider columnHeaderDataProvider =
        new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    ILayer columnHeaderLayer =
        new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);

    // build the row header layer
    IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
    DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);

    // build the corner layer
    IDataProvider cornerDataProvider =
        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);

    // build the grid layer
    GridLayer gridLayer =
        new GridLayer(viewportLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);

    // turn the auto configuration off as we want to add our header menu configuration
    NatTable natTable = new NatTable(parent, gridLayer, false);

    // as the autoconfiguration of the NatTable is turned off, we have to add the
    // DefaultNatTableStyleConfiguration manually
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());

    // add the header menu configuration for adding the column header menu with hide/show actions
    natTable.addConfiguration(
        new AbstractHeaderMenuConfiguration(natTable) {

          @Override
          protected PopupMenuBuilder createRowHeaderMenu(NatTable natTable) {
            return new PopupMenuBuilder(natTable).withHideRowMenuItem().withShowAllRowsMenuItem();
          }

          @Override
          protected PopupMenuBuilder createCornerMenu(NatTable natTable) {
            return super.createCornerMenu(natTable)
                .withShowAllRowsMenuItem()
                .withStateManagerMenuItemProvider();
          }
        });
    natTable.configure();

    natTable.registerCommandHandler(new DisplayPersistenceDialogCommandHandler(natTable));

    return natTable;
  }