public Control createExampleControl(Composite parent) {
    DefaultGridLayer gridLayer =
        new DefaultGridLayer(
            RowDataListFixture.getList(),
            RowDataListFixture.getPropertyNames(),
            RowDataListFixture.getPropertyToLabelMap());

    DataLayer columnHeaderDataLayer = (DataLayer) gridLayer.getColumnHeaderDataLayer();
    columnHeaderDataLayer.setConfigLabelAccumulator(new ColumnLabelAccumulator());

    final DataLayer bodyDataLayer = (DataLayer) gridLayer.getBodyDataLayer();
    IDataProvider dataProvider = bodyDataLayer.getDataProvider();

    // NOTE: Register the accumulator on the body data layer.
    // This ensures that the labels are bound to the column index and are unaffected by column
    // order.
    final ColumnOverrideLabelAccumulator columnLabelAccumulator =
        new ColumnOverrideLabelAccumulator(bodyDataLayer);
    bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);

    NatTable natTable = new NatTable(parent, gridLayer, false);

    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(new HeaderMenuConfiguration(natTable));
    natTable.addConfiguration(editableGridConfiguration(columnLabelAccumulator, dataProvider));

    final ColumnHeaderCheckBoxPainter columnHeaderCheckBoxPainter =
        new ColumnHeaderCheckBoxPainter(bodyDataLayer);
    final ICellPainter column9HeaderPainter =
        new BeveledBorderDecorator(
            new CellPainterDecorator(
                new TextPainter(), CellEdgeEnum.RIGHT, columnHeaderCheckBoxPainter));
    natTable.addConfiguration(
        new AbstractRegistryConfiguration() {
          public void configureRegistry(IConfigRegistry configRegistry) {
            configRegistry.registerConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                column9HeaderPainter,
                DisplayMode.NORMAL,
                ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + 9);
          }

          @Override
          public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
            uiBindingRegistry.registerFirstSingleClickBinding(
                new CellPainterMouseEventMatcher(
                    GridRegion.COLUMN_HEADER,
                    MouseEventMatcher.LEFT_BUTTON,
                    columnHeaderCheckBoxPainter),
                new ToggleCheckBoxColumnAction(columnHeaderCheckBoxPainter, bodyDataLayer));
          }
        });

    natTable.configure();

    return natTable;
  }
    public CalculatingBodyLayerStack(
        EventList<NumberValues> valuesToShow, ConfigRegistry configRegistry) {
      final CachedValueCalculatingDataProvider<NumberValues> dataProvider =
          new CachedValueCalculatingDataProvider<NumberValues>(
              valuesToShow, new BasicDataColumnAccessor());
      bodyDataLayer = new DataLayer(dataProvider);
      // adding this listener will trigger updates on data changes
      bodyDataLayer.addLayerListener(
          new ILayerListener() {
            @Override
            public void handleLayerEvent(ILayerEvent event) {
              if (event instanceof IVisualChangeEvent) {
                dataProvider.valueCache.clearCache();
              }
            }
          });
      // register a layer listener to ensure the value cache gets disposed
      bodyDataLayer.registerCommandHandler(
          new ILayerCommandHandler<DisposeResourcesCommand>() {

            @Override
            public boolean doCommand(ILayer targetLayer, DisposeResourcesCommand command) {
              dataProvider.valueCache.dispose();
              return false;
            }

            @Override
            public Class<DisposeResourcesCommand> getCommandClass() {
              return DisposeResourcesCommand.class;
            }
          });

      // connect the DataLayer with the data provider so the value cache knows how to fire updates
      dataProvider.setCacheEventLayer(bodyDataLayer);

      glazedListsEventLayer = new GlazedListsEventLayer<NumberValues>(bodyDataLayer, valuesToShow);
      summaryRowLayer = new SummaryRowLayer(glazedListsEventLayer, configRegistry, false);
      summaryRowLayer.addConfiguration(
          new CalculatingSummaryRowConfiguration(bodyDataLayer.getDataProvider()));
      columnReorderLayer = new ColumnReorderLayer(summaryRowLayer);
      columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
      selectionLayer = new SelectionLayer(columnHideShowLayer);
      viewportLayer = new ViewportLayer(selectionLayer);
      setUnderlyingLayer(viewportLayer);

      registerCommandHandler(new CopyDataCommandHandler(selectionLayer));
    }
