de.instanttouch.ui.scaffolding.swt.viewer.lazy.SnakeLazyTableViewer.java Source code

Java tutorial

Introduction

Here is the source code for de.instanttouch.ui.scaffolding.swt.viewer.lazy.SnakeLazyTableViewer.java

Source

/*******************************************************************************
 *  Copyright (c) 2015 Joachim Tessmer.
 *  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:
 *      Joachim Tessmer - initial API and implementation
 *******************************************************************************/
package de.instanttouch.ui.scaffolding.swt.viewer.lazy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.forms.widgets.TableWrapData;

import de.instantouch.model.base.SnakeType;
import de.instantouch.model.domain.SnakeModel;
import de.instantouch.model.marker.SnakeHighlightMarker;
import de.instantouch.model.marker.SnakeMarker;
import de.instantouch.model.marker.SnakeMarker.eFontStyle;
import de.instantouch.model.marker.SnakeStateMarker;
import de.instantouch.model.marker.SnakeValidationMarker;
import de.instanttouch.ui.scaffolding.swt.util.SnakeSwtUtils;
import de.instanttouch.ui.scaffolding.swt.viewer.lazy.SnakeLazyTablePresenter.ColumnInfo;

public class SnakeLazyTableViewer extends TableViewer {
    protected SnakeLazyTablePresenter presenter = null;

    private TableColumnLayout tableColumnLayout;
    private Map<String, TableViewerColumn> columnMap = new HashMap<String, TableViewerColumn>();
    private StyledDataCellLabelProvider labelProvider;
    private GC gc;

    public class StyledDataCellLabelProvider extends StyledCellLabelProvider {

        @Override
        public void update(ViewerCell cell) {
            super.update(cell);

            Object element = cell.getElement();
            if (element instanceof SnakeModel) {

                SnakeModel model = (SnakeModel) element;

                SnakeType dataItem = null;
                String converted = "";

                // label provider
                int columnIndex = cell.getColumnIndex();

                if (columnIndex >= 0 && columnIndex < presenter.getVisibleColumns().size()) {
                    ColumnInfo info = presenter.getVisibleColumns().get(columnIndex);

                    TableViewerColumn viewerColumn = columnMap.get(info.getTitle());
                    if (viewerColumn != null) {
                        dataItem = model.findByName(info.getTitle());
                        if (dataItem != null) {
                            converted = handleTextOrImage(cell, dataItem, viewerColumn);
                        }
                    }
                }

                // coloring rows
                int rowIndex = presenter.indexOf(model);
                Color color = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
                if (rowIndex % 2 == 0) {
                    color = new Color(Display.getCurrent(), new RGB(250, 250, 230));// ORANGE
                }
                cell.setBackground(color);

                // using markers
                if (dataItem != null) {
                    for (SnakeMarker marker : dataItem.getConstraints().getMarker()) {

                        if (marker instanceof SnakeHighlightMarker) {
                            handleSelectMarker(cell, converted, marker);
                        } else if (marker instanceof SnakeValidationMarker) {
                            handleValidationMarker(cell, dataItem, marker);
                        } else if (marker instanceof SnakeStateMarker) {
                            handleStateMarker(cell, dataItem, marker);
                        }
                    }
                }

                super.update(cell);
            }
        }

        @Override
        protected void measure(Event event, Object element) {
            super.measure(event, element);

            if (true && element instanceof SnakeModel) {
                int lines = 0;
                SnakeModel model = (SnakeModel) element;

                for (ColumnInfo info : presenter.getVisibleColumns()) {
                    TableViewerColumn viewerColumn = columnMap.get(info.getTitle());
                    SnakeType dataCell = model.findByName(info.getTitle());
                    String converted = wrapText(dataCell.toString(), viewerColumn.getColumn().getWidth());
                    StringTokenizer tokenizer = new StringTokenizer(converted, "\n");
                    int count = tokenizer.countTokens();
                    lines = count > lines ? count : lines;

                }

                int height = lines * gc.getFontMetrics().getHeight();
                event.setBounds(new Rectangle(event.x, event.y, 0, height));
            }

        }

        @Override
        protected void paint(Event event, Object element) {
            super.paint(event, element);
        }

    }

    public SnakeLazyTableViewer(final SnakeLazyTablePresenter presenter, Composite parent, int style) {
        super(parent, style | SWT.VIRTUAL | SWT.FULL_SELECTION | SWT.WRAP);

        this.presenter = presenter;

        tableColumnLayout = new TableColumnLayout();
        // sparent.setLayout(tableColumnLayout);
        final Table table = getTable();

        TableWrapData wrapData = new TableWrapData();
        table.setLayoutData(wrapData);

        for (ColumnInfo column : presenter.getVisibleColumns()) {
            final TableViewerColumn viewerColumn = new TableViewerColumn(this, SWT.WRAP);

            viewerColumn.getColumn().setText(column.getTitle());
            viewerColumn.getColumn().setWidth(column.getWidth());
            viewerColumn.getColumn().setMoveable(true);
            viewerColumn.getColumn().setResizable(true);
            viewerColumn.getColumn().pack();

            ColumnLayoutData data = new ColumnPixelData(column.getWidth(), true);
            tableColumnLayout.setColumnData(viewerColumn.getColumn(), data);
            columnMap.put(column.getTitle(), viewerColumn);

            labelProvider = new StyledDataCellLabelProvider();
            viewerColumn.setLabelProvider(labelProvider);
            viewerColumn.getColumn().addSelectionListener(new SelectionAdapter() {

                @Override
                public void widgetSelected(SelectionEvent e) {

                    if (e.getSource() instanceof TableColumn) {
                        presenter.sort(((TableColumn) e.getSource()));
                    }
                }

            });
            viewerColumn.getColumn().addControlListener(new ControlListener() {

                @Override
                public void controlResized(ControlEvent e) {
                    presenter.columnChanged(viewerColumn.getColumn().getText(),
                            viewerColumn.getColumn().getWidth());
                }

                @Override
                public void controlMoved(ControlEvent e) {
                    // TODO Auto-generated method stub

                }
            });

        }

        setContentProvider(presenter);
        // setLabelProvider(new SnakeLabelProvider());//TODO use cell label
        // provider

        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        table.addMouseWheelListener(new MouseWheelListener() {

            @Override
            public void mouseScrolled(MouseEvent e) {

                if (table.getParent() instanceof ScrolledComposite) {

                    ScrolledComposite scrolledComposite = (ScrolledComposite) table.getParent();
                    Point origin = scrolledComposite.getOrigin();
                    int difY = e.count * 10;
                    scrolledComposite.setOrigin(origin.x, origin.y - difY);
                }
            }
        });

        gc = new GC(getTable());

    }

