Package org.eclipse.nebula.widgets.nattable.extension.builder

Source Code of org.eclipse.nebula.widgets.nattable.extension.builder.NatTableBuilder

/*******************************************************************************
* Copyright (c) 2012 Original authors and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.builder;

import static org.eclipse.nebula.widgets.nattable.util.ObjectUtils.isNotNull;

import java.util.Comparator;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.columnCategories.ChooseColumnsFromCategoriesCommandHandler;
import org.eclipse.nebula.widgets.nattable.columnChooser.command.DisplayColumnChooserCommandHandler;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.NullComparator;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultBooleanDisplayConverter;
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
import org.eclipse.nebula.widgets.nattable.extension.builder.configuration.GridLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.extension.builder.configuration.RightClickColumnHeaderMenuConfiguration;
import org.eclipse.nebula.widgets.nattable.extension.builder.configuration.RowSelectionUIBindings;
import org.eclipse.nebula.widgets.nattable.extension.builder.configuration.SelectionStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.extension.builder.configuration.TableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.extension.builder.layers.BodyLayerStack;
import org.eclipse.nebula.widgets.nattable.extension.builder.layers.ColumnHeaderLayerStack;
import org.eclipse.nebula.widgets.nattable.extension.builder.layers.CornerLayerStack;
import org.eclipse.nebula.widgets.nattable.extension.builder.layers.RowHeaderLayerStack;
import org.eclipse.nebula.widgets.nattable.extension.builder.model.ColumnStyle;
import org.eclipse.nebula.widgets.nattable.extension.builder.model.IEditor;
import org.eclipse.nebula.widgets.nattable.extension.builder.model.TableColumn;
import org.eclipse.nebula.widgets.nattable.extension.builder.model.TableModel;
import org.eclipse.nebula.widgets.nattable.extension.builder.model.TableRow;
import org.eclipse.nebula.widgets.nattable.extension.builder.model.TableStyle;
import org.eclipse.nebula.widgets.nattable.extension.builder.util.ColumnAccessor;
import org.eclipse.nebula.widgets.nattable.extension.builder.util.ColumnCategoriesModelAssembler;
import org.eclipse.nebula.widgets.nattable.extension.builder.util.ColumnGroupModelAssembler;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowDataLayer;
import org.eclipse.nebula.widgets.nattable.filterrow.config.FilterRowConfigAttributes;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.CellOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.painter.cell.CheckBoxPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.ComboBoxPainter;
import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.selection.config.DefaultSelectionLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.selection.config.RowOnlySelectionConfiguration;
import org.eclipse.nebula.widgets.nattable.sort.SortConfigAttributes;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.style.editor.command.DisplayColumnStyleEditorCommandHandler;
import org.eclipse.nebula.widgets.nattable.ui.menu.DebugMenuConfiguration;
import org.eclipse.nebula.widgets.nattable.util.ObjectUtils;
import org.eclipse.swt.widgets.Composite;

import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;

/**
* Convenience class to configure the grid with the most commonly used features.
*
* @param <T>
*            Type of the object in the underlying list
*/
public class NatTableBuilder<T extends TableRow> {

    public static final String COLUMN_HEADER_COLUMN_LABEL_PREFIX = "columnHeaderColumnLabel_";
    public static final String BODY_COLUMN_LABEL_PREFIX = "bodyColumnLabel_";

    private final TableStyle tableStyle;
    private final TableModel tableModel;
    private final TableColumn[] columns;
    private final IRowIdAccessor<T> rowIdAccessor;

    private final Composite parent;
    private NatTable natTable;

    private final EventList<T> eventList;
    private FilterList<T> filterList;
    private ColumnOverrideLabelAccumulator columnLabelAccumulator;
    private IConfigRegistry configRegistry;

    // Layers
    private BodyLayerStack<T> bodyLayer;
    private ColumnHeaderLayerStack<T> columnHeaderLayer;
    private RowHeaderLayerStack<T> rowHeaderLayer;
    private CornerLayerStack<T> cornerLayer;
    private GridLayer gridLayer;

    public NatTableBuilder(Composite parent, TableModel tableModel,
            EventList<T> eventList, IRowIdAccessor<T> rowIdAccessor) {
        this.parent = parent;
        this.tableModel = tableModel;
        this.rowIdAccessor = rowIdAccessor;
        this.tableStyle = tableModel.tableStyle;
        this.columns = tableModel.columnProperties;
        this.eventList = GlazedLists.threadSafeList(eventList);
    }

