org.mwc.cmap.LiveDataMonitor.views.LiveDataMonitor.java Source code

Java tutorial

Introduction

Here is the source code for org.mwc.cmap.LiveDataMonitor.views.LiveDataMonitor.java

Source

/*
 *    Debrief - the Open Source Maritime Analysis Application
 *    http://debrief.info
 *
 *    (C) 2000-2014, PlanetMayo Ltd
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the Eclipse Public License v1.0
 *    (http://www.eclipse.org/legal/epl-v10.html)
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 */
package org.mwc.cmap.LiveDataMonitor.views;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.part.ViewPart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.experimental.chart.swt.ChartComposite;

import MWC.Algorithms.LiveData.DataDoublet;
import MWC.Algorithms.LiveData.IAttribute;
import MWC.Algorithms.LiveData.IAttribute.IndexedAttribute;

/**
 * This sample class demonstrates how to plug-in a new workbench view. The view
 * shows data obtained from the model. The sample creates a dummy model on the
 * fly, but a real implementation would connect to the model available either in
 * this or another plug-in (e.g. the workspace). The view is connected to the
 * model using a content provider.
 * <p>
 * The view uses a label provider to define how model objects should be
 * presented in the view. Each view can present the same model objects using
 * different labels and icons, if needed. Alternatively, a single label provider
 * can be shared between views in order to ensure that objects of the same type
 * are presented in the same way everywhere.
 * <p>
 */

public class LiveDataMonitor extends ViewPart {

    /**
     * The ID of the view as specified by the extension.
     */
    public static final String ID = "livedatamonitor.views.LiveDataMonitor";

    private JFreeChart _chart;

    private IAttribute _watchedAttr;

    private final PropertyChangeListener _attListener;

    private IndexedAttribute _myIndexedAttr;

    private ChartComposite _chartFrame;

    /*
     * The content provider class is responsible for providing objects to the
     * view. It can wrap existing objects in adapters or simply return objects
     * as-is. These objects may be sensitive to the current input of the view, or
     * ignore it and always show the same content (like Task List, for example).
     */

    /**
     * The constructor.
     */
    public LiveDataMonitor() {
        _attListener = new PropertyChangeListener() {
            public void propertyChange(final PropertyChangeEvent evt) {
                // aah, is this for the scenario we're watching
                if (_myIndexedAttr != null)
                    if (evt.getSource() == _myIndexedAttr.index) {

                        final DataDoublet newD = (DataDoublet) evt.getNewValue();
                        final long time = newD.getTime();
                        final Object newValue = newD.getValue();
                        if (newValue instanceof Number) {
                            final Number value = (Number) newValue;

                            // and store it
                            final TimeSeriesCollection coll = (TimeSeriesCollection) _chart.getXYPlot()
                                    .getDataset();

                            TimeSeries tmpSeries;

                            if (coll == null) {
                                final TimeSeriesCollection dataset = new TimeSeriesCollection();
                                tmpSeries = new TimeSeries(_watchedAttr.getName());
                                dataset.addSeries(tmpSeries);
                                // add to series in different thread...
                                Display.getDefault().asyncExec(new Runnable() {
                                    public void run() {
                                        _chart.getXYPlot().setDataset(dataset);
                                    }
                                });
                            } else {
                                tmpSeries = coll.getSeries(0);
                            }

                            final TimeSeries series = tmpSeries;

                            // add to series in current thread, accepting it will slow down
                            // the
                            // UI
                            Display.getDefault().syncExec(new Runnable() {
                                public void run() {
                                    // are we still open?i
                                    if (!_chartFrame.isDisposed()) {
                                        // sure, go for it,
                                        series.addOrUpdate(new Millisecond(new Date(time)), value);
                                    }
                                }
                            });
                        }
                    }
            }
        };
    }

    /**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
    public void createPartControl(final Composite parent) {
        _chart = createChart(null);
        _chartFrame = new ChartComposite(parent, SWT.NONE, _chart, true) {
            @Override
            public void mouseUp(MouseEvent event) {
                super.mouseUp(event);
                JFreeChart c = getChart();
                if (c != null) {
                    c.setNotify(true); // force redraw
                }
            }
        };

        configureListeners();
    }

    /**
     * a watchable item has been selected, better show it
     * 
     * @param attribute
     *          what we're going to watch
     */
    private void storeDataset(final IAttribute attribute, final Object index) {
        final Vector<DataDoublet> data = attribute.getHistoricValues(index);

        // is there any data in it?
        if (data.size() == 0) {
            _chart.setTitle(attribute.getName());
            _chart.getXYPlot().setDataset(null);
        } else {
            final TimeSeriesCollection dataset = new TimeSeriesCollection();
            final TimeSeries series = new TimeSeries(attribute.getName());

            for (final Iterator<DataDoublet> iterator = data.iterator(); iterator.hasNext();) {
                final DataDoublet thisD = (DataDoublet) iterator.next();
                final Object thisVal = thisD.getValue();
                if (thisVal instanceof Number) {
                    series.addOrUpdate(new Millisecond(new Date(thisD.getTime())), (Number) thisD.getValue());
                }
            }
            // did it work?
            if (!series.isEmpty()) {
                dataset.addSeries(series);
                _chart.getXYPlot().setDataset(dataset);
                _chart.setTitle(attribute.getName());
                _chart.getXYPlot().getRangeAxis().setLabel(attribute.getUnits());
            }
        }
    }

    /**
     * Creates the Chart based on a dataset
     */
    private JFreeChart createChart(final TimeSeriesCollection dataset) {

        final String annTitle = "[PENDING]";
        final String catLabel = "Time";
        final String valueLabel = "Value";
        final JFreeChart chart = ChartFactory.createXYLineChart(annTitle, catLabel, valueLabel, dataset,
                PlotOrientation.VERTICAL, false, true, false);

        final XYPlot plot = chart.getXYPlot();
        final DateAxis dateA = new DateAxis();
        plot.setDomainAxis(dateA);
        plot.setRenderer(new XYLineAndShapeRenderer());
        plot.setNoDataMessage("No data available");
        return chart;

    }

    /**
     * sort out who's listening to what
     * 
     */
    private void configureListeners() {
        final ISelectionListener mylistener = new ISelectionListener() {
            public void selectionChanged(final IWorkbenchPart sourcepart, final ISelection selection) {
                // is this something we can get at?
                if (selection instanceof IStructuredSelection) {
                    final IStructuredSelection strS = (IStructuredSelection) selection;
                    final Object val = strS.getFirstElement();
                    showNewSelection(val);
                }
            }
        };

        final IWorkbenchWindow theWindow = getSite().getWorkbenchWindow();
        theWindow.getSelectionService().addSelectionListener(mylistener);
    }

    protected void showNewSelection(final Object sel) {
        // it it something we want to watch?
        if (sel instanceof IndexedAttribute) {
            final IAttribute.IndexedAttribute ind = (IndexedAttribute) sel;

            // cool, go for it.
            final IAttribute attr = ind.attribute;
            final Object index = ind.index;

            // is this a different one?
            if (_myIndexedAttr != ind) {
                // yup, all change

                // are we already listening to one?
                if (_watchedAttr != null)
                    _watchedAttr.removePropertyChangeListener(_attListener);

                // store the new ones
                _watchedAttr = attr;
                _myIndexedAttr = ind;

                // and start listening to it
                _watchedAttr.addPropertyChangeListener(_attListener);

                storeDataset(_watchedAttr, index);
            }

        }

    }

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

    }

}