gov.redhawk.statistics.ui.views.StatisticsView.java Source code

Java tutorial

Introduction

Here is the source code for gov.redhawk.statistics.ui.views.StatisticsView.java

Source

/******************************************************************************
 * This file is protected by Copyright. 
 * Please refer to the COPYRIGHT file distributed with this source distribution.
 *
 * This file is part of REDHAWK IDE.
 *
 * 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
 *******************************************************************************/
package gov.redhawk.statistics.ui.views;

import gov.redhawk.statistics.ui.internal.CustomAction;
import gov.redhawk.statistics.ui.internal.DatalistDataset;
import gov.redhawk.statistics.ui.internal.SettingsDialog;
import gov.redhawk.statistics.ui.internal.Stats;

import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.WorkbenchJob;
import org.jfree.chart.ChartColor;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.XYItemLabelGenerator;
import org.jfree.chart.labels.XYSeriesLabelGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.xy.ClusteredXYBarRenderer;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.DatasetChangeListener;
import org.jfree.data.xy.XYDataset;

public class StatisticsView extends ViewPart {

    public static final String ID = "gov.redhawk.statistics.ui.views.StatisticsView";

    public static final String[] STAT_PROPS = { Stats.MINIMUM, Stats.MAXIMUM, Stats.MEDIAN, Stats.MEAN,
            Stats.STD_DEV, Stats.NUM };

    private Label[] labels = new Label[STAT_PROPS.length];

    private Number[][] datalist;

    private JFreeChart chart;

    private Stats[] stats;

    private Stats magnitudeStats;

    private Composite parent;

    private Section section;

    private DatalistDataset dataSet = new DatalistDataset();

    private int curIndex = -1;

    private int numBars = 4;

    private final List<DisposeListener> listeners = Collections.synchronizedList(new ArrayList<DisposeListener>());

