org.anstis.client.grid.widget.GridShowcaseWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.anstis.client.grid.widget.GridShowcaseWidget.java

Source

/*
 * Copyright 2015 JBoss Inc
 *
 * 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.
 */
package org.anstis.client.grid.widget;

import java.util.HashMap;
import java.util.Map;

import com.ait.lienzo.client.core.event.NodeMouseClickEvent;
import com.ait.lienzo.client.core.event.NodeMouseClickHandler;
import com.ait.lienzo.client.core.mediator.MousePanMediator;
import com.ait.lienzo.client.core.shape.Group;
import com.ait.lienzo.client.core.shape.Text;
import com.ait.lienzo.client.core.types.Point2D;
import com.ait.lienzo.client.core.types.Transform;
import com.ait.lienzo.client.widget.LienzoPanel;
import com.ait.lienzo.shared.core.types.ColorName;
import com.ait.lienzo.shared.core.types.TextAlign;
import com.ait.lienzo.shared.core.types.TextBaseLine;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import org.anstis.client.grid.model.BaseGridCellValue;
import org.anstis.client.grid.model.ICallback;
import org.anstis.client.grid.model.IGridCellValue;
import org.anstis.client.grid.model.IGridColumn;
import org.anstis.client.grid.model.IGridData;
import org.anstis.client.grid.model.basic.GridCell;
import org.anstis.client.grid.model.basic.GridColumn;
import org.anstis.client.grid.model.basic.GridData;
import org.anstis.client.grid.model.basic.GridRow;
import org.anstis.client.grid.model.mergable.MergableGridCell;
import org.anstis.client.grid.model.mergable.MergableGridColumn;
import org.anstis.client.grid.model.mergable.MergableGridData;
import org.anstis.client.grid.util.GridDataFactory;
import org.anstis.client.grid.widget.basic.GridWidget;
import org.anstis.client.grid.widget.context.GridCellRenderContext;
import org.anstis.client.grid.widget.dom.CheckBoxDOMElement;
import org.anstis.client.grid.widget.dom.CheckBoxDOMElementFactory;
import org.anstis.client.grid.widget.dom.TextBoxDOMElement;
import org.anstis.client.grid.widget.dom.TextBoxDOMElementFactory;
import org.anstis.client.grid.widget.dom.TextBoxSingletonDOMElementFactory;
import org.anstis.client.grid.widget.edit.EditorPopup;
import org.anstis.client.grid.widget.mergable.MergableGridWidget;
import org.anstis.client.grid.widget.renderers.IGridRenderer;
import org.anstis.client.grid.widget.renderers.basic.BlueGridRenderer;
import org.anstis.client.grid.widget.renderers.basic.GreenGridRenderer;
import org.anstis.client.grid.widget.renderers.basic.RedGridRenderer;
import org.anstis.client.grid.widget.renderers.mergable.MergableGridRenderer;
import org.gwtbootstrap3.client.ui.CheckBox;
import org.gwtbootstrap3.client.ui.ListBox;
import org.gwtbootstrap3.extras.slider.client.ui.Slider;

/**
 * Showcase/hack-fest for GridWidgets.
 */
public class GridShowcaseWidget extends Composite implements ISelectionManager {

    public static final int VP_WIDTH = 1200;
    public static final int VP_HEIGHT = 600;

    private static final double VP_SCALE = 1.0;

    private static final int GRID1_ROWS = 100;
    private static final int GRID2_ROWS = 100;
    private static final int GRID3_ROWS = 100;
    private static final int GRID4_ROWS = 100;

    interface GridShowcaseWidgetUiBinder extends UiBinder<Widget, GridShowcaseWidget> {

    }

    private static GridShowcaseWidgetUiBinder uiBinder = GWT.create(GridShowcaseWidgetUiBinder.class);

    @UiField
    AbsolutePanel domElementContainer;

    @UiField
    Slider slider;

    @UiField
    ListBox basicRendererSelector;

    @UiField
    CheckBox chkShowMerged;

    private final EditorPopup editor = new EditorPopup();

    private GridLayer gridLayer = new GridLayer();
    private LienzoPanel gridPanel = new LienzoPanel(VP_WIDTH, VP_HEIGHT);

