au.gov.ansto.bragg.kakadu.ui.plot.SchemaPlotComposite.java Source code

Java tutorial

Introduction

Here is the source code for au.gov.ansto.bragg.kakadu.ui.plot.SchemaPlotComposite.java

Source

/*******************************************************************************
 * Copyright (c) 2007 Australian Nuclear Science and Technology Organisation.
 * 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:
 *     Danil Klimontov (Bragg Institute) - initial API and implementation
 *******************************************************************************/
package au.gov.ansto.bragg.kakadu.ui.plot;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.gumtree.data.Factory;
import org.gumtree.data.exception.SignalNotAvailableException;
import org.gumtree.data.impl.netcdf.NcGroup;
import org.gumtree.data.interfaces.IArray;
import org.gumtree.data.interfaces.IArrayIterator;
import org.gumtree.data.interfaces.IGroup;
import org.gumtree.data.interfaces.IIndex;

import au.gov.ansto.bragg.datastructures.core.plot.Data;

/**
 * The widget displays data as key-value pairs in a table.
 * 
 * @author Danil Klimontov (dak)
 */
public class SchemaPlotComposite extends Composite {
    private final Plot plot;
    private TableViewer viewer;
    private TableColumn keyTableColumn;
    private TableColumn valueTableColumn;
    private TableColumn errorTableColumn;
    private TableViewerSorter tableViewerSorter;
    private final SortSelectionListener sortSelectionListener = new SortSelectionListener();
    private final List<TableColumn> tableColumns = new ArrayList<TableColumn>();

    /**
     * Table data model.
     */
    private List<List<SchemaDataItem>> dataItemsList = new ArrayList<List<SchemaDataItem>>();

    /**
     * Creates a new <code>SchemaPlotComposite</code> instance.
     * @param parent parent Composite
     * @param style SWT stile
     * @param plot Plot reference
     */
    public SchemaPlotComposite(Composite parent, int style, Plot plot) {
        super(parent, style);
        this.plot = plot;
        initialise();
    }

    private void initialise() {
        setLayout(new FillLayout());

        viewer = new TableViewer(this, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);

        keyTableColumn = new TableColumn(viewer.getTable(), SWT.NONE);
        keyTableColumn.setText("Key");
        keyTableColumn.setWidth(100);
        tableColumns.add(keyTableColumn);
        keyTableColumn.addListener(SWT.Selection, sortSelectionListener);

        valueTableColumn = new TableColumn(viewer.getTable(), SWT.NONE);
        valueTableColumn.setText("Value");
        valueTableColumn.setWidth(100);
        tableColumns.add(valueTableColumn);
        valueTableColumn.addListener(SWT.Selection, sortSelectionListener);

        errorTableColumn = new TableColumn(viewer.getTable(), SWT.NONE);
        errorTableColumn.setText("Error");
        errorTableColumn.setWidth(100);
        tableColumns.add(errorTableColumn);
        errorTableColumn.addListener(SWT.Selection, sortSelectionListener);

        viewer.setContentProvider(new SchemaListContentProvider());
        viewer.setLabelProvider(new SchemaLabelProvider());
        tableViewerSorter = new TableViewerSorter();
        viewer.setSorter(tableViewerSorter);
        viewer.getTable().setHeaderVisible(true);
        viewer.getTable().setLinesVisible(true);

        viewer.setInput(dataItemsList);
    }

    private int getColumnIndex(TableColumn column) {
        return tableColumns.indexOf(column);
    }