    public NatTable setupLayerStacks() {
        IColumnPropertyAccessor<T> columnAccessor = new ColumnAccessor<T>(
                columns);
        configRegistry = new ConfigRegistry();
        SortedList<T> sortedRows = new SortedList<T>(eventList, null);
        filterList = new FilterList<T>(sortedRows);

        setUpColumnGroupModel();
        setUpColumnCategoriesModel();

        // Body
        bodyLayer = new BodyLayerStack<T>(tableModel, filterList);

        // Column header
        columnHeaderLayer = new ColumnHeaderLayerStack<T>(sortedRows,
                filterList, tableModel, bodyLayer, columnAccessor,
                configRegistry);

        // Row header
        rowHeaderLayer = new RowHeaderLayerStack<T>(bodyLayer, tableModel);

        // Corner
        cornerLayer = new CornerLayerStack<T>(columnHeaderLayer, rowHeaderLayer);

        // Grid
        gridLayer = new GridLayer(bodyLayer, columnHeaderLayer, rowHeaderLayer,
                cornerLayer, false);
        natTable = new NatTable(parent, gridLayer, false);
        natTable.setConfigRegistry(configRegistry);
        natTable.setBackground(tableStyle.tableBgColor);

        // Configuration
        natTable.addConfiguration(new TableStyleConfiguration(tableStyle));
        configureColumnProperties();
        configureSorting();
        configureEditing();
        configureFiltering();
        configureColumnChooser();
        configureCategoriesBasedColumnChooser();
        configureColumnStyleCustomization();
        configureGridLayer();
        configureSelectionStyle();
        configureColumnHeaderRightClickMenu();

        return natTable;
    }

    private void setUpColumnGroupModel() {
        if (tableModel.enableColumnGroups) {
            tableModel.columnGroupModel = ColumnGroupModelAssembler
                    .setupColumnGroups(tableModel.columnProperties);
        }
    }

    private void setUpColumnCategoriesModel() {
        tableModel.columnCategoriesModel = ColumnCategoriesModelAssembler
                .setupColumnCategories(tableModel.columnProperties);
    }

    public NatTable build() {
        natTable.configure();
        return natTable;
    }

    protected void configureColumnStyleCustomization() {
        if (!tableModel.enableColumnStyleCustomization) {
            return;
        }
        // Register a command handler for the StyleEditorDialog
        DisplayColumnStyleEditorCommandHandler styleChooserCommandHandler = new DisplayColumnStyleEditorCommandHandler(
                bodyLayer.getSelectionLayer(), columnLabelAccumulator,
                configRegistry);
        bodyLayer.registerCommandHandler(styleChooserCommandHandler);

        // Register the style editor as persistable
        // This will persist the style applied to the columns when
        // NatTable#saveState is invoked
        bodyLayer.registerPersistable(styleChooserCommandHandler);
        bodyLayer.registerPersistable(columnLabelAccumulator);
    }

    protected void configureColumnHeaderRightClickMenu() {
        if (tableModel.enableColumnHeaderRightClickMenu) {
            natTable.addConfiguration(new RightClickColumnHeaderMenuConfiguration(
                    natTable, tableModel));
        }

        natTable.addConfiguration(new DebugMenuConfiguration(natTable));
    }

    /**
     * Set up selection behavior. Select cells vs select rows.
     */
    protected void configureSelectionStyle() {
        SelectionLayer selectionLayer = bodyLayer.getSelectionLayer();
        if (tableModel.enableFullRowSelection) {
            selectionLayer
                    .addConfiguration(new RowOnlySelectionConfiguration<T>());
            natTable.addConfiguration(new RowSelectionUIBindings());
            selectionLayer
                    .setSelectionModel(new RowSelectionModel<T>(selectionLayer,
                            bodyLayer.getDataProvider(), rowIdAccessor));
        } else {
            selectionLayer
                    .addConfiguration(new DefaultSelectionLayerConfiguration());
        }
        natTable.addConfiguration(new SelectionStyleConfiguration(tableStyle));
    }

    /**
     * Configure the Alternate row color
     */
    protected void configureGridLayer() {
        gridLayer.addConfiguration(new GridLayerConfiguration(gridLayer,
                tableStyle));
    }

