fr.inria.soctrace.tools.ocelotl.statistics.view.StatTableView.java Source code

Java tutorial

Introduction

Here is the source code for fr.inria.soctrace.tools.ocelotl.statistics.view.StatTableView.java

Source

/*******************************************************************************
 * Copyright (c) 2012-2015 INRIA.
 * 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:
 *     Damien Dosimont <damien.dosimont@imag.fr>
 *     Youenn Corre <youenn.corret@inria.fr>
 ******************************************************************************/
package fr.inria.soctrace.tools.ocelotl.statistics.view;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.HashMap;

import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
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.eclipse.wb.swt.SWTResourceManager;

import fr.inria.soctrace.framesoc.core.bus.FramesocBusTopic;
import fr.inria.soctrace.framesoc.core.bus.FramesocBusTopicList;
import fr.inria.soctrace.framesoc.core.bus.IFramesocBusListener;
import fr.inria.soctrace.framesoc.ui.model.ITableColumn;
import fr.inria.soctrace.framesoc.ui.model.ITableRow;
import fr.inria.soctrace.framesoc.ui.model.TableRow;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
import fr.inria.soctrace.tools.ocelotl.core.constants.OcelotlConstants;
import fr.inria.soctrace.tools.ocelotl.core.statistics.IStatisticsProvider;
import fr.inria.soctrace.tools.ocelotl.statistics.operators.StatisticsProvider;
import fr.inria.soctrace.tools.ocelotl.statistics.operators.SummaryStat.SummaryStatModel;
import fr.inria.soctrace.tools.ocelotl.ui.views.OcelotlView;
import fr.inria.soctrace.tools.ocelotl.ui.views.statview.StatView;

public class StatTableView extends StatView implements IFramesocBusListener {

    /**
     * Followed topics
     */
    protected FramesocBusTopicList topics = null;

    /**
     * The table viewer
     */
    private TableViewer tableViewer;

    /**
     * Provide the stat data
     */
    private StatisticsProvider statProvider;

    /**
     * Column comparator
     */
    private OcelotlStatisticsColumnComparator comparator;
    private HashMap<Integer, OcelotlStatisticsTableColumn> columnIndex = new HashMap<Integer, OcelotlStatisticsTableColumn>();

    private Composite compositeTable;

    /**
     * Constructor
     */
    public StatTableView(OcelotlView theView) {
        super(theView);
        dispose();

        // Register update to synchronize traces
        topics = new FramesocBusTopicList(this);
        topics.addTopic(FramesocBusTopic.TOPIC_UI_COLORS_CHANGED);
        topics.registerAll();

        createPartControl(ocelotlView.getStatComposite());
    }

    @Override
    public void handle(FramesocBusTopic topic, Object data) {
        // If color has changed
        if ((topic.equals(FramesocBusTopic.TOPIC_UI_COLORS_CHANGED))) {
            if (statProvider != null && statProvider.getTableData() != null && tableViewer != null) {
                // Update colors and the table
                statProvider.updateColor();
                updateTableData();
            }
        }
    }

    @Override
    public String getStatDataToCSV() {
        StringBuffer output = new StringBuffer();
        for (ITableRow aRow : statProvider.getStatData()) {
            SummaryStatModel aStatRow = (SummaryStatModel) aRow;
            for (ITableColumn aColumn : aStatRow.getFields().keySet()) {
                output.append(aStatRow.getFields().get(aColumn) + OcelotlConstants.CSVDelimiter);
            }
            // Remove the last csv delimiter
            output.deleteCharAt(output.lastIndexOf(OcelotlConstants.CSVDelimiter));
            output.append("\n");
        }

        return output.toString();
    }

    @Override
    public void createDiagram() {
        statProvider.setMicroMode(ocelotlView.getCore().getMicroModel());
        updateData();
    }

    @Override
    public void deleteDiagram() {
        if (tableViewer != null)
            tableViewer.setInput(null);
    }

    /**
     * If data has changed
     */
    public void updateTableData() {
        if (tableViewer != null && !tableViewer.getTable().isDisposed()) {
            tableViewer.setInput(statProvider);
            tableViewer.refresh();
        }
    }

    @Override
    public void updateData() {
        if (statProvider.getMicroMode() != null) {
            statProvider.computeData();
            updateTableData();
            // Needed for correct redraw of the table
            compositeTable.layout();
        }
    }