    /**
     * Sets the data to be displayed in table. 
     * @param plotData 
     */
    public void setSchemaData(Object plotData) {

        clearData();
        final ArrayList<String> columnNames = new ArrayList<String>();

        if (plotData != null && plotData instanceof IGroup) {
            IGroup group = (IGroup) plotData;

            IArray array = null;
            IArray varianceArray = null;
            List<IArray> axesArrayList = null;
            try {
                array = ((NcGroup) group).getSignalArray();
                axesArrayList = ((NcGroup) group).getAxesArrayList();
            } catch (SignalNotAvailableException e) {
                plot.handleException(e);
                return;
            }

            try {
                varianceArray = ((au.gov.ansto.bragg.datastructures.core.plot.Plot) group).findVarianceArray();
            } catch (Exception e) {
            }

            int[] shape = array.getShape();
            int rank = array.getRank();
            Class<?> type = array.getElementType();
            IIndex index = array.getIndex();

            if (rank == 1) {
                //get X Axis array info
                final IArray xAxisArray = axesArrayList.get(0);
                final Class<?> xAxisType = xAxisArray.getElementType();
                final int[] xAxisShape = xAxisArray.getShape();
                final IIndex xAxisIndex = Factory.createIndex(xAxisShape);

                //add columns
                columnNames.add("X");
                columnNames.add("Y");

                if (varianceArray == null) {
                    for (int i = 0; i < shape[0]; i++) {
                        //extract value
                        index.set(i);
                        Object value = array.getObject(index);

                        //extract X Axis info
                        xAxisIndex.set(i);
                        Object xAxisValue = xAxisArray.getObject(xAxisIndex);

                        //add data items to table model
                        List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
                        dataItemsList.add(rowList);
                        rowList.add(new SchemaDataItem(i, 0, xAxisValue, xAxisType, value, type, xAxisValue,
                                xAxisType));
                        rowList.add(new SchemaDataItem(i, 1, xAxisValue, xAxisType, value, type, value, type));

                    }
                } else {
                    columnNames.add("Sigma");
                    for (int i = 0; i < shape[0]; i++) {
                        //extract value
                        index.set(i);
                        Object value = array.getObject(index);

                        Object variance = varianceArray.getObject(index);
                        double error = Double.NaN;
                        try {
                            error = Math.sqrt(Double.valueOf(variance.toString()));
                        } catch (Exception e) {
                        }

                        //extract X Axis info
                        xAxisIndex.set(i);
                        Object xAxisValue = xAxisArray.getObject(xAxisIndex);

                        //add data items to table model
                        List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
                        dataItemsList.add(rowList);
                        rowList.add(new SchemaDataItem(i, 0, xAxisValue, xAxisType, value, type, xAxisValue,
                                xAxisType));
                        rowList.add(new SchemaDataItem(i, 1, xAxisValue, xAxisType, value, type, value, type));
                        rowList.add(
                                new SchemaDataItem(i, 2, xAxisValue, xAxisType, value, type, error, Double.TYPE));
                    }
                }
            } else if (rank == 2) {

                //First column for Y Axis values
                columnNames.add("Y");

                //get X Axis array info
                final IArray xAxisArray = axesArrayList.get(1);
                final Class<?> xAxisType = xAxisArray.getElementType();
                final int[] xAxisShape = xAxisArray.getShape();
                final IIndex xAxisIndex = Factory.createIndex(xAxisShape);

                List<Object> xAxisValueList = new ArrayList<Object>();

                //get Y Axis array info
                final IArray yAxisArray = axesArrayList.get(0);
                final Class<?> yAxisType = yAxisArray.getElementType();
                final int[] yAxisShape = yAxisArray.getShape();
                final IIndex yAxisIndex = Factory.createIndex(yAxisShape);

                for (int i = 0; i < shape[0]; i++) {
                    index.set(i);

                    //extract Y Axis info
                    yAxisIndex.set(i);
                    Object yAxisValue = yAxisArray.getObject(yAxisIndex);

                    List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
                    dataItemsList.add(rowList);
                    //Y Axis value for first column in the table
                    rowList.add(new SchemaDataItem(i, 0, null, xAxisType, yAxisValue, yAxisType,
                            "Y:" + getString(yAxisValue, yAxisType), String.class));

                    for (int j = 0; j < shape[1]; j++) {
                        index.set1(j);
                        Object value = array.getObject(index);

                        if (i == 0) {
                            //extract X Axis info
                            xAxisIndex.set(j);
                            Object xAxisValue = xAxisArray.getObject(xAxisIndex);
                            xAxisValueList.add(xAxisValue);

                            //create column title with X Axis value
                            columnNames.add("X:" + getString(xAxisValue, xAxisType));
                        }

                        rowList.add(new SchemaDataItem(i, j + 1, xAxisValueList.get(j), xAxisType, yAxisValue,
                                yAxisType, value, type));
                    }
                }

            } else {
                plot.handleException(new IllegalArgumentException(
                        "Not possible to create schema for the data object. Rank = " + rank));
                return;
            }

        }

        //1D data
        //      double[] xAxis = new double[15];
        //      double[] data = new double[xAxis.length];
        //      columnNames.add("X");
        //      columnNames.add("Y");
        //      
        //      for (int i = 0; i < xAxis.length; i++) {
        //         xAxis[i] = i;
        //
        //         List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
        //         dataItemsList.add(rowList);
        //         rowList.add(new SchemaDataItem(i, 0, xAxis[i], 0, xAxis[i]));
        //         
        //         final double value = data[i] = i * 10;
        //         rowList.add(new SchemaDataItem(i, 0, xAxis[i], 0, value));
        //      }

        //2D data
        //      double[] xAxis = new double[15];
        //      double[] yAxis = new double[7];
        //      double[][] data = new double[xAxis.length][yAxis.length];
        //      columnNames.add("Y \\ X");
        //      
        //      for (int j = 0; j < yAxis.length; j++) {
        //         yAxis[j] = j;
        //
        //         List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
        //         dataItemsList.add(rowList);
        //         rowList.add(new SchemaDataItem(0, j, 0, yAxis[j], yAxis[j]));
        //         
        //         for (int i = 0; i < xAxis.length; i++) {
        //            xAxis[i] = i;
        //            if (j == 0) {
        //               columnNames.add("X:" + String.valueOf(xAxis[i]));
        //            }
        //            final double value = data[i][j] = i * j;
        //            rowList.add(new SchemaDataItem(i + 1, j, xAxis[i], yAxis[j], value));
        //         }
        //      }

        updateColumns(columnNames);

        viewer.refresh();
    }

