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.components;
042:
043: import java.awt.*;
044: import java.awt.event.FocusEvent;
045: import java.awt.event.FocusListener;
046: import java.awt.event.KeyEvent;
047: import java.awt.event.KeyListener;
048: import java.awt.event.MouseEvent;
049: import java.awt.event.MouseListener;
050: import javax.accessibility.Accessible;
051: import javax.accessibility.AccessibleContext;
052: import javax.swing.*;
053: import javax.swing.plaf.ComponentUI;
054: import org.netbeans.lib.profiler.ui.UIUtils;
055:
056: public class SnippetPanel extends JPanel implements MouseListener,
057: KeyListener, FocusListener {
058: //~ Inner Classes ------------------------------------------------------------------------------------------------------------
059:
060: public static class Padding extends JPanel {
061: //~ Constructors ---------------------------------------------------------------------------------------------------------
062:
063: public Padding() {
064: setBackground(UIUtils.getProfilerResultsBackground());
065: setOpaque(true);
066: }
067:
068: //~ Methods --------------------------------------------------------------------------------------------------------------
069:
070: protected void paintComponent(Graphics g) {
071: super .paintComponent(g);
072: g.setColor(lineColor);
073: g.drawLine(0, 0, getWidth(), 0);
074: }
075: }
076:
077: private static class Title extends JComponent implements Accessible {
078: //~ Instance fields ------------------------------------------------------------------------------------------------------
079:
080: String name;
081: private boolean collapsed;
082: private boolean rollOver;
083:
084: //~ Constructors ---------------------------------------------------------------------------------------------------------
085:
086: private Title(String name) {
087: this .name = name;
088: setUI(new TitleUI());
089: }
090:
091: //~ Methods --------------------------------------------------------------------------------------------------------------
092:
093: public void setRollOver(boolean rollOver) {
094: if (rollOver == this .rollOver) {
095: return;
096: }
097:
098: this .rollOver = rollOver;
099: repaint();
100: }
101:
102: public void collapse() {
103: collapsed = true;
104: repaint();
105: }
106:
107: public void expand() {
108: collapsed = false;
109: repaint();
110: }
111: }
112:
113: private static class TitleUI extends ComponentUI {
114: //~ Instance fields ------------------------------------------------------------------------------------------------------
115:
116: ImageIcon collapsedIcon = new ImageIcon(TitleUI.class
117: .getResource("collapsedSnippet.png")); //NOI18N
118: ImageIcon expandedIcon = new ImageIcon(TitleUI.class
119: .getResource("expandedSnippet.png")); //NOI18N
120:
121: //~ Methods --------------------------------------------------------------------------------------------------------------
122:
123: public Dimension getPreferredSize(JComponent c) {
124: FontMetrics fm = c.getGraphics()
125: .getFontMetrics(c.getFont());
126:
127: return new Dimension(20 /* 20 is hardcoded x-offset for title string in paint(Graphics g, JComponent c)*/
128: + fm.getStringBounds(((Title) c).name, c.getGraphics())
129: .getBounds().width, fm.getHeight() + 4);
130: }
131:
132: public void installUI(JComponent c) {
133: Font f = UIManager.getFont("Label.font"); //NOI18N
134: c.setFont(f.deriveFont(Font.BOLD));
135: }
136:
137: public void paint(Graphics g, JComponent c) {
138: ((Graphics2D) g).setRenderingHint(
139: RenderingHints.KEY_ANTIALIASING,
140: RenderingHints.VALUE_ANTIALIAS_ON);
141:
142: Title title = (Title) c;
143: Font font = c.getFont();
144:
145: if (title.collapsed) { // use plain font if collapsed
146: g.setFont(font.deriveFont(Font.PLAIN));
147: } else {
148: g.setFont(font);
149: }
150:
151: g.setColor(lineColor);
152:
153: FontMetrics fm = g.getFontMetrics(font);
154:
155: g.drawLine(0, 0, c.getWidth(), 0);
156:
157: if (title.collapsed) { // do not draw bottom line if collapsed
158:
159: if (title.rollOver || title.isFocusOwner()) {
160: g.setColor(focusedBackgroundColor);
161: } else {
162: g.setColor(backgroundColor);
163: }
164: }
165:
166: g.drawLine(0, 1 + fm.getHeight() + 2, c.getWidth(), 1 + fm
167: .getHeight() + 2);
168:
169: if (title.rollOver || title.isFocusOwner()) {
170: g.setColor(focusedBackgroundColor);
171: } else {
172: g.setColor(backgroundColor);
173: }
174:
175: g.fillRect(0, 1, c.getWidth(), fm.getHeight() + 2);
176:
177: g.setColor(textColor);
178: g.drawString(title.name, 20, fm.getHeight() - 1);
179:
180: int iconX = 5;
181: int iconY = 5;
182: ImageIcon icon = title.collapsed ? collapsedIcon
183: : expandedIcon;
184:
185: icon.paintIcon(c, g, iconX, iconY);
186: }
187: }
188:
189: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
190:
191: private static Color lineColor;
192: private static Color backgroundColor;
193: private static Color focusedBackgroundColor;
194: private static Color textColor;
195:
196: static {
197: initColors();
198: }
199:
200: //~ Instance fields ----------------------------------------------------------------------------------------------------------
201:
202: private JComponent content;
203: private String snippetName;
204: private Title title;
205: private boolean collapsed = false;
206:
207: //~ Constructors -------------------------------------------------------------------------------------------------------------
208:
209: public SnippetPanel(String snippetName, JComponent content) {
210: this .snippetName = snippetName;
211: this .content = content;
212: setLayout(new BorderLayout());
213: title = new Title(snippetName) {
214: public AccessibleContext getAccessibleContext() {
215: return SnippetPanel.this .getAccessibleContext();
216: }
217: };
218: title.setFocusable(true);
219: title.addKeyListener(this );
220: title.addMouseListener(this );
221: title.addFocusListener(this );
222: // transfer the tooltip from the content to the snippet panel
223: title.setToolTipText(content.getToolTipText());
224: content.setToolTipText(null);
225: //**
226: add(title, BorderLayout.NORTH);
227: add(content, BorderLayout.CENTER);
228: getAccessibleContext().setAccessibleName(snippetName);
229: }
230:
231: //~ Methods ------------------------------------------------------------------------------------------------------------------
232:
233: private static void initColors() {
234: Color systemBackgroundColor = UIUtils
235: .getProfilerResultsBackground();
236:
237: int backgroundRed = systemBackgroundColor.getRed();
238: int backgroundGreen = systemBackgroundColor.getGreen();
239: int backgroundBlue = systemBackgroundColor.getBlue();
240: boolean inverseColors = backgroundRed < 41
241: || backgroundGreen < 32 || backgroundBlue < 25;
242:
243: if (inverseColors) {
244: lineColor = UIUtils.getSafeColor(backgroundRed + 41,
245: backgroundGreen + 32, backgroundBlue + 8);
246: backgroundColor = UIUtils.getSafeColor(backgroundRed + 7,
247: backgroundGreen + 7, backgroundBlue + 7);
248: focusedBackgroundColor = UIUtils.getSafeColor(
249: backgroundRed + 25, backgroundGreen + 25,
250: backgroundBlue + 25);
251: } else {
252: lineColor = UIUtils
253: .getSafeColor(backgroundRed - 41 /*214*/,
254: backgroundGreen - 32 /*223*/,
255: backgroundBlue - 8 /*247*/);
256: backgroundColor = UIUtils
257: .getSafeColor(backgroundRed - 7 /*248*/,
258: backgroundGreen - 7 /*248*/,
259: backgroundBlue - 7 /*248*/);
260: focusedBackgroundColor = UIUtils
261: .getSafeColor(backgroundRed - 25 /*230*/,
262: backgroundGreen - 25 /*230*/,
263: backgroundBlue - 25 /*230*/);
264: }
265:
266: textColor = UIManager.getColor("Button.foreground"); // NOI18N
267: }
268:
269: public void setCollapsed(boolean collapsed) {
270: if (this .collapsed == collapsed) {
271: return;
272: }
273:
274: this .collapsed = collapsed;
275:
276: if (collapsed) {
277: title.collapse();
278: } else {
279: title.expand();
280: }
281:
282: content.setVisible(!collapsed);
283: revalidate();
284: }
285:
286: public boolean isCollapsed() {
287: return collapsed;
288: }
289:
290: public void setContent(JComponent content) {
291: this .content = content;
292: }
293:
294: public JComponent getContent() {
295: return content;
296: }
297:
298: public void setSnippetName(String snippetName) {
299: this .snippetName = snippetName;
300: }
301:
302: public String getSnippetName() {
303: return snippetName;
304: }
305:
306: public void focusGained(FocusEvent e) {
307: title.repaint();
308: }
309:
310: public void focusLost(FocusEvent e) {
311: title.repaint();
312: }
313:
314: public void keyPressed(final KeyEvent evt) {
315: if (evt.getKeyCode() == KeyEvent.VK_SPACE) {
316: setCollapsed(!isCollapsed());
317: }
318: }
319:
320: public void keyReleased(final KeyEvent evt) {
321: } // not used
322:
323: public void keyTyped(final KeyEvent evt) {
324: } // not used
325:
326: public void mouseClicked(MouseEvent e) {
327: } // not used
328:
329: public void mouseEntered(MouseEvent e) {
330: title.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
331: title.setRollOver(true);
332: }
333:
334: public void mouseExited(MouseEvent e) {
335: title.setCursor(Cursor
336: .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
337: title.setRollOver(false);
338: }
339:
340: public void mousePressed(MouseEvent e) {
341: setCollapsed(!collapsed);
342: requestFocus();
343: }
344:
345: public void mouseReleased(MouseEvent e) {
346: } // not used
347:
348: public void requestFocus() {
349: if (title != null) {
350: title.requestFocus();
351: }
352: }
353:
354: /*public static void main (String args[]) {
355: try {
356: UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
357: } catch (ClassNotFoundException e) {
358: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
359: } catch (InstantiationException e) {
360: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
361: } catch (IllegalAccessException e) {
362: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
363: } catch (UnsupportedLookAndFeelException e) {
364: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
365: }
366: JFrame jf = new JFrame ();
367: jf.setSize(400, 400);
368: jf.getContentPane().setLayout(new GridBagLayout());
369: JPanel content = new JPanel (); content.setBackground(Color.WHITE); content.setOpaque(true);
370: JPanel content2 = new JPanel (); content2.setBackground(Color.WHITE); content2.setOpaque(true);
371: JPanel content3 = new JPanel (); content3.setBackground(Color.WHITE); content3.setOpaque(true);
372: JPanel content4 = new JPanel (); content4.setBackground(Color.WHITE); content4.setOpaque(true);
373: JPanel content5 = new JPanel (); content5.setBackground(Color.WHITE); content5.setOpaque(true);
374: JPanel padding = new JPanel (); padding.setBackground(Color.WHITE); padding.setOpaque(true);
375: GridBagConstraints gbc = new GridBagConstraints();
376: gbc.gridwidth = GridBagConstraints.REMAINDER;
377: gbc.fill = GridBagConstraints.BOTH;
378: gbc.weightx = 1;
379: jf.getContentPane().add (new SnippetPanel ("Controls", content), gbc);
380: jf.getContentPane().add (new SnippetPanel ("Status", content2), gbc);
381: jf.getContentPane().add (new SnippetPanel ("View", content3), gbc);
382: jf.getContentPane().add (new SnippetPanel ("Snapshots", content4), gbc);
383: jf.getContentPane().add (new SnippetPanel ("Timeline", content5), gbc);
384: gbc.weighty = 1;
385: jf.getContentPane().add (padding, gbc);
386: jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
387: jf.show();
388: }
389: */
390: }
|