001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.ui.monitor;
042:
043: import org.netbeans.lib.profiler.results.DataManagerListener;
044: import org.netbeans.lib.profiler.results.monitor.VMTelemetryDataManager;
045: import org.netbeans.lib.profiler.ui.charts.*;
046: import java.awt.Color;
047: import java.util.HashSet;
048: import java.util.Iterator;
049: import java.util.Set;
050:
051: /**
052: *
053: * @author Jiri Sedlacek
054: */
055: public abstract class VMTelemetryXYChartModel extends
056: AbstractSynchronousXYChartModel implements DataManagerListener {
057: //~ Instance fields ----------------------------------------------------------------------------------------------------------
058:
059: protected VMTelemetryDataManager vmTelemetryDataManager;
060: protected long[] maxYValues;
061: protected long[] minYValues;
062: protected Color[] seriesColors;
063: protected String[] seriesNames;
064: protected int itemCount = 0;
065: protected int seriesCount = 0;
066: protected long maxXValue = 0;
067: protected long minXValue = 0;
068: private final Set dataResetListeners = new HashSet();
069: private long lastXValue = Long.MIN_VALUE;
070:
071: //~ Constructors -------------------------------------------------------------------------------------------------------------
072:
073: /** Creates a new instance of VMTelemetryXYChartModel */
074: public VMTelemetryXYChartModel(
075: VMTelemetryDataManager vmTelemetryDataManager) {
076: this .vmTelemetryDataManager = vmTelemetryDataManager;
077: vmTelemetryDataManager.addDataListener(this );
078: }
079:
080: //~ Methods ------------------------------------------------------------------------------------------------------------------
081:
082: public int getItemCount() {
083: return itemCount;
084: }
085:
086: // TODO: will be moved to chart axis definition
087: public long getMaxDisplayYValue(int seriesIndex) {
088: return getMaxYValue(seriesIndex);
089: }
090:
091: public long getMaxXValue() {
092: return maxXValue;
093: }
094:
095: public long getMaxYValue(int seriesIndex) {
096: return maxYValues[seriesIndex];
097: }
098:
099: // TODO: will be moved to chart axis definition
100: public long getMinDisplayYValue(int seriesIndex) {
101: return 0;
102: }
103:
104: public long getMinXValue() {
105: return minXValue;
106: }
107:
108: public long getMinYValue(int seriesIndex) {
109: return minYValues[seriesIndex];
110: }
111:
112: public Color getSeriesColor(int seriesIndex) {
113: return seriesColors[seriesIndex];
114: }
115:
116: // --- Abstract SynchronousXYChartModel --------------------------------------
117: public int getSeriesCount() {
118: return seriesCount;
119: }
120:
121: public String getSeriesName(int seriesIndex) {
122: return seriesNames[seriesIndex];
123: }
124:
125: public long getXValue(int itemIndex) {
126: return vmTelemetryDataManager.timeStamps[itemIndex];
127: }
128:
129: public long getYValue(int itemIndex, int seriesIndex) {
130: return getYValues(seriesIndex)[itemIndex];
131: }
132:
133: // --- DataReset Listeners ---------------------------------------------------
134: public void addDataResetListener(
135: VMTelemetryXYChartModelDataResetListener listener) {
136: dataResetListeners.add(listener);
137: }
138:
139: // --- DataManagerListener ---------------------------------------------------
140:
141: /** Called when the data managed by the manager change */
142: public void dataChanged() {
143: int newItemCount = vmTelemetryDataManager.getItemCount();
144:
145: if (itemCount == 0) {
146: if (newItemCount > 0) {
147: minXValue = vmTelemetryDataManager.timeStamps[0];
148: maxXValue = vmTelemetryDataManager.timeStamps[0];
149:
150: for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) {
151: minYValues[seriesIndex] = getYValues(seriesIndex)[0];
152: maxYValues[seriesIndex] = getYValues(seriesIndex)[0];
153: }
154:
155: if (newItemCount > 1) {
156: processNewData(1, newItemCount - 1);
157: }
158: }
159: } else {
160: if (newItemCount > itemCount) {
161: processNewData(itemCount, newItemCount - 1);
162: }
163: }
164:
165: itemCount = newItemCount;
166:
167: fireChartDataChanged();
168: }
169:
170: /** Called when the data managed by the manager reset (e.g. when a new session is started) */
171: public void dataReset() {
172: itemCount = 0;
173:
174: minXValue = 0;
175: maxXValue = 0;
176:
177: minYValues = new long[seriesCount];
178: maxYValues = new long[seriesCount];
179:
180: lastXValue = Long.MIN_VALUE;
181:
182: fireChartDataReset();
183: }
184:
185: /**
186: * Removes ChartModel listener.
187: * @param listener ChartModel listener to remove
188: */
189: public void removeDataResetListener(
190: VMTelemetryXYChartModelDataResetListener listener) {
191: dataResetListeners.remove(listener);
192: }
193:
194: public void setupModel(String[] seriesNames, Color[] seriesColors) {
195: this .seriesNames = seriesNames;
196: this .seriesColors = seriesColors;
197:
198: if (seriesNames.length != seriesColors.length) {
199: seriesCount = 0;
200: throw new RuntimeException(
201: "Counts of series names and series colors don't match."); // NOI18N
202: } else {
203: seriesCount = seriesNames.length;
204: }
205:
206: itemCount = 0;
207:
208: minXValue = 0;
209: maxXValue = 0;
210:
211: minYValues = new long[seriesCount];
212: maxYValues = new long[seriesCount];
213: }
214:
215: // --- Protected methods to be overriden by concrete implementation ----------
216: protected abstract long[] getYValues(int seriesIndex);
217:
218: /**
219: * Notifies all listeners about the data change.
220: */
221: protected void fireChartDataReset() {
222: if (dataResetListeners == null) {
223: return;
224: }
225:
226: Set toNotify;
227:
228: synchronized (dataResetListeners) {
229: toNotify = new HashSet(dataResetListeners);
230: }
231:
232: Iterator iterator = toNotify.iterator();
233:
234: while (iterator.hasNext()) {
235: ((VMTelemetryXYChartModelDataResetListener) iterator.next())
236: .chartDataReset();
237: }
238: }
239:
240: private void processNewData(int startIndex, int endIndex) {
241: long newXValue;
242: long newYValue;
243:
244: for (int itemIndex = startIndex; itemIndex <= endIndex; itemIndex++) {
245: newXValue = vmTelemetryDataManager.timeStamps[itemIndex];
246:
247: if (lastXValue >= newXValue) {
248: //Profiler.getDefault().log(ErrorManager.WARNING, "New x-value not greater than previous x-value. Graphs may not be displayed correctly."); // ErrorManager not accessible
249: System.err
250: .println("Profiler Graphs Warning: New x-value not greater than previous x-value. Graphs may not be displayed correctly."); // NOI18N
251: } else {
252: maxXValue = newXValue;
253: }
254:
255: lastXValue = newXValue;
256:
257: for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) {
258: newYValue = getYValues(seriesIndex)[itemIndex];
259:
260: minYValues[seriesIndex] = Math.min(
261: minYValues[seriesIndex], newYValue);
262: maxYValues[seriesIndex] = Math.max(
263: maxYValues[seriesIndex], newYValue);
264: }
265: }
266: }
267: }
|