    /**
     * Sets the data to be displayed in table. 
     * @param plotData 
     */
    public void setMataDataSchema(Object plotData) {

        clearData();
        final ArrayList<String> columnNames = new ArrayList<String>();
        columnNames.add("Name");
        columnNames.add("Value");

        if (plotData != null && plotData instanceof au.gov.ansto.bragg.datastructures.core.plot.Plot) {
            au.gov.ansto.bragg.datastructures.core.plot.Plot group = (au.gov.ansto.bragg.datastructures.core.plot.Plot) plotData;

            List<Data> dataList = group.getCalculationData();
            int rowIndex = 0;
            boolean isFirstRow = true;
            for (Data data : dataList) {
                IArray array = null;
                String dataName = data.getTitle();
                if (dataName == null)
                    dataName = data.getShortName();
                try {
                    array = data.getData();
                } catch (Exception e) {
                    plot.handleException(e);
                    return;
                }

                int[] shape = array.getShape();
                int rank = array.getRank();
                Class<?> type = array.getElementType();
                IIndex index = array.getIndex();

                if (rank == 1) {
                    //get X Axis array info
                    //add columns
                    IArrayIterator arrayIterator = array.getIterator();
                    isFirstRow = true;
                    while (arrayIterator.hasNext()) {
                        Object value = arrayIterator.getDoubleNext();
                        List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
                        dataItemsList.add(rowList);
                        if (isFirstRow) {
                            rowList.add(new SchemaDataItem(rowIndex, 0, dataName, String.class, dataName,
                                    String.class, dataName, String.class));
                            isFirstRow = false;
                        } else
                            rowList.add(new SchemaDataItem(rowIndex, 0, "", String.class, "", String.class, "",
                                    String.class));
                        rowList.add(new SchemaDataItem(rowIndex, 1, value, type, value, type, value, type));
                        rowIndex++;
                    }
                    //               for (int i = 0; i < shape[0]; i++) {
                    //                  //extract value
                    //                  index.set(i);
                    //                  Object value = array.getObject(index);
                    //
                    //                  //extract X Axis info
                    //                  xAxisIndex.set(i);
                    //                  Object xAxisValue = xAxisArray.getObject(xAxisIndex);
                    //
                    //
                    //                  //add data items to table model
                    //                  List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
                    //                  dataItemsList.add(rowList);
                    //                  rowList.add(new SchemaDataItem(i, 0, xAxisValue, xAxisType, value, type, xAxisValue, xAxisType));
                    //                  rowList.add(new SchemaDataItem(i, 1, xAxisValue, xAxisType, value, type, value, type));
                    //               }
                } else if (rank == 2) {

                    //First column for Y Axis values
                    columnNames.add("Y");

                    //get X Axis array info
                    //               final Array xAxisArray = axesArrayList.get(1);
                    //               final Class<?> xAxisType = xAxisArray.getElementType();
                    //               final int[] xAxisShape = xAxisArray.getShape();
                    //               final Index xAxisIndex = Factory.createIndex(xAxisShape);
                    //
                    //               List<Object> xAxisValueList = new ArrayList<Object>();
                    //
                    //               //get Y Axis array info
                    //               final Array yAxisArray = axesArrayList.get(0);
                    //               final Class<?> yAxisType = yAxisArray.getElementType();
                    //               final int[] yAxisShape = yAxisArray.getShape();
                    //               final Index yAxisIndex = Factory.createIndex(yAxisShape);
                    //
                    //               for (int i = 0; i < shape[0]; i++) {
                    //                  index.set(i);
                    //
                    //                  //extract Y Axis info
                    //                  yAxisIndex.set(i);
                    //                  Object yAxisValue = yAxisArray.getObject(yAxisIndex);
                    //
                    //
                    //                  List<SchemaDataItem> rowList = new ArrayList<SchemaDataItem>();
                    //                  dataItemsList.add(rowList);
                    //                  //Y Axis value for first column in the table
                    //                  rowList.add(new SchemaDataItem(i, 0, null, xAxisType, yAxisValue, yAxisType, "Y:" + getString(yAxisValue, yAxisType), String.class));
                    //
                    //
                    //                  for (int j = 0; j < shape[1]; j++) {
                    //                     index.set1(j);
                    //                     Object value = array.getObject(index);
                    //
                    //                     if (i == 0) {
                    //                        //extract X Axis info
                    //                        xAxisIndex.set(j);
                    //                        Object xAxisValue = xAxisArray.getObject(xAxisIndex);
                    //                        xAxisValueList.add(xAxisValue);
                    //
                    //                        //create column title with X Axis value
                    //                        columnNames.add("X:" + getString(xAxisValue, xAxisType));
                    //                     }
                    //
                    //                     rowList.add(new SchemaDataItem(i, j + 1, xAxisValueList.get(j), xAxisType, yAxisValue, yAxisType, value, type));
                    //                  }
                    //               }
                }

                else {
                    plot.handleException(new IllegalArgumentException(
                            "Not possible to create schema for the data object. Rank = " + rank));
                    return;
                }
            }
        }

        updateColumns(columnNames);

        viewer.refresh();
    }