    protected void configureColumnChooser() {
        bodyLayer
                .registerCommandHandler(new DisplayColumnChooserCommandHandler(
                        bodyLayer.getSelectionLayer(), bodyLayer
                                .getColumnHideShowLayer(), columnHeaderLayer
                                .getColumnHeaderLayer(), columnHeaderLayer
                                .getDataLayer(), columnHeaderLayer
                                .getColumnGroupHeaderLayer(),
                        tableModel.columnGroupModel));
    }

    protected void configureCategoriesBasedColumnChooser() {
        if (ObjectUtils.isNull(tableModel.columnCategoriesModel)) {
            return;
        }
        bodyLayer
                .registerCommandHandler(new ChooseColumnsFromCategoriesCommandHandler(
                        bodyLayer.getColumnHideShowLayer(), columnHeaderLayer
                                .getColumnHeaderLayer(), columnHeaderLayer
                                .getDataLayer(),
                        tableModel.columnCategoriesModel));
    }

    protected void configureColumnProperties() {
        columnLabelAccumulator = new ColumnOverrideLabelAccumulator(
                bodyLayer.getDataLayer());
        bodyLayer.addLabelAccumulator(columnLabelAccumulator);

        for (int colIndex = 0; colIndex < columns.length; colIndex++) {
            Integer width = columns[colIndex].width;
            if (isNotNull(width)) {
                bodyLayer.getDataLayer().setColumnWidthByPosition(colIndex,
                        width);
            }

            // Register a label on each column
            String columnLabel = BODY_COLUMN_LABEL_PREFIX + colIndex;
            columnLabelAccumulator.registerColumnOverrides(colIndex,
                    columnLabel);

            // Add the display converter/formatter to the column
            configRegistry.registerConfigAttribute(
                    CellConfigAttributes.DISPLAY_CONVERTER,
                    columns[colIndex].displayConverter, DisplayMode.NORMAL,
                    columnLabel);

            // Add column visual style
            Style style = new Style();
            ColumnStyle columnStyle = columns[colIndex].style;
            if (ObjectUtils.isNotNull(columnStyle)) {
                style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR,
                        columnStyle.bgColor);
                style.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR,
                        columnStyle.fgColor);

                style.setAttributeValue(
                        CellStyleAttributes.HORIZONTAL_ALIGNMENT,
                        columnStyle.hAlign);
                style.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT,
                        columnStyle.vAlign);
                style.setAttributeValue(CellStyleAttributes.FONT,
                        columnStyle.font);