    @Override
    public void resizeDiagram() {
        compositeTable.redraw();
        compositeTable.update();
        compositeTable.layout();
    }

    /**
     * Create the widgets for the statistics operators using table
     * 
     * @param parent
     *            Composite parent widget
     */
    public void createPartControl(Composite parent) {
        compositeTable = parent;
        GridLayout gl_compositeTable = new GridLayout(1, false);
        compositeTable.setLayout(gl_compositeTable);

        // Filter
        /*textFilter = new Text(compositeTable, SWT.BORDER);
        textFilter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
        false, 1, 1));
        textFilter.addKeyListener(new KeyAdapter() {
           public void keyReleased(KeyEvent e) {
        if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
           if (nameFilter == null || tableViewer == null)
              return;
           nameFilter.setSearchText(textFilter.getText());
           tableViewer.refresh();
        }
           }
        });*/

        // Table
        tableViewer = new TableViewer(compositeTable,
                SWT.FILL | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
        tableViewer.setContentProvider(new StatContentProvider());
        ColumnViewerToolTipSupport.enableFor(tableViewer);

        Table table = tableViewer.getTable();
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        table.setFont(SWTResourceManager.getFont("Cantarell", 8, SWT.NORMAL));
        table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        tableViewer.getTable().addListener(SWT.Resize, new ResizeListener());
        // needed to set a correct table width
        compositeTable.layout();

        createColumns();
        comparator = new OcelotlStatisticsColumnComparator();
        tableViewer.setComparator(comparator);

        // Default sorting of the table
        tableViewer.getTable().setSortColumn(tableViewer.getTable()
                .getColumn(ocelotlView.getOcelotlParameters().getSortTableSettings().getColumnNumber()));
        tableViewer.getTable()
                .setSortDirection(ocelotlView.getOcelotlParameters().getSortTableSettings().getDirection());
    }

    private void createColumns() {
        int cpt = 0;
        columnIndex = new HashMap<Integer, OcelotlStatisticsTableColumn>();

        // For each column
        for (final OcelotlStatisticsTableColumn col : OcelotlStatisticsTableColumn.values()) {
            TableViewerColumn elemsViewerCol = new TableViewerColumn(tableViewer, SWT.NONE);
            int alignment;

            // If it is the column name
            if (col.equals(OcelotlStatisticsTableColumn.NAME)) {
                // add a filter for this column
                // nameFilter = new OcelotlStatisticsTableRowFilter(col);
                // tableViewer.addFilter(nameFilter);

                // the label provider also puts the image
                elemsViewerCol.setLabelProvider(new OcelotlStatisticsTableRowLabelImageProvider(col));
                alignment = SWT.LEFT;
            } else {
                OcelotlStatisticsTableRowLabelProvider labelProvider = new OcelotlStatisticsTableRowLabelProvider(
                        col);
                if (col.equals(OcelotlStatisticsTableColumn.OCCURRENCES))
                    labelProvider.setToolTip(ocelotlView.getOcelotlParameters().getCurrentUnit());

                elemsViewerCol.setLabelProvider(labelProvider);
                alignment = SWT.RIGHT;
            }

            final TableColumn elemsTableCol = elemsViewerCol.getColumn();

            elemsTableCol.setWidth(Math.max((int) (tableViewer.getTable().getClientArea().width
                    * ocelotlView.getOcelotlParameters().getSortTableSettings().getColumnWidthWeight()[cpt]),
                    (int) (tableViewer.getTable().getClientArea().width * 0.05)));

            elemsTableCol.setText(col.getHeader());
            elemsTableCol.setAlignment(alignment);
            // Set sorting comparator when clicking on a column header
            elemsTableCol.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    comparator.setColumn(col);
                    tableViewer.getTable().setSortDirection(comparator.getDirection());
                    tableViewer.getTable().setSortColumn(elemsTableCol);
                    tableViewer.refresh();
                }
            });

