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.threads;
042:
043: import org.netbeans.lib.profiler.global.CommonConstants;
044: import org.netbeans.lib.profiler.global.Platform;
045: import org.netbeans.lib.profiler.results.threads.ThreadData;
046: import org.netbeans.lib.profiler.ui.UIUtils;
047: import java.awt.*;
048: import java.io.Serializable;
049: import javax.swing.*;
050: import javax.swing.table.TableCellRenderer;
051:
052: /**
053: * @author Jiri Sedlacek
054: */
055: public class ThreadStateCellRenderer extends JPanel implements
056: TableCellRenderer, Serializable {
057: //~ Instance fields ----------------------------------------------------------------------------------------------------------
058:
059: private Color unselectedBackground;
060: private Color unselectedForeground;
061: private ThreadData threadData;
062: private ThreadsPanel viewManager; // view manager for this cell
063: private long dataEnd;
064: private long dataStart;
065: private long viewEnd;
066: private long viewStart;
067:
068: //~ Constructors -------------------------------------------------------------------------------------------------------------
069:
070: /** Creates a new instance of ThreadStateCellRenderer */
071: public ThreadStateCellRenderer(ThreadsPanel viewManager) {
072: this .viewManager = viewManager;
073: }
074:
075: //~ Methods ------------------------------------------------------------------------------------------------------------------
076:
077: /**
078: * Overrides <code>JComponent.setBackground</code> to assign
079: * the unselected-background color to the specified color.
080: *
081: * @param c set the background color to this value
082: */
083: public void setBackground(Color c) {
084: super .setBackground(c);
085: unselectedBackground = UIUtils.getProfilerResultsBackground();
086: }
087:
088: /**
089: * Overrides <code>JComponent.setForeground</code> to assign
090: * the unselected-foreground color to the specified color.
091: *
092: * @param c set the foreground color to this value
093: */
094: public void setForeground(Color c) {
095: super .setForeground(c);
096: unselectedForeground = c;
097: }
098:
099: /**
100: * Overridden for performance reasons.
101: */
102: public boolean isOpaque() {
103: Color back = getBackground();
104: Component p = getParent();
105:
106: if (p != null) {
107: p = p.getParent();
108: }
109:
110: boolean colorMatch = (back != null) && (p != null)
111: && back.equals(p.getBackground()) && p.isOpaque();
112:
113: return !colorMatch && super .isOpaque();
114: }
115:
116: public java.awt.Component getTableCellRendererComponent(
117: JTable table, Object value, boolean isSelected,
118: boolean hasFocus, int row, int column) {
119: if (isSelected) {
120: super .setForeground(table.isFocusOwner() ? table
121: .getSelectionForeground() : UIUtils
122: .getUnfocusedSelectionForeground());
123: super .setBackground(table.isFocusOwner() ? table
124: .getSelectionBackground() : UIUtils
125: .getUnfocusedSelectionBackground());
126: } else {
127: if ((row & 0x1) == 0) { //even row
128: super
129: .setForeground((unselectedForeground != null) ? unselectedForeground
130: : table.getForeground());
131: super
132: .setBackground(UIUtils
133: .getDarker((unselectedBackground != null) ? unselectedBackground
134: : table.getBackground()));
135: } else {
136: super
137: .setForeground((unselectedForeground != null) ? unselectedForeground
138: : table.getForeground());
139: super
140: .setBackground((unselectedBackground != null) ? unselectedBackground
141: : table.getBackground());
142: }
143: }
144:
145: if (value instanceof ThreadData) {
146: threadData = (ThreadData) value;
147: }
148:
149: viewStart = viewManager.getViewStart();
150: viewEnd = viewManager.getViewEnd();
151: dataStart = viewManager.getDataStart();
152: dataEnd = viewManager.getDataEnd();
153:
154: return this ;
155: }
156:
157: /**
158: * Overridden for performance reasons.
159: */
160: public void firePropertyChange(String propertyName,
161: boolean oldValue, boolean newValue) {
162: }
163:
164: public void paint(Graphics g) {
165: super .paint(g);
166: paintTimeMarks(g);
167:
168: if (threadData != null) {
169: int index = getFirstVisibleDataUnit();
170:
171: if (index != -1) {
172: int width = getWidth();
173:
174: if ((viewEnd - viewStart) > 0) {
175: float factor = (float) width
176: / (float) (viewEnd - viewStart);
177:
178: while ((index < threadData.size())
179: && (threadData.getTimeStampAt(index) <= viewEnd)) {
180: // Thread alive
181: if (threadData.getStateAt(index) != CommonConstants.THREAD_STATUS_ZOMBIE) {
182: paintThreadState(g, index, threadData
183: .getThreadStateColorAt(index),
184: factor, width);
185: }
186:
187: index++;
188: }
189: }
190: }
191: }
192: }
193:
194: /**
195: * Overridden for performance reasons.
196: */
197: public void repaint(long tm, int x, int y, int width, int height) {
198: }
199:
200: /**
201: * Overridden for performance reasons.
202: */
203: public void repaint(Rectangle r) {
204: }
205:
206: /**
207: * Overridden for performance reasons.
208: */
209: public void revalidate() {
210: }
211:
212: /**
213: * Notification from the <code>UIManager</code> that the look and feel
214: * [L&F] has changed.
215: */
216: public void updateUI() {
217: super .updateUI();
218: setForeground(null);
219: setBackground(null);
220: }
221:
222: /**
223: * Overridden for performance reasons.
224: */
225: public void validate() {
226: }
227:
228: /**
229: * Overridden for performance reasons.
230: */
231: protected void firePropertyChange(String propertyName,
232: Object oldValue, Object newValue) {
233: }
234:
235: private boolean isFinishedDataUnit(int index) {
236: return (threadData.getStateAt(index) == CommonConstants.THREAD_STATUS_ZOMBIE);
237: }
238:
239: private int getFirstVisibleDataUnit() {
240: for (int i = 0; i < threadData.size(); i++) {
241: long timestamp = threadData.getTimeStampAt(i);
242:
243: if ((timestamp <= viewEnd)
244: && (i == (threadData.size() - 1))) {
245: return i; // last data unit before viewEnd
246: }
247:
248: if (timestamp <= viewStart) {
249: if (threadData.getTimeStampAt(i + 1) > viewStart) {
250: return i; // data unit ends between viewStart and viewEnd
251: }
252: } else {
253: if (timestamp <= viewEnd) {
254: return i; // data unit begins between viewStart and viewEnd
255: }
256: }
257: }
258:
259: return -1;
260: }
261:
262: private boolean isLastDataUnit(int index) {
263: return (index == (threadData.size() - 1));
264: }
265:
266: private void paintThreadState(Graphics g, int index,
267: Color threadStateColor, float factor, int width) {
268: int x; // Begin of rectangle
269: int xx; // End of rectangle
270:
271: x = Math
272: .max(
273: (int) ((float) (threadData
274: .getTimeStampAt(index) - viewStart) * factor),
275: 0);
276:
277: if (index < (threadData.size() - 1)) {
278: xx = Math.min((int) ((float) (threadData
279: .getTimeStampAt(index + 1) - viewStart) * factor),
280: width);
281: } else {
282: xx = Math.min((int) ((dataEnd - viewStart) * factor),
283: width + 1);
284: }
285:
286: g.setColor(threadStateColor);
287: g.fillRect(x, 6, xx - x, getHeight() - 12);
288: }
289:
290: private void paintTimeMarks(Graphics g) {
291: if ((viewEnd - viewStart) > 0) {
292: int firstValue = (int) (viewStart - dataStart);
293: int lastValue = (int) (viewEnd - dataStart);
294: float factor = (float) getWidth()
295: / (float) (viewEnd - viewStart);
296: int optimalUnits = TimeLineUtils.getOptimalUnits(factor);
297:
298: int firstMark = Math
299: .max((int) (Math.ceil((double) firstValue
300: / optimalUnits) * optimalUnits), 0);
301:
302: int currentMark = firstMark - optimalUnits;
303:
304: while (currentMark <= (lastValue + optimalUnits)) {
305: if (currentMark >= 0) {
306: float currentMarkRel = currentMark - firstValue;
307: int markPosition = (int) (currentMarkRel * factor);
308: paintTimeTicks(
309: g,
310: (int) (currentMarkRel * factor),
311: (int) ((currentMarkRel + optimalUnits) * factor),
312: TimeLineUtils.getTicksCount(optimalUnits));
313: g.setColor(TimeLineUtils.MAIN_TIMELINE_COLOR);
314: g.drawLine(markPosition, 0, markPosition,
315: getHeight() - 1);
316: }
317:
318: currentMark += optimalUnits;
319: }
320: }
321: }
322:
323: private void paintTimeTicks(Graphics g, int startPos, int endPos,
324: int count) {
325: float factor = (float) (endPos - startPos) / (float) count;
326:
327: g.setColor(TimeLineUtils.TICK_TIMELINE_COLOR);
328:
329: for (int i = 1; i < count; i++) {
330: int x = startPos + (int) (i * factor);
331: g.drawLine(x, 0, x, getHeight() - 1);
332: }
333: }
334: }
|