001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.jconsole;
027:
028: import java.awt.*;
029:
030: import javax.accessibility.*;
031: import javax.swing.*;
032: import javax.swing.border.*;
033: import javax.swing.tree.*;
034:
035: import sun.tools.jconsole.inspector.*;
036:
037: import static java.lang.Math.*;
038:
039: /**
040: * Miscellaneous utility methods for JConsole
041: */
042: public class Utilities {
043: private static final String windowsLaF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
044:
045: public static void updateTransparency(JComponent comp) {
046: LookAndFeel laf = UIManager.getLookAndFeel();
047: boolean transparent = laf.getClass().getName().equals(
048: windowsLaF);
049: setTabbedPaneTransparency(comp, transparent);
050: }
051:
052: private static void setTabbedPaneTransparency(JComponent comp,
053: boolean transparent) {
054: for (Component child : comp.getComponents()) {
055: if (comp instanceof JTabbedPane) {
056: setTransparency((JComponent) child, transparent);
057: } else if (child instanceof JComponent) {
058: setTabbedPaneTransparency((JComponent) child,
059: transparent);
060: }
061: }
062: }
063:
064: private static void setTransparency(JComponent comp,
065: boolean transparent) {
066: comp.setOpaque(!transparent);
067: for (Component child : comp.getComponents()) {
068: if (child instanceof JPanel || child instanceof JSplitPane
069: || child instanceof JScrollPane
070: || child instanceof JViewport
071: || child instanceof JCheckBox) {
072:
073: setTransparency((JComponent) child, transparent);
074: }
075: if (child instanceof XTree) {
076: XTree t = (XTree) child;
077: DefaultTreeCellRenderer cr = (DefaultTreeCellRenderer) t
078: .getCellRenderer();
079:
080: cr.setBackground(null);
081: cr
082: .setBackgroundNonSelectionColor(new Color(0, 0,
083: 0, 1));
084: t.setCellRenderer(cr);
085: setTransparency((JComponent) child, transparent);
086: }
087: }
088: }
089:
090: /**
091: * A slightly modified border for JScrollPane to be used with a JTable inside
092: * a JTabbedPane. It has only top part and the rest is clipped to make the
093: * overall border less thick.
094: * The top border helps differentiating the containing table from its container.
095: */
096: public static JScrollPane newTableScrollPane(JComponent comp) {
097: return new TableScrollPane(comp);
098: }
099:
100: @SuppressWarnings("serial")
101: private static class TableScrollPane extends JScrollPane {
102: public TableScrollPane(JComponent comp) {
103: super (comp);
104: }
105:
106: protected void paintBorder(Graphics g) {
107: Border border = getBorder();
108: if (border != null) {
109: Insets insets = border.getBorderInsets(this );
110: if (insets != null) {
111: Shape oldClip = g.getClip();
112: g.clipRect(0, 0, getWidth(), insets.top);
113: super .paintBorder(g);
114: g.setClip(oldClip);
115: }
116: }
117: }
118: }
119:
120: public static void setAccessibleName(Accessible comp, String name) {
121: comp.getAccessibleContext().setAccessibleName(name);
122: }
123:
124: public static void setAccessibleDescription(Accessible comp,
125: String description) {
126: comp.getAccessibleContext().setAccessibleDescription(
127: description);
128: }
129:
130: /**
131: * Modifies color c1 to ensure it has acceptable contrast
132: * relative to color c2.
133: *
134: * http://www.w3.org/TR/AERT#color-contrast
135: * http://www.cs.rit.edu/~ncs/color/t_convert.html#RGB%20to%20YIQ%20&%20YIQ%20to%20RGB
136: */
137: public static Color ensureContrast(Color c1, Color c2) {
138: double y1 = getColorBrightness(c1);
139: double y2 = getColorBrightness(c2);
140:
141: if (abs(y1 - y2) < 125.0) {
142: if (y2 < 128.0) {
143: c1 = setColorBrightness(c1, y2 + 125.0);
144: } else {
145: c1 = setColorBrightness(c1, y2 - 125.0);
146: }
147: }
148:
149: return c1;
150: }
151:
152: public static double getColorBrightness(Color c) {
153: // Convert RGB -> YIQ and return the Y value
154: return (c.getRed() * 0.299 + c.getGreen() * 0.587 + c.getBlue() * 0.114);
155: }
156:
157: private static Color setColorBrightness(Color c, double y) {
158: // Convert YIQ -> RGB
159: double i = (c.getRed() * 0.596 - c.getGreen() * 0.275 - c
160: .getBlue() * 0.321);
161: double q = (c.getRed() * 0.212 - c.getGreen() * 0.523 + c
162: .getBlue() * 0.311);
163:
164: // Keep values in legal range. This may reduce the
165: // achieved contrast somewhat.
166: int r = max(0, min(255, (int) round(y + i * 0.956 + q * 0.621)));
167: int g = max(0, min(255, (int) round(y - i * 0.272 - q * 0.647)));
168: int b = max(0, min(255, (int) round(y - i * 1.105 + q * 1.702)));
169:
170: return new Color(r, g, b);
171: }
172:
173: }
|