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 java.awt.*;
044: import java.io.Serializable;
045: import javax.swing.*;
046: import javax.swing.table.TableCellRenderer;
047:
048: /**
049: *
050: * @author Jiri Sedlacek
051: */
052: public class ThreadStateHeaderRenderer extends JPanel implements
053: TableCellRenderer, Serializable {
054: //~ Instance fields ----------------------------------------------------------------------------------------------------------
055:
056: private ThreadsPanel viewManager; // view manager for this header
057: private long dataEnd;
058: private long dataStart;
059: private long viewEnd;
060: private long viewStart;
061:
062: //~ Constructors -------------------------------------------------------------------------------------------------------------
063:
064: /** Creates a new instance of ThreadStateHeaderRenderer */
065: public ThreadStateHeaderRenderer(ThreadsPanel viewManager) {
066: this .viewManager = viewManager;
067: }
068:
069: //~ Methods ------------------------------------------------------------------------------------------------------------------
070:
071: public Dimension getMinimumSize() {
072: return getPreferredSize();
073: }
074:
075: /**
076: * Overridden for performance reasons.
077: */
078: public boolean isOpaque() {
079: Color back = getBackground();
080: Component p = getParent();
081:
082: if (p != null) {
083: p = p.getParent();
084: }
085:
086: boolean colorMatch = (back != null) && (p != null)
087: && back.equals(p.getBackground()) && p.isOpaque();
088:
089: return !colorMatch && super .isOpaque();
090: }
091:
092: public Dimension getPreferredSize() {
093: return new Dimension(super .getPreferredSize().width, getFont()
094: .getSize() + 11);
095: }
096:
097: public java.awt.Component getTableCellRendererComponent(
098: JTable table, Object value, boolean isSelected,
099: boolean hasFocus, int row, int column) {
100: viewStart = viewManager.getViewStart();
101: viewEnd = viewManager.getViewEnd();
102: dataStart = viewManager.getDataStart();
103: dataEnd = viewManager.getDataEnd();
104:
105: return this ;
106: }
107:
108: public void paint(Graphics g) {
109: super .paint(g);
110: paintResizableMark(g);
111: paintTimeMarks(g);
112: }
113:
114: /**
115: * Overridden for performance reasons.
116: */
117: public void repaint(long tm, int x, int y, int width, int height) {
118: }
119:
120: /**
121: * Overridden for performance reasons.
122: */
123: public void repaint(Rectangle r) {
124: }
125:
126: /**
127: * Overridden for performance reasons.
128: */
129: public void revalidate() {
130: }
131:
132: /**
133: * Overridden for performance reasons.
134: */
135: public void validate() {
136: }
137:
138: private void paintResizableMark(Graphics g) {
139: g.setColor(Color.BLACK);
140:
141: int margin = 4;
142:
143: for (int i = margin; i < (getSize().height - margin); i += 2) {
144: g.drawLine(1, i, 1, i);
145: }
146:
147: for (int i = margin + 1; i < (getSize().height - margin - 1); i += 2) {
148: g.drawLine(0, i, 0, i);
149: }
150:
151: g.setClip(4, 0, getWidth() - 3, getHeight());
152: }
153:
154: private void paintString(Graphics g, String string, int x, int y) {
155: int length = g.getFontMetrics().stringWidth(string);
156: g.drawString(string, x - (length / 2) + 1, y);
157: }
158:
159: private void paintTimeMarkString(Graphics g, int currentMark,
160: int optimalUnits, int x, int y) {
161: int markStringMillisMargin = 0; // space between mark's string without milliseconds and mark's milliseconds string
162: int markStringMillisReduce = 2; // markStringNoMillis.height - markStringMillisReduce = markStringMillis.height
163:
164: Font markStringNoMillisFont = g.getFont();
165: Font markStringMillisFont = markStringNoMillisFont
166: .deriveFont((float) (markStringNoMillisFont.getSize() - 2));
167:
168: String markStringNoMillis = TimeLineUtils
169: .getTimeMarkNoMillisString(currentMark, optimalUnits);
170: int wMarkStringNoMillis = g.getFontMetrics().stringWidth(
171: markStringNoMillis); // width of the mark's string without milliseconds
172: String markStringMillis = TimeLineUtils
173: .getTimeMarkMillisString(currentMark, optimalUnits);
174:
175: if (!markStringMillis.equals("")) {
176: markStringMillis = "." + markStringMillis; // NOI18N
177: }
178:
179: int wMarkStringMillis = g.getFontMetrics(markStringMillisFont)
180: .stringWidth(markStringMillis); // width of the mark's milliseconds string
181:
182: int xMarkStringNoMillis = x - (wMarkStringNoMillis / 2) + 1; // x-position of the mark's string without milliseconds
183: int xMarkStringMillis = xMarkStringNoMillis
184: + wMarkStringNoMillis + markStringMillisMargin; // x-position of the mark's milliseconds string
185:
186: g.setColor(TimeLineUtils.BASE_TIMELINE_COLOR);
187: g.drawString(markStringNoMillis, xMarkStringNoMillis, y);
188:
189: g.setFont(markStringMillisFont);
190: g.drawString(markStringMillis, xMarkStringMillis, y
191: - markStringMillisReduce + 1);
192: g.setFont(markStringNoMillisFont);
193: }
194:
195: private void paintTimeMarks(Graphics g) {
196: g.setFont(g.getFont().deriveFont(Font.BOLD));
197:
198: if ((viewEnd - viewStart) > 0) {
199: int firstValue = (int) (viewStart - dataStart);
200: int lastValue = (int) (viewEnd - dataStart);
201: float factor = (float) getWidth()
202: / (float) (viewEnd - viewStart);
203: int optimalUnits = TimeLineUtils.getOptimalUnits(factor);
204:
205: int firstMark = Math
206: .max((int) (Math.ceil((double) firstValue
207: / optimalUnits) * optimalUnits), 0);
208:
209: int currentMark = firstMark - optimalUnits;
210:
211: int componentFontSize = getFont().getSize();
212:
213: while (currentMark <= (lastValue + optimalUnits)) {
214: if (currentMark >= 0) {
215: float currentMarkRel = currentMark - firstValue;
216: int markPosition = (int) (currentMarkRel * factor);
217: paintTimeTicks(
218: g,
219: (int) (currentMarkRel * factor),
220: (int) ((currentMarkRel + optimalUnits) * factor),
221: TimeLineUtils.getTicksCount(optimalUnits));
222: g.setColor(TimeLineUtils.BASE_TIMELINE_COLOR);
223: g.drawLine(markPosition, 0, markPosition, 4);
224: paintTimeMarkString(g, currentMark, optimalUnits,
225: markPosition, 5 + componentFontSize);
226: g.setColor(TimeLineUtils.MAIN_TIMELINE_COLOR);
227: g.drawLine(markPosition, 8 + componentFontSize,
228: markPosition, getHeight() - 1);
229: }
230:
231: currentMark += optimalUnits;
232: }
233:
234: Font origFont = g.getFont();
235: Font plainFont = origFont.deriveFont(Font.PLAIN);
236: String sLegend = TimeLineUtils.getUnitsLegend(lastValue,
237: optimalUnits);
238: int wLegend = g.getFontMetrics(plainFont).stringWidth(
239: sLegend);
240:
241: if ((wLegend + 7) <= getWidth()) {
242: g.setFont(plainFont);
243: g.setColor(Color.WHITE);
244: g.fillRect(getWidth() - wLegend - 6, 5, wLegend + 7,
245: 4 + plainFont.getSize());
246: g.setColor(Color.BLACK);
247: g.drawString(sLegend, getWidth() - wLegend - 2,
248: 5 + plainFont.getSize());
249: g.setFont(origFont);
250: }
251: }
252: }
253:
254: private void paintTimeTicks(Graphics g, int startPos, int endPos,
255: int count) {
256: float factor = (float) (endPos - startPos) / (float) count;
257:
258: for (int i = 1; i < count; i++) {
259: int x = startPos + (int) (i * factor);
260: g.setColor(TimeLineUtils.BASE_TIMELINE_COLOR);
261: g.drawLine(x, 0, x, 2);
262: g.setColor(TimeLineUtils.TICK_TIMELINE_COLOR);
263: g.drawLine(x, 3, x, getHeight() - 1);
264: }
265: }
266: }
|