    /**
     * Converts value object to string representation.
     * @param value a value object.
     * @param type class type object of the value.
     * @return string representation of the value.
     */
    private static String getString(Object value, Class<?> type) {
        if (type == null) {
            return String.valueOf(value);
        }
        if (type.isAssignableFrom(Double.class)) {
            return Double.toString((Double) value);
        } else if (type.isAssignableFrom(Integer.class)) {
            return Integer.toString((Integer) value);
        } else if (type.isAssignableFrom(Float.class)) {
            return Float.toString((Float) value);
        }
        return String.valueOf(value);
    }

    /**
     * Creates columns for current data structure.
     * @param columnNames column names.
     */
    private void updateColumns(List<String> columnNames) {

        for (String columnName : columnNames) {
            TableColumn tableColumn = new TableColumn(viewer.getTable(), SWT.NONE);
            tableColumn.setText(columnName);
            tableColumn.setWidth(70);
            //         tableColumn.setMoveable(true);
            tableColumn.addListener(SWT.Selection, sortSelectionListener);

            tableColumns.add(tableColumn);
        }
    }

    /**
     * Clear data from the table view.
     */
    public void clearData() {
        final TableColumn[] columns = viewer.getTable().getColumns();
        for (TableColumn tableColumn : columns) {
            tableColumn.removeListener(SWT.Selection, sortSelectionListener);
            tableColumn.dispose();
        }
        tableColumns.clear();
        dataItemsList.clear();
    }

    class SchemaListContentProvider implements IStructuredContentProvider {
        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        }

        public void dispose() {
        }