    private WorkbenchJob refreshJob = new WorkbenchJob("Refreshing Data and Composite") {
        {
            setSystem(true);
            setUser(false);
        }

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            refresh();
            return Status.OK_STATUS;
        }
    };

    /**
     * the constructor
     */
    public StatisticsView() {
    }

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    @Override
    public void createPartControl(Composite comp) {

        parent = comp;
        parent.setLayout(GridLayoutFactory.fillDefaults().margins(10, 10).numColumns(1).create());

        // Custom Action for the View's Menu
        CustomAction customAction = new CustomAction() {

            @Override
            public void run() {
                SettingsDialog dialog = new SettingsDialog(parent.getShell(), datalist.length, curIndex, numBars);
                dialog.create();
                if (dialog.open() == Window.OK) {
                    numBars = dialog.getNumBars();
                    curIndex = dialog.getSelectedIndex();
                    refreshJob.schedule();
                }
            }
        };
        customAction.setText("Settings");
        getViewSite().getActionBars().getMenuManager().add(customAction);

        // creation of chart composite and selection of associated options
        Composite chartComposite = new Composite(parent, SWT.EMBEDDED);
        chartComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());

        chart = ChartFactory.createXYBarChart(null, null, false, null, dataSet, PlotOrientation.VERTICAL, false,
                true, false);

        org.eclipse.swt.graphics.Color backgroundColor = chartComposite.getBackground();
        chart.setBackgroundPaint(
                new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue()));
        chart.getXYPlot().setBackgroundPaint(ChartColor.WHITE);

        Frame chartFrame = SWT_AWT.new_Frame(chartComposite);
        chartFrame.setBackground(
                new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue()));
        chartFrame.setLayout(new GridLayout());

        ChartPanel jFreeChartPanel = new ChartPanel(chart);
        chartFrame.add(jFreeChartPanel);

        ClusteredXYBarRenderer renderer = new ClusteredXYBarRenderer();
        renderer.setBarPainter(new StandardXYBarPainter());
        renderer.setMargin(0.05);
        renderer.setShadowVisible(false);
        renderer.setBaseItemLabelsVisible(true);
        renderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() {
            @Override
            public String generateLabel(XYDataset dataset, int series, int item) {
                return String.valueOf((int) (dataset.getYValue(series, item)));
            }
        });
        renderer.setBasePaint(new Color(139, 0, 0));
        renderer.setLegendItemLabelGenerator(new XYSeriesLabelGenerator() {

            @Override
            public String generateLabel(XYDataset ds, int i) {
                if (ds.getSeriesCount() == 2) {
                    if (i == 0) {
                        return "Real";
                    } else if (i == 1) {
                        return "Imaginary";
                    } else {
                        return "Complex";
                    }
                } else if (ds.getSeriesCount() > 1) {
                    return "Dimension " + i;
                }

                return null;
            }
        });
        chart.getXYPlot().setRenderer(renderer);

        dataSet.addChangeListener(new DatasetChangeListener() {

            @Override
            public void datasetChanged(DatasetChangeEvent event) {
                chart.getPlot().datasetChanged(event);

            }
        });

        // creation of the statistics composite
        FormToolkit toolkit = new FormToolkit(parent.getDisplay());
        section = toolkit.createSection(parent, Section.DESCRIPTION | Section.NO_TITLE | Section.CLIENT_INDENT);
        section.setBackground(parent.getBackground());
        section.setDescription("");
        section.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); // layout within parent

        // Composite for storing the data
        Composite composite = toolkit.createComposite(section, SWT.WRAP);
        composite.setBackground(parent.getBackground());
        composite.setLayout(GridLayoutFactory.fillDefaults().margins(10, 10).numColumns(4).create());
        composite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); // layout within parent
        toolkit.paintBordersFor(composite);
        section.setClient(composite);

        for (int j = 0; j < STAT_PROPS.length; j++) {
            Label label = new Label(composite, SWT.None);
            label.setText(STAT_PROPS[j] + ":");
            labels[j] = new Label(composite, SWT.None);
            labels[j].setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
        }

    }

    private void refresh() {
        Job job = new Job("Update Chart..") {

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                createStatsArray();
                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                    @Override
                    public void run() {
                        updateStatsLabels(curIndex);
                    }

                });

                setAllCategories();

                return Status.OK_STATUS;
            }

        };
        job.schedule();
    }

    private void createStatsArray() {
        stats = new Stats[datalist.length];
        for (int i = 0; i < stats.length; i++) {
            stats[i] = new Stats(datalist[i]);
        }
        magnitudeStats = new Stats(magArray());
    }

    private void updateStatsLabels(int i) {
        int showIndex = i;
        if (datalist.length == 1) {
            showIndex = 0;
        }
        Stats s;
        if (showIndex < 0) {
            s = magnitudeStats;
        } else {
            s = stats[showIndex];
        }

        for (int j = 0; j < STAT_PROPS.length; j++) {
            DecimalFormat form;
            double value = s.getStat(STAT_PROPS[j]).doubleValue();
            if (STAT_PROPS[j].equals(Stats.NUM)) {
                form = new DecimalFormat();
            } else if (value != 0 && (Math.abs(value) * 10 < 1 || Math.abs(value) / 10 > 99)) {
                form = new DecimalFormat("0.0#E0");
            } else {
                form = new DecimalFormat();
                form.setMaximumFractionDigits(3);
                form.setMaximumIntegerDigits(2);
            }
            labels[j].setText(form.format(value));
        }
        section.setDescription(getCategoryName(showIndex));
    }

    private void setAllCategories() {
        dataSet.removeAllSeries();
        if (curIndex >= 0) {
            dataSet.addSeries(getCategoryName(curIndex), doubleArray(curIndex), numBars);
        } else {
            for (int i = 0; i < datalist.length; i++) {
                dataSet.addSeries(getCategoryName(i), doubleArray(i), numBars);
            }
        }
    }

    private String getCategoryName(int i) {
        if (i < 0) {
            return "Complex (statistics calculated using magnitude)";
        } else if (datalist.length == 2) {
            if (i == 0) {
                return "Real";
            } else {
                return "Imaginary";
            }
        } else if (datalist.length == 1) {
            return "";
        }
        return "Dimension " + i;

    }

    /**
     * @since 2.0
     */
    public void setInput(Number[][] datalist) {
        this.datalist = datalist;
        refreshJob.schedule();
    }

    private double[] doubleArray(int index) {
        Number[] series = datalist[index];

        double[] array = new double[series.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = series[i].doubleValue();
        }
        return array;
    }

    private Number[] magArray() {
        Number[] array = new Number[datalist.length];
        for (int i = 0; i < datalist.length; i++) {
            array[i] = findMagnitude(datalist[i]);
        }
        return array;
    }

    private Number findMagnitude(Number[] nums) {
        double n = 0;
        for (int i = 0; i < nums.length; i++) {
            n += Math.pow(nums[i].doubleValue(), 2);
        }
        return Math.sqrt(n);
    }

    public void setIndex(int i) {
        this.curIndex = i;
        refreshJob.schedule();
    }

    public void setNumBars(int i) {
        this.numBars = i;
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    @Override
    public void setFocus() {
    }

    @Override
    public void dispose() {
        super.dispose();
        for (DisposeListener listener : listeners) {
            listener.widgetDisposed(null);
        }
    }

    public void addDisposeListener(DisposeListener listener) {
        if (listeners.contains(listener)) {
            return;
        }
        listeners.add(listener);
    }

    public void removeDisposeListener(DisposeListener listener) {
        if (listeners.contains(listener)) {
            listeners.remove(listener);
        }
    }
}