    public String layoutText(ViewerCell viewerCell, SnakeType cell, TableViewerColumn viewerColumn) {
        String converted = "";

        String text = cell.toString();
        int columnWidth = viewerColumn.getColumn().getWidth();

        // wrapping text
        if (text != null && text.length() > 0) {

            converted = wrapText(text, columnWidth);
            if (!viewerCell.getItem().isDisposed()) {
                viewerCell.setText(converted);
                viewerCell.getBounds().height = 100;
            }
        }

        return converted;
    }

    private String wrapText(String text, int columnWidth) {
        String converted = "";
        String line = "";

        StringTokenizer tokenizer = new StringTokenizer(text);
        String token = null;
        boolean start = true;

        while (tokenizer.hasMoreTokens()) {
            token = tokenizer.nextToken();

            // long token wrap
            Point extent = gc.textExtent(token);
            if (extent.x > columnWidth) {

                String devidedToken = token.substring(0, token.length() / 2);
                converted += devidedToken + "\n";
                token = token.substring(token.length() / 2);
            }

            // normal wrap
            extent = gc.textExtent(line + " " + token + "    ");
            if (extent.x > columnWidth) {
                converted += line + "\n";
                line = token;
            } else {

                if (!start) {
                    line += " ";
                }
                line += token;
                start = false;
            }
        }
        converted += line;
        return converted;
    }

    private String handleTextOrImage(final ViewerCell cell, SnakeType dataItem,
            final TableViewerColumn viewerColumn) {
        ColumnInfo info = presenter.getVisibleColumns().get(cell.getColumnIndex());

        String urlStr = dataItem.toString();
        Image image = SnakeSwtUtils.createImage(urlStr);
        if (image != null) {
            cell.setImage(image);
        }

        String converted = layoutText(cell, dataItem, viewerColumn);

        final SnakeType resizeCell = dataItem;
        viewerColumn.getColumn().addControlListener(new ControlListener() {

            @Override
            public void controlResized(ControlEvent e) {
                layoutText(cell, resizeCell, viewerColumn);
            }

            @Override
            public void controlMoved(ControlEvent e) {
            }
        });

        return converted;

    }

    private void handleStateMarker(ViewerCell cell, SnakeType dataItem, SnakeMarker marker) {
        SnakeStateMarker stateMarker = (SnakeStateMarker) marker;

        String backColorStr = stateMarker.getStateColor(dataItem);
        if (backColorStr != null) {
            Color stateBackground = SnakeSwtUtils.createFromHexString(backColorStr);
            cell.setBackground(stateBackground);
        }
    }

    private void handleValidationMarker(ViewerCell cell, SnakeType dataItem, SnakeMarker marker) {
        SnakeValidationMarker validationMarker = (SnakeValidationMarker) marker;
        if (!validationMarker.isValid(dataItem)) {

            String backColorStr = validationMarker.getBackgroundColor();
            Color validationBackground = SnakeSwtUtils.createFromHexString(backColorStr);

            cell.setBackground(validationBackground);
        }
    }

    private void handleSelectMarker(ViewerCell cell, String converted, SnakeMarker marker) {
        List<StyleRange> ranges = new ArrayList<StyleRange>();

        SnakeHighlightMarker selector = (SnakeHighlightMarker) marker;
        String colorStr = selector.getForegroundColor();
        Color textColor = SnakeSwtUtils.createFromHexString(colorStr);

        String backColorStr = selector.getBackgroundColor();
        Color markerBackground = SnakeSwtUtils.createFromHexString(backColorStr);

        StringTokenizer tokenizer = new StringTokenizer(converted);
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (selector.match(token)) {
                int index = converted.indexOf(token);
                if (index >= 0) {
                    int fontStyle = SWT.NORMAL;
                    if (selector.getFontStyle() == eFontStyle.bold) {
                        fontStyle = SWT.BOLD;
                    } else if (selector.getFontStyle() == eFontStyle.italic) {
                        fontStyle = SWT.ITALIC;
                    }

                    FontData fontData = new FontData(selector.getFontFamily(), selector.getFontSize(), fontStyle);
                    Font font = new Font(getControl().getDisplay(), fontData);

                    StyleRange myStyledRange = new StyleRange(index, token.length(), textColor, markerBackground,
                            fontStyle);
                    myStyledRange.font = font;

                    ranges.add(myStyledRange);
                }
            }
        }

        if (ranges.size() > 0) {
            StyleRange[] collected = new StyleRange[ranges.size()];
            for (int i = 0; i < ranges.size(); i++) {
                StyleRange range = ranges.get(i);
                collected[i] = range;
            }
            cell.setStyleRanges(collected);
        }
    }
}