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.cpu;
042:
043: import org.netbeans.lib.profiler.ProfilerClient;
044: import org.netbeans.lib.profiler.client.ClientUtils;
045: import org.netbeans.lib.profiler.global.CommonConstants;
046: import org.netbeans.lib.profiler.global.CommonConstants;
047: import org.netbeans.lib.profiler.results.coderegion.CodeRegionResultsSnapshot;
048: import org.netbeans.lib.profiler.ui.LiveResultsPanel;
049: import org.netbeans.lib.profiler.ui.components.HTMLTextArea;
050: import org.netbeans.lib.profiler.utils.StringUtils;
051: import java.awt.*;
052: import java.awt.image.BufferedImage;
053: import java.text.MessageFormat;
054: import java.util.ResourceBundle;
055: import javax.swing.*;
056:
057: /**
058: * A display for live code region profiling results
059: *
060: * @author Ian Formanek
061: */
062: public class CodeRegionLivePanel extends JPanel implements
063: LiveResultsPanel {
064: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
065:
066: // -----
067: // I18N String constants
068: private static final ResourceBundle messages = ResourceBundle
069: .getBundle("org.netbeans.lib.profiler.ui.cpu.Bundle"); // NOI18N
070: private static final String PANEL_NAME = messages
071: .getString("CodeRegionLivePanel_PanelName"); // NOI18N
072: private static final String NO_RESULTS_TERMINATED_MSG = messages
073: .getString("CodeRegionLivePanel_NoResultsTerminatedMsg"); // NOI18N
074: private static final String NO_RESULTS_REGION_MSG = messages
075: .getString("CodeRegionLivePanel_NoResultsRegionMsg"); // NOI18N
076: private static final String INDIVIDUAL_TIMES_MSG = messages
077: .getString("CodeRegionLivePanel_IndividualTimesMsg"); // NOI18N
078: private static final String SUMMARY_TIMES_MSG = messages
079: .getString("CodeRegionLivePanel_SummaryTimesMsg"); // NOI18N
080: private static final String TOTAL_INVOCATIONS_MSG = messages
081: .getString("CodeRegionLivePanel_TotalInvocationsMsg"); // NOI18N
082: private static final String ALL_REMEMBERED_MSG = messages
083: .getString("CodeRegionLivePanel_AllRememberedMsg"); // NOI18N
084: private static final String LAST_REMEMBERED_MSG = messages
085: .getString("CodeRegionLivePanel_LastRememberedMsg"); // NOI18N
086: private static final String INVOCATIONS_LISTED_MSG = messages
087: .getString("CodeRegionLivePanel_InvocationsListedMsg"); // NOI18N
088: private static final String AREA_ACCESS_NAME = messages
089: .getString("CodeRegionLivePanel_AreaAccessName"); // NOI18N
090: // -----
091:
092: //~ Instance fields ----------------------------------------------------------------------------------------------------------
093:
094: private HTMLTextArea resArea;
095: private ProfilerClient profilerClient;
096:
097: //~ Constructors -------------------------------------------------------------------------------------------------------------
098:
099: public CodeRegionLivePanel(ProfilerClient client) {
100: this .profilerClient = client;
101: setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
102: setLayout(new BorderLayout());
103: resArea = new HTMLTextArea();
104: resArea.getAccessibleContext().setAccessibleName(
105: AREA_ACCESS_NAME);
106: add(new JScrollPane(resArea), BorderLayout.CENTER);
107: }
108:
109: //~ Methods ------------------------------------------------------------------------------------------------------------------
110:
111: public int getSortingColumn() {
112: return CommonConstants.SORTING_COLUMN_DEFAULT; // Not used for code region
113: }
114:
115: public boolean getSortingOrder() {
116: return false; // Not used for code region
117: }
118:
119: public String getTitle() {
120: return PANEL_NAME;
121: }
122:
123: public BufferedImage getViewImage(boolean onlyVisibleArea) {
124: return null;
125: }
126:
127: public String getViewName() {
128: return null;
129: }
130:
131: public boolean fitsVisibleArea() {
132: return true;
133: }
134:
135: public void handleRemove() {
136: }
137:
138: /**
139: * Called when auto refresh is on and profiling session will finish
140: * to give the panel chance to do some cleanup before asynchrounous
141: * call to updateLiveResults() will happen.
142: */
143: public void handleShutdown() {
144: // Nothing to do for Code Region live results, updateLiveResults will be called explicitely from outside
145: }
146:
147: // --- Save current View action support --------------------------------------
148: // Code Region not used in 6.0
149: public boolean hasView() {
150: return false;
151: }
152:
153: public void reset() {
154: updateLiveResults();
155: }
156:
157: public boolean supports(int instrumentationType) {
158: return instrumentationType == CommonConstants.INSTR_CODE_REGION;
159: }
160:
161: public void updateLiveResults() {
162: try {
163: CodeRegionResultsSnapshot sn = profilerClient
164: .getCodeRegionProfilingResultsSnapshot();
165: resArea.setText(getResultsText(sn.getTimes(), sn
166: .getTimerCountsInSecond()));
167: } catch (ClientUtils.TargetAppOrVMTerminated e) {
168: resArea.setText("<i>" + NO_RESULTS_TERMINATED_MSG + "</i>"); // NOI18N
169: }
170: }
171:
172: private String getResultsText(long[] results,
173: long timerCountsInSecond) {
174: StringBuffer resultText = new StringBuffer(results.length * 10);
175: StringBuffer summaryOfTimes = new StringBuffer();
176: long sum = 0;
177: long min;
178: long max;
179:
180: if (results.length < 2) {
181: resultText.append("<i>" + NO_RESULTS_REGION_MSG + "</i>"); // NOI18N
182: } else {
183: min = max = results[1];
184:
185: int nRes = results.length - 1;
186:
187: StringBuffer individualTimes = new StringBuffer();
188:
189: for (int i = 1; i < results.length; i++) {
190: long time = results[i];
191: sum += time;
192:
193: if (time > max) {
194: max = time;
195: } else if (time < min) {
196: min = time;
197: }
198:
199: individualTimes.append(MessageFormat.format(
200: INDIVIDUAL_TIMES_MSG,
201: new Object[] { StringUtils
202: .mcsTimeToString((time * 1000000)
203: / timerCountsInSecond) }));
204: individualTimes.append("<br>"); // NOI18N
205: }
206:
207: summaryOfTimes
208: .append(MessageFormat
209: .format(
210: SUMMARY_TIMES_MSG,
211: new Object[] {
212: StringUtils
213: .mcsTimeToString((sum * 1000000)
214: / timerCountsInSecond), // total
215: StringUtils
216: .mcsTimeToString((long) (((double) sum * 1000000)
217: / nRes / timerCountsInSecond)), // average
218: StringUtils
219: .mcsTimeToString((min * 1000000)
220: / timerCountsInSecond), // minimum
221: StringUtils
222: .mcsTimeToString((max * 1000000)
223: / timerCountsInSecond) // maximum
224: }));
225:
226: resultText.append(MessageFormat.format(
227: TOTAL_INVOCATIONS_MSG, new Object[] { ""
228: + results[0] })); // NOI18N
229: resultText.append(", "); // NOI18N
230:
231: if (results[0] <= nRes) {
232: resultText.append(ALL_REMEMBERED_MSG);
233: } else {
234: resultText.append(MessageFormat
235: .format(LAST_REMEMBERED_MSG, new Object[] { ""
236: + nRes })); // NOI18N
237: }
238:
239: resultText.append("<br>"); // NOI18N
240: resultText.append(summaryOfTimes);
241: resultText.append("<br><br><hr><br>"); // NOI18N
242: resultText.append(individualTimes);
243: resultText.append("<br><hr><br>"); // NOI18N
244: resultText
245: .append(MessageFormat.format(
246: INVOCATIONS_LISTED_MSG, new Object[] { ""
247: + nRes })); // NOI18N
248: resultText.append(", "); // NOI18N
249: resultText.append(summaryOfTimes);
250: }
251:
252: return resultText.toString();
253: }
254: }
|