                style.setAttributeValue(CellStyleAttributes.BORDER_STYLE,
                        columnStyle.borderStyle);
                configRegistry.registerConfigAttribute(
                        CellConfigAttributes.CELL_STYLE, style,
                        DisplayMode.NORMAL, columnLabel);
            }
        }
    }

    protected void configureSorting() {
        ColumnOverrideLabelAccumulator columnHeaderLabelAccumulator = new ColumnOverrideLabelAccumulator(
                columnHeaderLayer.getDataLayer());
        columnHeaderLayer.addLabelAccumulator(columnHeaderLabelAccumulator);

        for (int colIndex = 0; colIndex < columns.length; colIndex++) {
            String columnHeaderLabel = COLUMN_HEADER_COLUMN_LABEL_PREFIX
                    + colIndex;

            // Register an accumulator on the Column Header layer (since it
            // triggers sort)
            columnHeaderLabelAccumulator.registerColumnOverrides(colIndex,
                    columnHeaderLabel);

            if (columns[colIndex].isSortable) {
                Comparator<?> comparator = columns[colIndex].comparator;
                configRegistry.registerConfigAttribute(
                        SortConfigAttributes.SORT_COMPARATOR, comparator,
                        DisplayMode.NORMAL, columnHeaderLabel);
            } else {
                configRegistry.registerConfigAttribute(
                        SortConfigAttributes.SORT_COMPARATOR,
                        new NullComparator(), DisplayMode.NORMAL,
                        columnHeaderLabel);
            }
        }
    }

    protected void configureFiltering() {
        if (!tableModel.enableFilterRow) {
            return;
        }
        for (int colIndex = 0; colIndex < columns.length; colIndex++) {

            String filterRowLabel = FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
                    + colIndex;
            TableColumn column = columns[colIndex];

            configRegistry.registerConfigAttribute(
                    FilterRowConfigAttributes.FILTER_COMPARATOR,
                    column.comparator, DisplayMode.NORMAL, filterRowLabel);
            configRegistry.registerConfigAttribute(
                    FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER,
                    column.filterRowDisplayConverter, DisplayMode.NORMAL,
                    filterRowLabel);
            configRegistry.registerConfigAttribute(
                    EditConfigAttributes.CELL_EDITOR,
                    column.filterRowEditor.getCellEditor(), DisplayMode.NORMAL,
                    filterRowLabel);
        }

        // Filter row style
        Style style = new Style();
        style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR,
                tableStyle.filterRowBGColor);
        style.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR,
                tableStyle.filterRowFGColor);
        style.setAttributeValue(CellStyleAttributes.FONT,
                tableStyle.filterRowFont);
        configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE,
                style, DisplayMode.NORMAL, GridRegion.FILTER_ROW);
    }

    protected void configureEditing() {
        for (int colIndex = 0; colIndex < columns.length; colIndex++) {
            TableColumn column = columns[colIndex];

            if (column.isEditable) {
                IEditor editor = column.editor;

                // Column label has been registered already
                String columnLabel = BODY_COLUMN_LABEL_PREFIX + colIndex;

                configRegistry
                        .registerConfigAttribute(
                                EditConfigAttributes.CELL_EDITABLE_RULE,
                                editor.getEditableRule(), DisplayMode.EDIT,
                                columnLabel);

                configRegistry.registerConfigAttribute(
                        EditConfigAttributes.DATA_VALIDATOR,
                        editor.getValidator(), DisplayMode.EDIT, columnLabel);

                switch (editor.getType()) {
                    case CHECKBOX:
                        configRegistry.registerConfigAttribute(
                                CellConfigAttributes.CELL_PAINTER,
                                new CheckBoxPainter(), DisplayMode.NORMAL,
                                columnLabel);
                        configRegistry.registerConfigAttribute(
                                CellConfigAttributes.DISPLAY_CONVERTER,
                                new DefaultBooleanDisplayConverter(),
                                DisplayMode.NORMAL, columnLabel);
                        configRegistry.registerConfigAttribute(
                                EditConfigAttributes.CELL_EDITOR,
                                editor.getCellEditor(), DisplayMode.NORMAL,
                                columnLabel);
                        break;
                    case COMBO:
                        configRegistry.registerConfigAttribute(
                                CellConfigAttributes.CELL_PAINTER,
                                new ComboBoxPainter(), DisplayMode.NORMAL,
                                columnLabel);
                        configRegistry.registerConfigAttribute(
                                EditConfigAttributes.CELL_EDITOR,
                                editor.getCellEditor(), DisplayMode.NORMAL,
                                columnLabel);
                        configRegistry.registerConfigAttribute(
                                EditConfigAttributes.CELL_EDITOR,
                                editor.getCellEditor(), DisplayMode.EDIT,
                                columnLabel);
                        break;
                    case TEXT:
                        configRegistry.registerConfigAttribute(
                                EditConfigAttributes.CELL_EDITOR,
                                new TextCellEditor());
                        break;
                    default:
                        break;
                }
            }
        }
    }

    // Accessors for layers

    public BodyLayerStack<T> getBodyLayerStack() {
        return bodyLayer;
    }

    public ColumnHeaderLayerStack<T> getColumnHeaderLayerStack() {
        return columnHeaderLayer;
    }

    public RowHeaderLayerStack<T> getRowHeaderLayer() {
        return rowHeaderLayer;
    }

    public CornerLayerStack<T> getCornerLayer() {
        return cornerLayer;
    }

    public GridLayer getGridLayer() {
        return gridLayer;
    }

    public TableModel getTableModel() {
        return tableModel;
    }

    public EventList<T> getEventList() {
        return eventList;
    }

    public FilterList<T> getFilterList() {
        return filterList;
    }

    public NatTable getNatTable() {
        return natTable;
    }

    public void addCellLabelsToBody(
            CellOverrideLabelAccumulator<? extends TableRow> myAccumulator) {
        bodyLayer.addLabelAccumulator(myAccumulator);
    }

}
TOP

Related Classes of org.eclipse.nebula.widgets.nattable.extension.builder.NatTableBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.