        public Object[] getElements(Object parent) {
            return dataItemsList.toArray();
        }
    }

    class SchemaLabelProvider extends LabelProvider implements ITableLabelProvider {

        public String getColumnText(Object obj, int index) {
            List<SchemaDataItem> rowList = (List<SchemaDataItem>) obj;

            SchemaDataItem statisticItem = rowList.get(index);

            return statisticItem.getString();
        }

        public Image getColumnImage(Object obj, int index) {
            return null;
            //         StatisticItem statisticItem = (StatisticItem) obj;
            //         Image icon = new Image(this.getShell().getDisplay(),  parent.getParent().getParent().getWorkspaceDir() + "/" + algorithm.getIcon());
            //         switch (index) {
            //         case 1:
            //         case 0:
            //            return null;
            //         default:
            //            return PlatformUI.getWorkbench().
            //            getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
            //         }
        }
    }

    private final class SortSelectionListener implements Listener {
        public void handleEvent(Event event) {
            //apply sorting
            tableViewerSorter.setSortColumn((TableColumn) event.widget);
            viewer.refresh(false);
        }
    }

    private final class TableViewerSorter extends ViewerSorter {

        private TableColumn column;

        private int direction = SWT.NONE;

        /**
         * Does the sort. If it's a different column from the previous sort, do an
         * ascending sort. If it's the same column as the last sort, toggle the sort
         * direction.
         *
         * @param column a column to be sorted
         */
        public void setSortColumn(TableColumn column) {
            final Table table = viewer.getTable();
            if (column == this.column) {
                // Same column as last sort; toggle the direction
                switch (direction) {
                case SWT.DOWN:
                    direction = SWT.UP;
                    break;
                //            case SWT.UP:
                //               direction = SWT.NONE;
                //               break;

                default:
                    direction = SWT.DOWN;
                    break;
                }

            } else {
                // New column; do an ascending sort
                this.column = column;
                direction = SWT.DOWN;

                table.setSortColumn(column);
            }

            table.setSortDirection(direction);
        }

        /**
         * Compares the object for sorting
         */
        public int compare(Viewer viewer, Object e1, Object e2) {
            if (direction == SWT.NONE) {
                //not sorted result
                return 0;
            }

            int columnIndex = getColumnIndex(column);
            if (columnIndex == -1) {
                return 0;
            }

            int result = 0;

            if (e1 instanceof List && e2 instanceof List) {
                List<SchemaDataItem> list1 = (List<SchemaDataItem>) e1;
                List<SchemaDataItem> list2 = (List<SchemaDataItem>) e2;

                final SchemaDataItem schemaDataItem1 = list1.get(columnIndex);
                final SchemaDataItem schemaDataItem2 = list2.get(columnIndex);

                Object value1 = schemaDataItem1.getValue();
                Object value2 = schemaDataItem2.getValue();

                if (value1 instanceof Comparable) {
                    result = ((Comparable<Object>) value1).compareTo(value2);
                } else {
                    // use the comparator to compare the values as string
                    result = getComparator().compare(schemaDataItem1.getString(), schemaDataItem2.getString());
                }

            } else {

                String name1;
                String name2;

                if (viewer == null || !(viewer instanceof ContentViewer)) {
                    name1 = e1.toString();
                    name2 = e2.toString();
                } else {
                    IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider();
                    if (prov instanceof ITableLabelProvider) {
                        ITableLabelProvider lprov = (ITableLabelProvider) prov;

                        name1 = lprov.getColumnText(e1, columnIndex);
                        name2 = lprov.getColumnText(e2, columnIndex);
                    } else {
                        name1 = e1.toString();
                        name2 = e2.toString();
                    }
                }
                if (name1 == null) {
                    name1 = "";//$NON-NLS-1$
                }
                if (name2 == null) {
                    name2 = "";//$NON-NLS-1$
                }

                // use the comparator to compare the strings
                result = getComparator().compare(name1, name2);

            }

            if (direction == SWT.UP) {
                //opposite direction
                result = -result;
            }
            return result;
        }
    }

    private static class SchemaDataItem {
        private final int row, column;
        private final Object xAxis, yAxis;
        private Class<?> xAxisType, yAxisType;
        //      private String key;
        private Object value;
        private Class<?> type;
        private String stringValue;

        public SchemaDataItem(int row, int column, Object xAxis, Class<?> xAxisType, Object yAxis,
                Class<?> yAxisType, Object value, Class<?> type) {
            this.row = row;
            this.column = column;
            this.xAxis = xAxis;
            this.xAxisType = xAxisType;
            this.yAxis = yAxis;
            this.yAxisType = yAxisType;
            this.value = value;
            this.type = type;

            stringValue = SchemaPlotComposite.getString(value, type);
        }

        /**
         * @return the row
         */
        public int getRow() {
            return row;
        }

        /**
         * @return the column
         */
        public int getColumn() {
            return column;
        }

        /**
         * @return the xAxis
         */
        public Object getXAxis() {
            return xAxis;
        }

        /**
         * @return the yAxis
         */
        public Object getYAxis() {
            return yAxis;
        }

        /**
         * @return the xAxisType
         */
        public Class<?> getXAxisType() {
            return xAxisType;
        }

        /**
         * @return the yAxisType
         */
        public Class<?> getYAxisType() {
            return yAxisType;
        }

        /**
         * @return the type
         */
        public Class<?> getType() {
            return type;
        }

        public Object getValue() {
            return value;
        }

        public String getString() {
            return stringValue;
        }
    }

}