            elemsTableCol.addControlListener(new ControlListener() {

                @Override
                public void controlResized(ControlEvent e) {
                    // Modified the weight of each column according to their new
                    // width
                    double areaWidth = tableViewer.getTable().getClientArea().width;
                    // Avoid complication due to small number
                    if (areaWidth > 4.0) {
                        // Set a minimal and maximal value to avoid column
                        // disappearing
                        for (int anIndex : columnIndex.keySet())
                            if (columnIndex.get(anIndex).getHeader().equals(col.getHeader())) {
                                ocelotlView.getOcelotlParameters().getSortTableSettings()
                                        .getColumnWidthWeight()[anIndex] = Math.min(
                                                Math.max(0.05, (double) elemsTableCol.getWidth() / areaWidth),
                                                0.95);
                            }
                    }
                }

                @Override
                public void controlMoved(ControlEvent e) {
                }
            });
            columnIndex.put(cpt, col);
            cpt++;
        }
    }

    public StatisticsProvider getStatProvider() {
        return statProvider;
    }

    public void setStatProvider(IStatisticsProvider statProvider) {
        this.statProvider = (StatisticsProvider) statProvider;
    }

    /**
     * Delete the old widgets
     */
    public void dispose() {
        if (topics != null)
            topics.unregisterAll();

        for (Control c : ocelotlView.getStatComposite().getChildren())
            c.dispose();
    }

    /**
     * Resize the columns dynamically
     */
    private class ResizeListener implements Listener {

        @Override
        public void handleEvent(Event event) {
            Table table = (Table) event.widget;
            int columnCount = table.getColumnCount();
            if (columnCount == 0)
                return;
            int totalAreaWidth = table.getClientArea().width;
            TableColumn[] columns = table.getColumns();
            for (int i = 0; i < columns.length; i++) {
                columns[i].setWidth((int) (totalAreaWidth
                        * ocelotlView.getOcelotlParameters().getSortTableSettings().getColumnWidthWeight()[i]));
            }
        }
    }

    /**
     * Class used to sort the column (copied and adapted from
     * StatisticsColumnComparator in Framesoc)
     */
    public class OcelotlStatisticsColumnComparator extends ViewerComparator {
        private OcelotlStatisticsTableColumn col = columnIndex
                .get(ocelotlView.getOcelotlParameters().getSortTableSettings().getColumnNumber());
        private int direction = ocelotlView.getOcelotlParameters().getSortTableSettings().getDirection();

        public int getDirection() {
            return direction;
        }

        public void setColumn(OcelotlStatisticsTableColumn aCol) {
            if (this.col.equals(aCol)) {
                // Same column as last sort: toggle the direction
                direction = (direction == SWT.UP) ? SWT.DOWN : SWT.UP;
            } else {
                // New column: do an ascending sort
                this.col = aCol;
                direction = SWT.UP;
            }

            // Get the column number and save it into the index
            TableColumn[] columns = tableViewer.getTable().getColumns();
            for (int i = 0; i < columns.length; i++)
                if (columns[i].getText().equals(aCol.getHeader()))
                    ocelotlView.getOcelotlParameters().getSortTableSettings().setColumnNumber(i);

            // Get the sorting direction
            ocelotlView.getOcelotlParameters().getSortTableSettings().setDirection(direction);
        }

        @Override
        public int compare(Viewer viewer, Object e1, Object e2) {

            TableRow r1 = (TableRow) e1;
            TableRow r2 = (TableRow) e2;

            int rc = 0;
            try {
                if (this.col.equals(OcelotlStatisticsTableColumn.OCCURRENCES)) {
                    // Number comparison
                    // If using a decimal separator, then parse with the local
                    // separator (dot or comma)
                    NumberFormat format = NumberFormat.getInstance();
                    Double v1 = format.parse(r1.get(this.col)).doubleValue();
                    Double v2 = format.parse(r2.get(this.col)).doubleValue();
                    rc = v1.compareTo(v2);
                } else if (this.col.equals(OcelotlStatisticsTableColumn.PERCENTAGE)) {
                    // percentage comparison 'xx.xx %'
                    NumberFormat format = NumberFormat.getInstance();
                    Double v1 = format.parse(r1.get(this.col).split(" ")[0]).doubleValue();
                    Double v2 = format.parse(r2.get(this.col).split(" ")[0]).doubleValue();
                    rc = v1.compareTo(v2);
                } else {
                    // string comparison
                    String v1 = r1.get(this.col);
                    String v2 = r2.get(this.col);
                    rc = v1.compareTo(v2);
                }
            } catch (SoCTraceException e) {
                e.printStackTrace();
                rc = 0;
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                rc = 0;
            }
            // If descending order, flip the direction
            if (direction == SWT.DOWN) {
                rc = -rc;
            }
            return rc;
        }
    }

}