    public GridShowcaseWidget() {
        initWidget(uiBinder.createAndBindUi(this));
        setup();
    }

    private void setup() {
        //Lienzo stuff - Set default scale
        final Transform transform = new Transform().scale(VP_SCALE);
        gridPanel.getViewport().setTransform(transform);

        //Lienzo stuff - Add mouse pan support
        final MousePanMediator mediator1 = new MousePanMediator();
        gridPanel.getViewport().getMediators().push(mediator1);

        //Wire-up widgets
        gridPanel.add(gridLayer);
        domElementContainer.add(gridPanel);

        gridLayer.addNodeMouseClickHandler(new NodeMouseClickHandler() {
            @Override
            public void onNodeMouseClick(NodeMouseClickEvent nodeMouseClickEvent) {
                gridPanel.setFocus(true);
            }
        });

        //Grid 1
        final MergableGridData grid1 = new MergableGridData();
        final MergableGridWidget gridWidget1 = new MergableGridWidget(grid1, this, new MergableGridRenderer());
        for (int idx = 0; idx < 10; idx++) {
            final int grid1ColumnGroupSuffix = (idx < 5 ? 0 : 1);
            final Double minimumColumnWidth = (idx == 1 ? 75.0 : 100.0);
            final Double maximumColumnWidth = (idx == 1 ? 200.0 : null);
            final MergableGridColumn<String> grid1Column = new MergableGridColumn<String>(
                    "G1-G" + grid1ColumnGroupSuffix + "-C" + idx, minimumColumnWidth) {
                @Override
                public void renderCell(final Group g, final MergableGridCell<String> cell,
                        final GridCellRenderContext context) {
                    final Text t = new Text(cell.getValue().getValue()).setFillColor(ColorName.GREY).setFontSize(12)
                            .setFontFamily("serif").setListening(false).setTextBaseLine(TextBaseLine.MIDDLE)
                            .setTextAlign(TextAlign.CENTER).setX(context.getWidth() / 2)
                            .setY(context.getHeight() / 2);
                    g.add(t);
                }

                @Override
                public void edit(final MergableGridCell<String> cell, final GridCellRenderContext context,
                        final ICallback<IGridCellValue<String>> callback) {
                    editor.edit(cell == null ? null : cell.getValue(), callback);
                }

                @Override
                public String getColumnGroup() {
                    return "grid1ColumnGroup" + grid1ColumnGroupSuffix;
                }

                @Override
                public Double getMinimumColumnWidth() {
                    return minimumColumnWidth;
                }

                @Override
                public Double getMaximumColumnWidth() {
                    return maximumColumnWidth;
                }
            };
            grid1.appendColumn(grid1Column);
        }
        GridDataFactory.populate(grid1, GRID1_ROWS);

        //Grid 2
        final MergableGridData grid2 = new MergableGridData();
        final MergableGridWidget gridWidget2 = new MergableGridWidget(grid2, this, new MergableGridRenderer());
        for (int idx = 0; idx < 5; idx++) {
            final MergableGridColumn<String> grid2Column = new MergableGridColumn<String>("G2-G0-C" + idx, 150) {
                @Override
                public void renderCell(final Group g, final MergableGridCell<String> cell,
                        final GridCellRenderContext context) {
                    final Text t = new Text(cell.getValue().getValue()).setFillColor(ColorName.GREY).setFontSize(12)
                            .setFontFamily("serif").setListening(false).setTextBaseLine(TextBaseLine.MIDDLE)
                            .setTextAlign(TextAlign.CENTER).setX(context.getWidth() / 2)
                            .setY(context.getHeight() / 2);
                    g.add(t);
                }

                @Override
                public void edit(final MergableGridCell<String> cell, final GridCellRenderContext context,
                        final ICallback<IGridCellValue<String>> callback) {
                    editor.edit(cell == null ? null : cell.getValue(), callback);
                }

            };
            grid2.appendColumn(grid2Column);
        }
        GridDataFactory.populate(grid2, GRID2_ROWS);

        //Grid 3
        final MergableGridData grid3 = new MergableGridData();
        final MergableGridWidget gridWidget3 = new MergableGridWidget(grid3, this, new MergableGridRenderer());
        for (int idx = 0; idx < 2; idx++) {
            final boolean isResizeable = idx != 1;
            final boolean isMoveable = idx != 1;
            final MergableGridColumn<String> grid3Column = new MergableGridColumn<String>("G3-G0-C" + idx, 100) {
                @Override
                public void renderCell(final Group g, final MergableGridCell<String> cell,
                        final GridCellRenderContext context) {
                    final Text t = new Text(cell.getValue().getValue()).setFillColor(ColorName.GREY).setFontSize(12)
                            .setFontFamily("serif").setListening(false).setTextBaseLine(TextBaseLine.MIDDLE)
                            .setTextAlign(TextAlign.CENTER).setX(context.getWidth() / 2)
                            .setY(context.getHeight() / 2);
                    g.add(t);
                }

                @Override
                public void edit(final MergableGridCell<String> cell, final GridCellRenderContext context,
                        final ICallback<IGridCellValue<String>> callback) {
                    editor.edit(cell == null ? null : cell.getValue(), callback);
                }

                @Override
                public boolean isResizable() {
                    return isResizeable;
                }

                @Override
                public boolean isMoveable() {
                    return isMoveable;
                }

            };
            grid3.appendColumn(grid3Column);
        }
        GridDataFactory.populate(grid3, GRID3_ROWS);

        //Grid 3 - DOM Column - TextBox (Lazy show)
        final String grid3ColumnGroup1 = "grid3ColumnGroup1";
        final MergableGridColumn<String> grid3Column2 = new MergableGridColumn<String>("G3-G1-C2", 100) {

            private TextBoxSingletonDOMElementFactory factory = new TextBoxSingletonDOMElementFactory(gridLayer,
                    gridWidget3, domElementContainer);

            @Override
            public void renderCell(final Group g, final MergableGridCell<String> cell,
                    final GridCellRenderContext context) {
                final Text t = new Text(cell.getValue().getValue()).setFillColor(ColorName.GREY).setFontSize(12)
                        .setFontFamily("serif").setListening(false).setTextBaseLine(TextBaseLine.MIDDLE)
                        .setTextAlign(TextAlign.CENTER).setX(context.getWidth() / 2).setY(context.getHeight() / 2);
                g.add(t);
            }

            @Override
            public void edit(final MergableGridCell<String> cell, final GridCellRenderContext context,
                    final ICallback<IGridCellValue<String>> callback) {
                factory.initialiseDomElement(cell, context, new ICallback<TextBoxDOMElement>() {
                    @Override
                    public void callback(final TextBoxDOMElement e) {
                        e.attach();
                        e.getWidget().setFocus(true);
                    }
                });
            }

            @Override
            public void initialiseResources() {
                factory.initialiseResources();
            }

            @Override
            public void destroyResources() {
                factory.destroyResources();
            }

            @Override
            public void freeUnusedResources() {
                factory.freeUnusedResources();
            }

            @Override
            public String getColumnGroup() {
                return grid3ColumnGroup1;
            }

        };
        grid3.appendColumn(grid3Column2);
        for (int rowIndex = 0; rowIndex < GRID4_ROWS; rowIndex++) {
            grid3.setCell(rowIndex, 2, new BaseGridCellValue<>("(" + 2 + ", " + rowIndex + ")"));
        }

        //Grid 3 - DOM Column - CheckBox
        final MergableGridColumn<Boolean> grid3Column3 = new MergableGridColumn<Boolean>("G3-G1-C3", 100) {

            private CheckBoxDOMElementFactory factory = new CheckBoxDOMElementFactory(gridLayer, gridWidget3,
                    domElementContainer);

            @Override
            public void renderCell(final Group g, final MergableGridCell<Boolean> cell,
                    final GridCellRenderContext context) {
                factory.initialiseDomElement(cell, context, new ICallback<CheckBoxDOMElement>() {
                    @Override
                    public void callback(final CheckBoxDOMElement e) {
                        e.attach();
                    }
                });
            }

            @Override
            public void initialiseResources() {
                factory.initialiseResources();
            }

            @Override
            public void destroyResources() {
                factory.destroyResources();
            }

            @Override
            public void freeUnusedResources() {
                factory.freeUnusedResources();
            }

            @Override
            public String getColumnGroup() {
                return grid3ColumnGroup1;
            }

        };
        grid3.appendColumn(grid3Column3);
        for (int rowIndex = 0; rowIndex < GRID4_ROWS; rowIndex++) {
            grid3.setCell(rowIndex, 3, new BaseGridCellValue<>(Math.random() < GridDataFactory.FILL_FACTOR));
        }

        //Grid 3 - DOM Column - TextBox
        final MergableGridColumn<String> grid3Column4 = new MergableGridColumn<String>("G3-G1-C4", 100) {

            private TextBoxDOMElementFactory factory = new TextBoxDOMElementFactory(gridLayer, gridWidget3,
                    domElementContainer);

            @Override
            public void renderCell(final Group g, final MergableGridCell<String> cell,
                    final GridCellRenderContext context) {
                factory.initialiseDomElement(cell, context, new ICallback<TextBoxDOMElement>() {
                    @Override
                    public void callback(final TextBoxDOMElement e) {
                        e.attach();
                    }
                });
            }

            @Override
            public void initialiseResources() {
                factory.initialiseResources();
            }

            @Override
            public void destroyResources() {
                factory.destroyResources();
            }

            @Override
            public void freeUnusedResources() {
                factory.freeUnusedResources();
            }

            @Override
            public String getColumnGroup() {
                return grid3ColumnGroup1;
            }

        };
        grid3.appendColumn(grid3Column4);
        for (int rowIndex = 0; rowIndex < GRID4_ROWS; rowIndex++) {
            if (Math.random() < GridDataFactory.FILL_FACTOR) {
                grid3.setCell(rowIndex, 4, new BaseGridCellValue<>("(" + 4 + ", " + rowIndex + ")"));
            }
        }

        //Grid 4
        final GridData grid4 = new GridData();
        final GridWidget gridWidget4 = new GridWidget(grid4, this, new RedGridRenderer());

        //Grid 4 - DOM Column - TextBox
        final GridColumn<String> grid4Column1 = new GridColumn<String>("G4-G0-C0", 100) {

            @Override
            public void renderCell(final Group g, final GridCell<String> cell,
                    final GridCellRenderContext context) {
                final Text t = new Text(cell.getValue().getValue()).setFillColor(ColorName.GREY).setFontSize(12)
                        .setFontFamily("serif").setListening(false).setTextBaseLine(TextBaseLine.MIDDLE)
                        .setTextAlign(TextAlign.CENTER).setX(context.getWidth() / 2).setY(context.getHeight() / 2);
                g.add(t);
            }

            @Override
            public void edit(final GridCell<String> cell, final GridCellRenderContext context,
                    final ICallback<IGridCellValue<String>> callback) {
                editor.edit(cell == null ? null : cell.getValue(), callback);
            }

        };
        grid4.appendColumn(grid4Column1);

        //Grid 4 - DOM Column - CheckBox
        final GridColumn<Boolean> grid4Column2 = new GridColumn<Boolean>("G4-G0-C1", 100) {

            private CheckBoxDOMElementFactory factory = new CheckBoxDOMElementFactory(gridLayer, gridWidget4,
                    domElementContainer);

            @Override
            public void renderCell(final Group g, final GridCell<Boolean> cell,
                    final GridCellRenderContext context) {
                factory.initialiseDomElement(cell, context, new ICallback<CheckBoxDOMElement>() {
                    @Override
                    public void callback(final CheckBoxDOMElement e) {
                        e.attach();
                    }
                });
            }

            @Override
            public void initialiseResources() {
                factory.initialiseResources();
            }

            @Override
            public void destroyResources() {
                factory.destroyResources();
            }

            @Override
            public void freeUnusedResources() {
                factory.freeUnusedResources();
            }

        };
        grid4.appendColumn(grid4Column2);

        for (int rowIndex = 0; rowIndex < GRID4_ROWS; rowIndex++) {
            final GridRow row = new GridRow();
            grid4.appendRow(row);
            for (int columnIndex = 0; columnIndex < grid4.getColumns().size(); columnIndex++) {
                switch (columnIndex) {
                case 0:
                    grid4.setCell(rowIndex, columnIndex,
                            new BaseGridCellValue<>("(" + columnIndex + ", " + rowIndex + ")"));
                    break;
                case 1:
                    grid4.setCell(rowIndex, columnIndex, new BaseGridCellValue<>(Math.random() < 0.5));
                    break;
                }
            }
        }

        //Link grids
        grid1.getColumns().get(9).setLink(grid2.getColumns().get(0));
        grid2.getColumns().get(3).setLink(grid3.getColumns().get(0));
        grid3.getColumns().get(0).setLink(grid1.getColumns().get(0));

        //Add Widgets to the Layer
        gridWidget1.setLocation(new Point2D(-1300, 0));
        gridWidget2.setLocation(new Point2D(0, 750));
        gridWidget3.setLocation(new Point2D(1050, 0));
        gridWidget4.setLocation(new Point2D(1800, 0));
        gridLayer.add(gridWidget1);
        gridLayer.add(gridWidget2);
        gridLayer.add(gridWidget3);
        gridLayer.add(gridWidget4);

        //Slider
        slider.setValue(VP_SCALE * 100);
        slider.addValueChangeHandler(new ValueChangeHandler<Double>() {

            private double m_currentZoom = 1.0;

            @Override
            public void onValueChange(final ValueChangeEvent<Double> event) {
                final double pct = event.getValue();
                final int compare = Double.compare(m_currentZoom, pct);
                if (compare == 0) {
                    return;
                }
                m_currentZoom = pct;

                final Transform transform = new Transform();
                final double tx = gridPanel.getViewport().getTransform().getTranslateX();
                final double ty = gridPanel.getViewport().getTransform().getTranslateY();
                transform.translate(tx, ty);
                transform.scale(m_currentZoom / 100);

                gridPanel.getViewport().setTransform(transform);
                gridPanel.getViewport().draw();
            }

        });

        //Style selectors
        final Map<String, IGridRenderer<GridData>> basicRenderers = new HashMap<>();
        final RedGridRenderer redRenderer = new RedGridRenderer();
        final GreenGridRenderer greenRenderer = new GreenGridRenderer();
        final BlueGridRenderer blueRenderer = new BlueGridRenderer();
        basicRenderers.put(redRenderer.getName(), redRenderer);
        basicRenderers.put(greenRenderer.getName(), greenRenderer);
        basicRenderers.put(blueRenderer.getName(), blueRenderer);
        for (String name : basicRenderers.keySet()) {
            basicRendererSelector.addItem(name);
        }
        basicRendererSelector.addChangeHandler(new ChangeHandler() {
            @Override
            @SuppressWarnings("unused")
            public void onChange(final ChangeEvent event) {
                final IGridRenderer<GridData> renderer = basicRenderers
                        .get(basicRendererSelector.getItemText(basicRendererSelector.getSelectedIndex()));
                gridWidget4.setRenderer(renderer);
                gridLayer.draw();
            }
        });

        //Merged indicator
        chkShowMerged.setValue(grid1.isMerged());
        chkShowMerged.addChangeHandler(new ChangeHandler() {
            @Override
            @SuppressWarnings("unused")
            public void onChange(final ChangeEvent event) {
                grid1.setMerged(chkShowMerged.getValue());
                grid2.setMerged(chkShowMerged.getValue());
                grid3.setMerged(chkShowMerged.getValue());
                gridLayer.draw();
            }
        });

        //Prevent DOMElements scrolling into view when they receive the focus
        domElementContainer.addDomHandler(new ScrollHandler() {

            @Override
            public void onScroll(ScrollEvent scrollEvent) {
                domElementContainer.getElement().setScrollTop(0);
                domElementContainer.getElement().setScrollLeft(0);
            }
        }, ScrollEvent.getType());
    }

    @Override
    public void select(final IGridData<?, ?, ?> selectable) {
        gridLayer.select(selectable);
    }

    @Override
    public void selectLinkedColumn(final IGridColumn<?, ?> link) {
        gridLayer.selectLinkedColumn(link);
    }

}