Java tutorial
/* * Copyright (C) 2011 Ives van der Flaas * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package be.ac.ua.comp.scarletnebula.gui; import java.awt.Color; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.SwingUtilities; import org.jfree.chart.ChartPanel; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.time.Millisecond; import org.jfree.data.time.RegularTimePeriod; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import be.ac.ua.comp.scarletnebula.core.Datapoint; import be.ac.ua.comp.scarletnebula.core.Server; import be.ac.ua.comp.scarletnebula.core.ServerStatisticsManager; import be.ac.ua.comp.scarletnebula.core.TimedDatapoint; /** * An abstract Graph that displays streaming data. * * @author ives * */ public abstract class Graph implements NewDatapointListener { protected Map<String, TimeSeries> datastreams = new HashMap<String, TimeSeries>(); protected final TimeSeriesCollection dataset = new TimeSeriesCollection(); protected final XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); final long maximumAge; private int maxSeriesID = 0; private final Collection<Server> serversToRefresh = new ArrayList<Server>(); /** * Constructor. * * @param maximumAge * The age after which data is no longer displayed in the graph */ public Graph(final long maximumAge) { this.maximumAge = maximumAge; } /** * Register a relative datastream coming from server with name streamname * and formal title (a displayable name) streamtitle. This stream will be * displayed with Color color. * * If this datastream was already running, historical data will be taken * from the stream and be displayed in the graph. * * @param server * Server that generates this relative datastream * @param streamname * The stream's short ID name (e.g. MEM) * @param color * The color this stream will be displayed in */ public final void registerRelativeDatastream(final Server server, final String streamname, final Color color) { final ServerStatisticsManager manager = server.getServerStatistics(); manager.addNewDatapointListener(this, streamname); final TimeSeries series = new TimeSeries(streamname); series.setMaximumItemAge(maximumAge); datastreams.put(streamname, series); dataset.addSeries(series); renderer.setSeriesPaint(maxSeriesID++, color); addListOfDatapoints(manager.getHistoricalDatapoints(streamname)); } /** * Returns the JFreeChart ChartPanel that will be updated as this object is * updated. * * @return The ChartPanel containing the Graph */ abstract ChartPanel getChartPanel(); /** * Registers a new datapoint for the stream named streamname, which was * measured at value, at the current time. * * @param datapoint * The datapoint to add (now). */ @Override public void newDataPoint(final Datapoint datapoint) { newDataPoint(new Millisecond(), datapoint); } /** * Adds a new server to the list of servers to be refreshed when a new * datapoint is received. * * @param server * Server that's refreshed. */ public void addServerToRefresh(final Server server) { serversToRefresh.add(server); } /** * Adds a list of datapoints. * * @param datapoints * The timed datapoints to add. */ public void addListOfDatapoints(final List<TimedDatapoint> datapoints) { for (final TimedDatapoint datapoint : datapoints) { newDataPoint(new Millisecond(new Date(datapoint.getTimeMs())), datapoint); } } /** * Registers a new datapoint for the stream named streamname, which was * measured at value, at time time. * * @param datapoint * The datapoint to add. * @param time * The time at which this measurement was made */ @Override public void newDataPoint(final RegularTimePeriod time, final Datapoint datapoint) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { final String dataStreamName = datapoint.getDatastream(); if (datastreams.containsKey(dataStreamName)) { datastreams.get(dataStreamName).addOrUpdate(time, datapoint.getValue()); } for (final Server server : serversToRefresh) { server.serverChanged(); } } }); } }