org.greatlogic.gxtexamples.client.glgwt.GLGridWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.greatlogic.gxtexamples.client.glgwt.GLGridWidget.java

Source

package org.greatlogic.gxtexamples.client.glgwt;

/*
 * Copyright 2006-2014 Andy King (GreatLogic.com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;
import org.greatlogic.gxtexamples.client.glgwt.GLValueProviderClasses.GLBigDecimalValueProvider;
import org.greatlogic.gxtexamples.client.glgwt.GLValueProviderClasses.GLBooleanValueProvider;
import org.greatlogic.gxtexamples.client.glgwt.GLValueProviderClasses.GLDateValueProvider;
import org.greatlogic.gxtexamples.client.glgwt.GLValueProviderClasses.GLForeignKeyValueProvider;
import org.greatlogic.gxtexamples.client.glgwt.GLValueProviderClasses.GLIntegerValueProvider;
import org.greatlogic.gxtexamples.client.glgwt.GLValueProviderClasses.GLStringValueProvider;
import org.greatlogic.gxtexamples.client.glgwt.IGLEnums.EGLColumnDataType;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.safecss.shared.SafeStyles;
import com.google.gwt.safecss.shared.SafeStylesUtils;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.cell.core.client.NumberCell;
import com.sencha.gxt.cell.core.client.form.CheckBoxCell;
import com.sencha.gxt.core.client.IdentityValueProvider;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.util.TextMetrics;
import com.sencha.gxt.data.shared.Converter;
import com.sencha.gxt.data.shared.LabelProvider;
import com.sencha.gxt.data.shared.Store;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.Dialog.PredefinedButton;
import com.sencha.gxt.widget.core.client.box.AlertMessageBox;
import com.sencha.gxt.widget.core.client.box.ConfirmMessageBox;
import com.sencha.gxt.widget.core.client.box.ProgressMessageBox;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.BoxLayoutContainer.BoxLayoutPack;
import com.sencha.gxt.widget.core.client.event.ColumnWidthChangeEvent;
import com.sencha.gxt.widget.core.client.event.ColumnWidthChangeEvent.ColumnWidthChangeHandler;
import com.sencha.gxt.widget.core.client.event.DialogHideEvent;
import com.sencha.gxt.widget.core.client.event.DialogHideEvent.DialogHideHandler;
import com.sencha.gxt.widget.core.client.event.HeaderContextMenuEvent;
import com.sencha.gxt.widget.core.client.event.HeaderContextMenuEvent.HeaderContextMenuHandler;
import com.sencha.gxt.widget.core.client.event.RefreshEvent;
import com.sencha.gxt.widget.core.client.event.RowClickEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.form.BigDecimalField;
import com.sencha.gxt.widget.core.client.form.ComboBox;
import com.sencha.gxt.widget.core.client.form.DateField;
import com.sencha.gxt.widget.core.client.form.DateTimePropertyEditor;
import com.sencha.gxt.widget.core.client.form.IntegerField;
import com.sencha.gxt.widget.core.client.form.IsField;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.sencha.gxt.widget.core.client.grid.CheckBoxSelectionModel;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.grid.GridSelectionModel;
import com.sencha.gxt.widget.core.client.grid.GridView;
import com.sencha.gxt.widget.core.client.grid.editing.GridEditing;
import com.sencha.gxt.widget.core.client.grid.editing.GridInlineEditing;
import com.sencha.gxt.widget.core.client.menu.Item;
import com.sencha.gxt.widget.core.client.menu.MenuItem;

public abstract class GLGridWidget implements IsWidget {
    //--------------------------------------------------------------------------------------------------
    private final HashSet<ColumnConfig<GLRecord, ?>> _checkBoxSet;
    private ContentPanel _contentPanel;
    private Grid<GLRecord> _grid;
    protected ArrayList<GLGridColumnDef> _gridColumnDefList;
    private TreeMap<String, GLGridColumnDef> _gridColumnDefMap;
    protected GLListStore _listStore;
    private final String _noRowsMessage;
    private GridSelectionModel<GLRecord> _selectionModel;

    //--------------------------------------------------------------------------------------------------
    protected GLGridWidget(final String headingText, final String noRowsMessage) {
        super();
        _noRowsMessage = noRowsMessage == null ? "There are no results to display" : noRowsMessage;
        _listStore = new GLListStore();
        _checkBoxSet = new HashSet<ColumnConfig<GLRecord, ?>>();
        _gridColumnDefList = new ArrayList<GLGridColumnDef>();
        loadGridColumnDefList();
        createGridColumnDefMap();
        createContentPanel(headingText);
        createGrid();
        _contentPanel.add(_grid);
    }

    //--------------------------------------------------------------------------------------------------
    private void addHeaderContextMenuHandler() {
        final HeaderContextMenuHandler headerContextMenuHandler = new HeaderContextMenuHandler() {
            @Override
            public void onHeaderContextMenu(final HeaderContextMenuEvent headerContextMenuEvent) {
                MenuItem menuItem = new MenuItem("Size To Fit");
                menuItem.addSelectionHandler(new SelectionHandler<Item>() {
                    @Override
                    public void onSelection(final SelectionEvent<Item> selectionEvent) {
                        resizeColumnToFit(headerContextMenuEvent.getColumnIndex());
                        _grid.getView().refresh(true);
                    }
                });
                headerContextMenuEvent.getMenu().add(menuItem);
                menuItem = new MenuItem("Size All To Fit");
                menuItem.addSelectionHandler(new SelectionHandler<Item>() {
                    @Override
                    public void onSelection(final SelectionEvent<Item> selectionEvent) {
                        final ProgressMessageBox messageBox = new ProgressMessageBox("Size All Columns", //
                                "Resizing Columns...");
                        messageBox.setProgressText("Calculating...");
                        //          messageBox.setPredefinedButtons();
                        messageBox.show();
                        resizeNextColumn(messageBox, _selectionModel instanceof CheckBoxSelectionModel ? 1 : 0,
                                _grid.getColumnModel().getColumnCount() - 1);
                    }
                });
                headerContextMenuEvent.getMenu().add(menuItem);
            }
        };
        _grid.addHeaderContextMenuHandler(headerContextMenuHandler);
    }

    //--------------------------------------------------------------------------------------------------
    @Override
    public Widget asWidget() {
        return _contentPanel;
    }

    //--------------------------------------------------------------------------------------------------
    private void centerCheckBox(final ColumnConfig<GLRecord, ?> columnConfig) {
        final int leftPadding = (columnConfig.getWidth() - 12) / 2;
        final String styles = "padding: 3px 0px 0px " + leftPadding + "px;";
        final SafeStyles textStyles = SafeStylesUtils.fromTrustedString(styles);
        columnConfig.setColumnTextStyle(textStyles);
    }

    //--------------------------------------------------------------------------------------------------
    private void createCheckBoxSelectionModel() {
        final IdentityValueProvider<GLRecord> identityValueProvider;
        identityValueProvider = new IdentityValueProvider<GLRecord>();
        _selectionModel = new CheckBoxSelectionModel<GLRecord>(identityValueProvider) {
            @Override
            protected void onRefresh(final RefreshEvent event) {
                if (isSelectAllChecked()) {
                    selectAll();
                }
                super.onRefresh(event);
            }
        };
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnConfig<GLRecord, BigDecimal> createColumnConfigBigDecimal(final GLGridColumnDef gridColumnDef,
            final IGLColumn column) {
        final ColumnConfig<GLRecord, BigDecimal> result;
        final ValueProvider<GLRecord, BigDecimal> valueProvider;
        valueProvider = new GLBigDecimalValueProvider(column, column.getNumberOfDecimalPlaces());
        result = new ColumnConfig<GLRecord, BigDecimal>(valueProvider, gridColumnDef.getWidth(), //
                column.getTitle());
        result.setHorizontalAlignment(gridColumnDef.getHorizontalAlignment());
        NumberFormat numberFormat;
        if (column.getDataType() == EGLColumnDataType.Currency) {
            numberFormat = NumberFormat.getSimpleCurrencyFormat();
        } else {
            numberFormat = NumberFormat.getDecimalFormat();
        }
        result.setCell(new NumberCell<BigDecimal>(numberFormat));
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnConfig<GLRecord, Boolean> createColumnConfigBoolean(final GLGridColumnDef gridColumnDef,
            final IGLColumn column) {
        final ColumnConfig<GLRecord, Boolean> result;
        final ValueProvider<GLRecord, Boolean> valueProvider = new GLBooleanValueProvider(column);
        result = new ColumnConfig<GLRecord, Boolean>(valueProvider, gridColumnDef.getWidth(), //
                column.getTitle());
        result.setHorizontalAlignment(gridColumnDef.getHorizontalAlignment());
        result.setCell(new CheckBoxCell());
        result.setSortable(false);
        _checkBoxSet.add(result);
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnConfig<GLRecord, Date> createColumnConfigDateTime(final GLGridColumnDef gridColumnDef,
            final IGLColumn column, final String dateTimeFormat) {
        final ColumnConfig<GLRecord, Date> result;
        final ValueProvider<GLRecord, Date> valueProvider = new GLDateValueProvider(column);
        result = new ColumnConfig<GLRecord, Date>(valueProvider, gridColumnDef.getWidth(), //
                column.getTitle());
        result.setHorizontalAlignment(gridColumnDef.getHorizontalAlignment());
        final DateCell dateCell = new DateCell(DateTimeFormat.getFormat(dateTimeFormat));
        result.setCell(dateCell);
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnConfig<GLRecord, String> createColumnConfigForeignKey(final GLGridColumnDef gridColumnDef,
            final IGLColumn column) {
        final ColumnConfig<GLRecord, String> result;
        final ValueProvider<GLRecord, String> valueProvider = new GLForeignKeyValueProvider(column);
        result = new ColumnConfig<GLRecord, String>(valueProvider, gridColumnDef.getWidth(), //
                column.getTitle());
        result.setHorizontalAlignment(gridColumnDef.getHorizontalAlignment());
        result.setCell(new TextCell());
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnConfig<GLRecord, Integer> createColumnConfigInteger(final GLGridColumnDef gridColumnDef,
            final IGLColumn column) {
        final ColumnConfig<GLRecord, Integer> result;
        final ValueProvider<GLRecord, Integer> valueProvider = new GLIntegerValueProvider(column);
        result = new ColumnConfig<GLRecord, Integer>(valueProvider, gridColumnDef.getWidth(), //
                column.getTitle());
        result.setHorizontalAlignment(gridColumnDef.getHorizontalAlignment());
        result.setCell(new NumberCell<Integer>());
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnConfig<GLRecord, String> createColumnConfigString(final GLGridColumnDef gridColumnDef,
            final IGLColumn column) {
        final ColumnConfig<GLRecord, String> result;
        final ValueProvider<GLRecord, String> valueProvider = new GLStringValueProvider(column);
        result = new ColumnConfig<GLRecord, String>(valueProvider, gridColumnDef.getWidth(), //
                column.getTitle());
        result.setHorizontalAlignment(gridColumnDef.getHorizontalAlignment());
        result.setCell(new TextCell());
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private ColumnModel<GLRecord> createColumnModel() {
        ColumnModel<GLRecord> result;
        final ArrayList<ColumnConfig<GLRecord, ?>> columnConfigList;
        columnConfigList = new ArrayList<ColumnConfig<GLRecord, ?>>();
        if (_selectionModel instanceof CheckBoxSelectionModel) {
            columnConfigList.add(((CheckBoxSelectionModel<GLRecord>) _selectionModel).getColumn());
        }
        for (final GLGridColumnDef gridColumnDef : _gridColumnDefList) {
            ColumnConfig<GLRecord, ?> columnConfig = null;
            final IGLColumn column = gridColumnDef.getColumn();
            switch (column.getDataType()) {
            case Boolean:
                columnConfig = createColumnConfigBoolean(gridColumnDef, column);
                break;
            case Currency:
                columnConfig = createColumnConfigBigDecimal(gridColumnDef, column);
                break;
            case Date:
                columnConfig = createColumnConfigDateTime(gridColumnDef, column, "dd MMM yyyy");
                break;
            case DateTime:
                columnConfig = createColumnConfigDateTime(gridColumnDef, column, "dd MMM yyyy hh:mm a");
                break;
            case Decimal:
                columnConfig = createColumnConfigBigDecimal(gridColumnDef, column);
                break;
            case Int:
                if (column.getParentTable() == null) {
                    columnConfig = createColumnConfigInteger(gridColumnDef, column);
                } else {
                    columnConfig = createColumnConfigForeignKey(gridColumnDef, column);
                }
                break;
            case String:
                columnConfig = createColumnConfigString(gridColumnDef, column);
                break;
            }
            if (columnConfig != null) {
                gridColumnDef.setColumnConfig(columnConfig, columnConfigList.size());
                columnConfigList.add(columnConfig);
            }
        }
        result = new ColumnModel<GLRecord>(columnConfigList);
        result.addColumnWidthChangeHandler(new ColumnWidthChangeHandler() {
            @Override
            public void onColumnWidthChange(final ColumnWidthChangeEvent event) {
                final ColumnConfig<GLRecord, ?> columnConfig = columnConfigList.get(event.getIndex());
                if (_checkBoxSet.contains(columnConfig)) {
                    centerCheckBox(columnConfig);
                    _grid.getView().refresh(true);
                }
            }
        });
        for (final ColumnConfig<GLRecord, ?> columnConfig : _checkBoxSet) {
            centerCheckBox(columnConfig);
        }
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    private void createContentPanel(final String headingText) {
        _contentPanel = new ContentPanel();
        if (GLUtil.isBlank(headingText)) {
            _contentPanel.setHeaderVisible(false);
        } else {
            _contentPanel.setHeaderVisible(true);
            _contentPanel.setHeadingText(headingText);
        }
        _contentPanel.setButtonAlign(BoxLayoutPack.START);
        _contentPanel.addButton(new TextButton("Reset", new SelectHandler() {
            @Override
            public void onSelect(final SelectEvent event) {
                _listStore.rejectChanges();
            }
        }));
        _contentPanel.addButton(new TextButton("Save", new SelectHandler() {
            @Override
            public void onSelect(final SelectEvent event) {
                _listStore.commitChanges();
            }
        }));
        _contentPanel.addButton(createContentPanelDeleteButton());
        createContentPanelDeleteButton();
    }

    //--------------------------------------------------------------------------------------------------
    private TextButton createContentPanelDeleteButton() {
        return new TextButton("Delete Selected", new SelectHandler() {
            @Override
            public void onSelect(final SelectEvent selectEvent) {
                final List<GLRecord> selectedRecordList = _selectionModel.getSelectedItems();
                if (selectedRecordList.size() == 0) {
                    final AlertMessageBox messageBox;
                    messageBox = new AlertMessageBox("Delete Rows", "You haven't selected any rows to delete");
                    messageBox.show();
                    return;
                }
                final String rowMessage;
                if (selectedRecordList.size() == 1) {
                    rowMessage = "this row";
                } else {
                    rowMessage = "these " + selectedRecordList.size() + " rows";
                }
                final ConfirmMessageBox messageBox;
                messageBox = new ConfirmMessageBox("Delete Rows", //
                        "Are you sure you want to delete " + rowMessage + "?");
                messageBox.addDialogHideHandler(new DialogHideHandler() {
                    @Override
                    public void onDialogHide(final DialogHideEvent hideEvent) {
                        if (hideEvent.getHideButton() == PredefinedButton.YES) {
                            final ArrayList<GLRecord> recordList;
                            recordList = new ArrayList<GLRecord>(selectedRecordList.size());
                            for (final GLRecord record : selectedRecordList) {
                                recordList.add(record);
                            }
                            _listStore.remove(recordList);
                        }
                    }
                });
                messageBox.show();
            }
        });
    }

    //--------------------------------------------------------------------------------------------------
    @SuppressWarnings("unchecked")
    private void createEditors() {
        final GridEditing<GLRecord> gridEditing = new GridInlineEditing<GLRecord>(_grid);
        for (final GLGridColumnDef gridColumnDef : _gridColumnDefList) {
            final ColumnConfig<GLRecord, ?> columnConfig = gridColumnDef.getColumnConfig();
            final IGLColumn column = gridColumnDef.getColumn();
            switch (column.getDataType()) {
            case Boolean:
                // no editor is needed - the checkbox can be changed in place
                break;
            case Currency:
                gridEditing.addEditor((ColumnConfig<GLRecord, BigDecimal>) columnConfig, new BigDecimalField());
                break;
            case Date: {
                final DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("MM/dd/yyyy");
                final DateTimePropertyEditor propertyEditor = new DateTimePropertyEditor(dateTimeFormat);
                final DateField dateField = new DateField(propertyEditor);
                dateField.setClearValueOnParseError(false);
                gridEditing.addEditor((ColumnConfig<GLRecord, Date>) columnConfig, dateField);
                final IsField<Date> editor = gridEditing.getEditor(columnConfig);
                if (editor == null) {
                    GLUtil.initialize();
                }
                break;
            }
            case DateTime: {
                /*
                 * In 3, I'd probably start by making an Editor instance with two sub-editors, one DateField
                 * and one TimeField, each using @Path("") to have them bind to the same value.
                 * 
                 * Or make the new class implement IsField, and use setValue() and getValue() to modify/read
                 * both sub-editors.
                 * 
                 * IsField is what is being used in 3 to replace most MultiField cases - it allows a widget
                 * to supply methods that are helpful for most fields, and as it extends LeafValueEditor, it
                 * can be used in GWT Editor framework, and subfields will be ignored, leaving the dev to
                 * write their own logic for binding the values.
                 */
                final DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG);
                final DateTimePropertyEditor propertyEditor = new DateTimePropertyEditor(dateTimeFormat);
                final DateField dateField = new DateField(propertyEditor);
                dateField.setClearValueOnParseError(false);
                gridEditing.addEditor((ColumnConfig<GLRecord, Date>) columnConfig, dateField);
                break;
            }
            case Decimal:
                gridEditing.addEditor((ColumnConfig<GLRecord, BigDecimal>) columnConfig, new BigDecimalField());
                break;
            case Int:
                if (column.getParentTable() == null) {
                    gridEditing.addEditor((ColumnConfig<GLRecord, Integer>) columnConfig, new IntegerField());
                } else {
                    createEditorsForeignKeyCombobox(gridEditing, gridColumnDef);
                }
                break;
            case String:
                gridEditing.addEditor((ColumnConfig<GLRecord, String>) columnConfig, new TextField());
                break;
            }
        }
    }

    //--------------------------------------------------------------------------------------------------
    @SuppressWarnings("unchecked")
    private void createEditorsForeignKeyCombobox(final GridEditing<GLRecord> gridEditing,
            final GLGridColumnDef gridColumnDef) {
        final IGLColumn column = gridColumnDef.getColumn();
        final IGLLookupListStoreKey lookupListStoreKey = gridColumnDef.getLookupListStoreKey();
        final GLListStore lookupListStore = getLookupListStore(lookupListStoreKey);
        if (lookupListStore == null) {
            GLUtil.info(10, "Lookup list store not found for column:" + column + " key" + lookupListStoreKey);
            return;
        }
        final LabelProvider<GLRecord> labelProvider = new LabelProvider<GLRecord>() {
            @Override
            public String getLabel(final GLRecord record) {
                try {
                    return record.asString(column.getParentDisplayColumn());
                } catch (final GLInvalidFieldOrColumnException e) {
                    return "???";
                }
            }
        };
        final ComboBox<GLRecord> comboBox = new ComboBox<GLRecord>(lookupListStore, labelProvider);
        final Converter<String, GLRecord> converter = new Converter<String, GLRecord>() {
            @Override
            public GLRecord convertModelValue(final String displayValue) {
                return getRecordForLookupValue(lookupListStoreKey, displayValue);
            }

            @Override
            public String convertFieldValue(final GLRecord record) {
                return "Cat";
            }
        };
        gridEditing.addEditor((ColumnConfig<GLRecord, String>) gridColumnDef.getColumnConfig(), converter,
                comboBox);
    }

    //--------------------------------------------------------------------------------------------------
    private void createGrid() {
        createCheckBoxSelectionModel();
        final ColumnModel<GLRecord> columnModel = createColumnModel();
        _grid = new Grid<GLRecord>(_listStore, columnModel);
        _grid.addRowClickHandler(new RowClickEvent.RowClickHandler() {
            @Override
            public void onRowClick(final RowClickEvent event) {
                final Collection<Store<GLRecord>.Record> records = _listStore.getModifiedRecords();
                if (records.size() > 0) {
                    _grid.setBorders(false);
                }
            }
        });
        _grid.setBorders(true);
        _grid.setColumnReordering(true);
        _grid.setLoadMask(true);
        _grid.setSelectionModel(_selectionModel);
        _grid.setView(createGridView());
        addHeaderContextMenuHandler();
        createEditors();
    }

    //--------------------------------------------------------------------------------------------------
    private void createGridColumnDefMap() {
        _gridColumnDefMap = new TreeMap<String, GLGridColumnDef>();
        for (final GLGridColumnDef gridColumnDef : _gridColumnDefList) {
            _gridColumnDefMap.put(gridColumnDef.getColumn().toString(), gridColumnDef);
        }
    }

    //--------------------------------------------------------------------------------------------------
    private GridView<GLRecord> createGridView() {
        final GridView<GLRecord> result = new GridView<GLRecord>();
        result.setColumnLines(true);
        result.setEmptyText(_noRowsMessage);
        result.setForceFit(false);
        result.setStripeRows(true);
        return result;
    }

    //--------------------------------------------------------------------------------------------------
    public GLListStore getListStore() {
        return _listStore;
    }

    //--------------------------------------------------------------------------------------------------
    public GLListStore getLookupListStore(final IGLLookupListStoreKey lookupListStoreKey) {
        return null;
    }

    //--------------------------------------------------------------------------------------------------
    public GLRecord getRecordForLookupValue(final IGLLookupListStoreKey lookupListStoreKey, final String value) {
        return null;
    }

    //--------------------------------------------------------------------------------------------------
    protected abstract void loadGridColumnDefList();

    //--------------------------------------------------------------------------------------------------
    private void resizeColumnToFit(final int columnIndex) {
        final ColumnConfig<GLRecord, ?> columnConfig = _grid.getColumnModel().getColumn(columnIndex);
        final TextMetrics textMetrics = TextMetrics.get();
        textMetrics.bind(_grid.getView().getHeader().getAppearance().styles().head());
        int maxWidth = textMetrics.getWidth(columnConfig.getHeader().asString()) + 15; // extra is for the dropdown arrow
        if (_listStore.size() > 0) {
            textMetrics.bind(_grid.getView().getCell(0, 1));
            for (final GLRecord record : _listStore.getAll()) {
                final Object value = columnConfig.getValueProvider().getValue(record);
                if (value != null) {
                    String valueAsString;
                    if (columnConfig.getCell() instanceof DateCell) {
                        final DateCell dateCell = (DateCell) columnConfig.getCell();
                        final SafeHtmlBuilder sb = new SafeHtmlBuilder();
                        dateCell.render(null, (Date) value, sb);
                        valueAsString = sb.toSafeHtml().asString();
                    } else {
                        valueAsString = value.toString();
                    }
                    final int width = textMetrics.getWidth(valueAsString) + 12;
                    maxWidth = width > maxWidth ? width : maxWidth;
                }
            }
            for (final Store<GLRecord>.Record record : _listStore.getModifiedRecords()) {
                final int width = textMetrics.getWidth(record.getValue(columnConfig.getValueProvider()) //
                        .toString()) + 12;
                maxWidth = width > maxWidth ? width : maxWidth;
            }
        }
        columnConfig.setWidth(maxWidth);
        if (_checkBoxSet.contains(columnConfig)) {
            centerCheckBox(columnConfig);
        }
    }

    //--------------------------------------------------------------------------------------------------
    private void resizeNextColumn(final ProgressMessageBox messageBox, final int columnIndex,
            final int lastColumnIndex) {
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
            @Override
            public void execute() {
                resizeColumnToFit(columnIndex);
                if (columnIndex == lastColumnIndex) {
                    messageBox.hide();
                    _grid.getView().refresh(true);
                    return;
                }
                messageBox.updateProgress((double) columnIndex / (lastColumnIndex + 1), "{0}% Complete");
                resizeNextColumn(messageBox, columnIndex + 1, lastColumnIndex);
            }
        });
    }
    //--------------------------------------------------------------------------------------------------
}