Esempio n. 3
0
  private void changeCurrentlyDisplayedExecutionRecord(ExecutionHistoryRecord newExecutionRecord) {
    if (newExecutionRecord.out.rows.isEmpty()) {
      // We do not want to erase the old content, but we want to give feedback that the command was
      // executed.
      return;
    }
    boolean needRefresh = currentlySelectedExecutionRecord == null;
    currentlySelectedExecutionRecord = newExecutionRecord;

    if (!needRefresh) {
      int percentage = 100 / (terminalDataLayer.getColumnCount() + 1);
      terminalDataLayer.setColumnWidthPercentageByPosition(0, percentage * 2);
      for (int i = 1; i < terminalDataLayer.getColumnCount(); i++) {
        terminalDataLayer.setColumnWidthPercentageByPosition(i, percentage);
      }
    }
    terminalGrid
        .refresh(); // FIXME: This somewhat works to display the columns the first time a command is
                    // run. Especially if the output contains few rows and does not require a scroll
                    // bar

    int selectedTab = 0;
    tabularErrorTable.clearAll();
    int numberOfErrLines = 0;
    //    if(currentlySelectedExecutionRecord.err!=null){
    //      numberOfErrLines=currentlySelectedExecutionRecord.err.rows.size();
    //      if(numberOfErrLines>0){
    //        selectedTab=1;
    //      }
    //    }
    TabFolder tabPane = (TabFolder) terminalGrid.getParent();
    tabPane.getItem(1).setText("err " + numberOfErrLines + " lines");
    tabularErrorTable.setItemCount(numberOfErrLines);

    tabularLogTable.clearAll();
    int numberOfLogLines = 0;
    //    if(currentlySelectedExecutionRecord.log!=null){
    //      numberOfLogLines=currentlySelectedExecutionRecord.log.rows.size();
    //    }
    tabPane.getItem(2).setText("log-" + numberOfLogLines);
    tabularLogTable.setItemCount(numberOfLogLines);

    tabPane.setSelection(selectedTab);
    commandLineTxt.setFocus();
  }
  /* (non-Javadoc)
   * @see org.eclipse.nebula.widgets.nattable.examples.INatExample#createExampleControl(org.eclipse.swt.widgets.Composite)
   */
  public Control createExampleControl(Composite parent) {
    Composite panel = new Composite(parent, SWT.NONE);

    GridData layoutData = GridDataFactory.fillDefaults().grab(true, true).create();

    GridLayout layout = new GridLayout();
    layout.numColumns = 1;
    layout.marginWidth = 0;
    layout.marginHeight = 0;
    panel.setLayout(layout);
    panel.setLayoutData(layoutData);

    loadMessages();

    ListDataProvider<LogRecord> dataProvider =
        new ListDataProvider<LogRecord>(
            logMessages,
            new ReflectiveColumnPropertyAccessor<LogRecord>(
                new String[] {"message"})); // $NON-NLS-1$
    DataLayer dataLayer = new DataLayer(dataProvider);
    dataLayer.setColumnPercentageSizing(true);
    dataLayer.setColumnWidthPercentageByPosition(0, 100);
    dataLayer.setConfigLabelAccumulator(new ValidatorMessageLabelAccumulator());

    ViewportLayer layer = new ViewportLayer(dataLayer);
    layer.setRegionName(GridRegion.BODY);

    NatTable natTable =
        new NatTable(panel, NatTable.DEFAULT_STYLE_OPTIONS | SWT.BORDER, layer, false);
    natTable.addConfiguration(new ValidationMessageTableStyleConfiguration());

    natTable.configure();

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

    return panel;
  }
  public CalculatingBodyLayerStack(
      EventList<NumberValues> valuesToShow, ConfigRegistry configRegistry) {
    IDataProvider dataProvider =
        new GlazedListsDataProvider<NumberValues>(valuesToShow, new CalculatingDataProvider());
    bodyDataLayer = new DataLayer(dataProvider);
    glazedListsEventLayer = new GlazedListsEventLayer<NumberValues>(bodyDataLayer, valuesToShow);
    summaryRowLayer = new SummaryRowLayer(glazedListsEventLayer, configRegistry, false);
    summaryRowLayer.addConfiguration(
        new CalculatingSummaryRowConfiguration(bodyDataLayer.getDataProvider()));
    columnReorderLayer = new ColumnReorderLayer(summaryRowLayer);
    columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
    selectionLayer = new SelectionLayer(columnHideShowLayer);
    viewportLayer = new ViewportLayer(selectionLayer);
    setUnderlyingLayer(viewportLayer);

    registerCommandHandler(new CopyDataCommandHandler(selectionLayer));
  }
    @SuppressWarnings("unchecked")
    public BodyLayerStack(
        List<T> values,
        IColumnPropertyAccessor<T> columnPropertyAccessor,
        TreeList.Format<T> treeFormat) {
      // wrapping of the list to show into GlazedLists
      // see http://publicobject.com/glazedlists/ for further information
      EventList<T> eventList = GlazedLists.eventList(values);
      TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);

      // use the SortedList constructor with 'null' for the Comparator because the Comparator
      // will be set by configuration
      SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
      // wrap the SortedList with the TreeList
      this.treeList = new TreeList<T>(sortedList, treeFormat, TreeList.NODES_START_EXPANDED);

      this.bodyDataProvider = new GlazedListsDataProvider<T>(treeList, columnPropertyAccessor);
      DataLayer bodyDataLayer = new DataLayer(this.bodyDataProvider);

      // simply apply labels for every column by index
      bodyDataLayer.setConfigLabelAccumulator(new ColumnLabelAccumulator());

      // layer for event handling of GlazedLists and PropertyChanges
      GlazedListsEventLayer<T> glazedListsEventLayer =
          new GlazedListsEventLayer<T>(bodyDataLayer, treeList);

      GlazedListTreeData<T> treeData =
          new GlazedListTreeData<T>(treeList) {
            @Override
            public String formatDataForDepth(int depth, T object) {
              if (object instanceof PersonWithAddress) {
                return ((PersonWithAddress) object).getLastName();
              }
              return null;
            }
          };
      ITreeRowModel<T> treeRowModel = new GlazedListTreeRowModel<T>(treeData);

      this.selectionLayer = new SelectionLayer(glazedListsEventLayer);

      TreeLayer treeLayer =
          new TreeLayer(selectionLayer, treeRowModel) {
            @Override
            public ICellPainter getCellPainter(
                int columnPosition,
                int rowPosition,
                ILayerCell cell,
                IConfigRegistry configRegistry) {
              ICellPainter painter =
                  super.getCellPainter(columnPosition, rowPosition, cell, configRegistry);
              // this is a little hack to get a padding between tree node icon and left border
              // the reason for this hack is that the TreeLayer internally wraps the registered
              // cell painter with the IndentedTreeImagePainter
              // so for backwards compatibility instead of adding it to the TreeLayer itself
              // we override getCellPainter() and wrap the created painter for the tree column again
              if (columnPosition == TREE_COLUMN_NUMBER) {
                painter = new PaddingDecorator(painter, 0, 0, 0, 2);
              }
              return painter;
            }
          };
      ViewportLayer viewportLayer = new ViewportLayer(treeLayer);

      setUnderlyingLayer(viewportLayer);
    }
  @Override
  public Control createExampleControl(Composite parent) {
    // create a new ConfigRegistry which will be needed for GlazedLists
    // handling
    ConfigRegistry configRegistry = new ConfigRegistry();

    String[] propertyNames = {"name", "age", "money", "gender", "city"};

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<>();
    propertyToLabelMap.put("name", "Name");
    propertyToLabelMap.put("age", "Age");
    propertyToLabelMap.put("money", "Money");
    propertyToLabelMap.put("gender", "Gender");
    propertyToLabelMap.put("city", "City");

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

    BodyLayerStack<MyRowObject> bodyLayerStack =
        new BodyLayerStack<>(createMyRowObjects(50), columnPropertyAccessor);
    // add a label accumulator to be able to register converter
    bodyLayerStack.getBodyDataLayer().setConfigLabelAccumulator(new ColumnLabelAccumulator());

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

    // Note: The column header layer is wrapped in a filter row composite.
    // This plugs in the filter row functionality
    FilterRowHeaderComposite<MyRowObject> filterRowHeaderLayer =
        new FilterRowHeaderComposite<>(
            new DefaultGlazedListsFilterStrategy<>(
                bodyLayerStack.getFilterList(), columnPropertyAccessor, configRegistry),
            columnHeaderLayer,
            columnHeaderDataLayer.getDataProvider(),
            configRegistry);

    // 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, filterRowHeaderLayer);

    // build the grid layer
    GridLayer gridLayer =
        new GridLayer(bodyLayerStack, filterRowHeaderLayer, 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 and the ConfigRegistry manually
    natTable.setConfigRegistry(configRegistry);
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    // add filter row configuration
    natTable.addConfiguration(new FilterRowConfiguration());
    natTable.addConfiguration(new MyRowObjectTableConfiguration());

    natTable.addConfiguration(
        new HeaderMenuConfiguration(natTable) {
          @Override
          protected PopupMenuBuilder createCornerMenu(NatTable natTable) {
            return super.createCornerMenu(natTable).withStateManagerMenuItemProvider();
          }
        });

    natTable.configure();

    natTable.registerCommandHandler(new DisplayPersistenceDialogCommandHandler(natTable));

    return natTable;
  }
  /* (non-Javadoc)
   * @see org.eclipse.nebula.widgets.nattable.examples.INatExample#createExampleControl(org.eclipse.swt.widgets.Composite)
   */
  @Override
  public Control createExampleControl(Composite parent) {
    Composite panel = new Composite(parent, SWT.NONE);
    panel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(panel);

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

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

    // property names of the NumberValues class
    String[] propertyNames = {
      "columnOneNumber",
      "columnTwoNumber",
      "columnThreeNumber",
      "columnFourNumber",
      "columnFiveNumber"
    };

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("columnOneNumber", "100%");
    propertyToLabelMap.put("columnTwoNumber", "Value One");
    propertyToLabelMap.put("columnThreeNumber", "Value Two");
    propertyToLabelMap.put("columnFourNumber", "Sum");
    propertyToLabelMap.put("columnFiveNumber", "Percentage");

    valuesToShow.add(createNumberValues());
    valuesToShow.add(createNumberValues());

    ConfigRegistry configRegistry = new ConfigRegistry();

    CalculatingGridLayer gridLayer =
        new CalculatingGridLayer(valuesToShow, configRegistry, propertyNames, propertyToLabelMap);
    DataLayer bodyDataLayer = gridLayer.getBodyDataLayer();

    final ColumnOverrideLabelAccumulator columnLabelAccumulator =
        new ColumnOverrideLabelAccumulator(bodyDataLayer);
    bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
    registerColumnLabels(columnLabelAccumulator);

    final NatTable natTable = new NatTable(gridPanel, gridLayer, false);
    natTable.setConfigRegistry(configRegistry);
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(new CalculatingEditConfiguration());
    natTable.configure();
    GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);

    Button addRowButton = new Button(buttonPanel, SWT.PUSH);
    addRowButton.setText("add row");
    addRowButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            valuesToShow.add(createNumberValues());
          }
        });

    Button resetButton = new Button(buttonPanel, SWT.PUSH);
    resetButton.setText("reset");
    resetButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            valuesToShow.clear();
            valuesToShow.add(createNumberValues());
            valuesToShow.add(createNumberValues());
          }
        });

    return panel;
  }
  @Override
  public Control createExampleControl(Composite parent) {
    IConfigRegistry configRegistry = new ConfigRegistry();

    // Underlying data source
    EventList<RowDataFixture> eventList = GlazedLists.eventList(RowDataListFixture.getList(200));
    FilterList<RowDataFixture> filterList = new FilterList<RowDataFixture>(eventList);
    String[] propertyNames = RowDataListFixture.getPropertyNames();
    Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();

    // Body
    IColumnPropertyAccessor<RowDataFixture> columnPropertyAccessor =
        new ReflectiveColumnPropertyAccessor<RowDataFixture>(propertyNames);
    ListDataProvider<RowDataFixture> bodyDataProvider =
        new ListDataProvider<RowDataFixture>(filterList, columnPropertyAccessor);
    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
    ColumnGroupBodyLayerStack bodyLayer =
        new ColumnGroupBodyLayerStack(bodyDataLayer, columnGroupModel);

    ColumnOverrideLabelAccumulator bodyLabelAccumulator =
        new ColumnOverrideLabelAccumulator(bodyDataLayer);
    bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);

    bodyLabelAccumulator.registerColumnOverrides(
        RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
        "PRICING_TYPE_PROP_NAME");

    // Column header
    IDataProvider columnHeaderDataProvider =
        new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    columnHeaderLayer =
        new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());
    ColumnGroupHeaderLayer columnGroupHeaderLayer =
        new ColumnGroupHeaderLayer(
            columnHeaderLayer, bodyLayer.getSelectionLayer(), columnGroupModel);

    columnGroupHeaderLayer.addColumnsIndexesToGroup("Group 1", 1, 2);

    // calculate the height of the column header area dependent if column groups exist or not
    columnGroupHeaderLayer.setCalculateHeight(true);

    //	Note: The column header layer is wrapped in a filter row composite.
    //	This plugs in the filter row functionality
    final FilterRowHeaderComposite<RowDataFixture> filterRowHeaderLayer =
        new FilterRowHeaderComposite<RowDataFixture>(
            new DefaultGlazedListsFilterStrategy<RowDataFixture>(
                filterList, columnPropertyAccessor, configRegistry),
            columnGroupHeaderLayer,
            columnHeaderDataProvider,
            configRegistry);

    filterRowHeaderLayer.setFilterRowVisible(false);

    ColumnOverrideLabelAccumulator labelAccumulator =
        new ColumnOverrideLabelAccumulator(columnHeaderDataLayer);
    columnHeaderDataLayer.setConfigLabelAccumulator(labelAccumulator);

    // Register labels
    labelAccumulator.registerColumnOverrides(
        RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.RATING_PROP_NAME),
        "CUSTOM_COMPARATOR_LABEL");

    // Row header

    final DefaultRowHeaderDataProvider rowHeaderDataProvider =
        new DefaultRowHeaderDataProvider(bodyDataProvider);
    DefaultRowHeaderDataLayer rowHeaderDataLayer =
        new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    ILayer rowHeaderLayer =
        new RowHeaderLayer(rowHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());

    // Corner

    final DefaultCornerDataProvider cornerDataProvider =
        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, filterRowHeaderLayer);

    // Grid
    GridLayer gridLayer =
        new GridLayer(bodyLayer, filterRowHeaderLayer, rowHeaderLayer, cornerLayer);

    NatTable natTable = new NatTable(parent, gridLayer, false);

    // Register create column group command handler

    // Register column chooser
    DisplayColumnChooserCommandHandler columnChooserCommandHandler =
        new DisplayColumnChooserCommandHandler(
            bodyLayer.getSelectionLayer(),
            bodyLayer.getColumnHideShowLayer(),
            columnHeaderLayer,
            columnHeaderDataLayer,
            columnGroupHeaderLayer,
            columnGroupModel);
    bodyLayer.registerCommandHandler(columnChooserCommandHandler);

    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(
        new HeaderMenuConfiguration(natTable) {
          @Override
          protected PopupMenuBuilder createColumnHeaderMenu(NatTable natTable) {
            return super.createColumnHeaderMenu(natTable).withColumnChooserMenuItem();
          }
        });
    natTable.addConfiguration(
        new AbstractRegistryConfiguration() {
          @Override
          public void configureRegistry(IConfigRegistry configRegistry) {
            configRegistry.registerConfigAttribute(
                ExportConfigAttributes.EXPORTER, new HSSFExcelExporter());
          }
        });
    natTable.addConfiguration(new FilterRowCustomConfiguration());

    natTable.setConfigRegistry(configRegistry);
    natTable.configure();

    // add button
    Button button = new Button(parent, SWT.NONE);
    button.setText("Switch FilterRow visibility");
    button.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            filterRowHeaderLayer.setFilterRowVisible(!filterRowHeaderLayer.isFilterRowVisible());
          }
        });

    return natTable;
  }