001: /*
002: * UIUtils.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.swing.plaf;
023:
024: import com.sun.java.swing.plaf.motif.MotifLookAndFeel;
025: import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
026: import java.awt.Color;
027: import java.awt.Component;
028: import java.awt.Graphics;
029: import java.io.Serializable;
030: import javax.swing.Icon;
031: import javax.swing.JMenuItem;
032: import javax.swing.UIManager;
033: import javax.swing.plaf.UIResource;
034: import javax.swing.plaf.metal.MetalLookAndFeel;
035: import javax.swing.plaf.metal.OceanTheme;
036: import org.underworldlabs.swing.plaf.smoothgradient.SmoothGradientLookAndFeel;
037:
038: /* ----------------------------------------------------------
039: * CVS NOTE: Changes to the CVS repository prior to the
040: * release of version 3.0.0beta1 has meant a
041: * resetting of CVS revision numbers.
042: * ----------------------------------------------------------
043: */
044:
045: /**
046: * User interface utilities. Allows for central determination of
047: * colours, icons etc.
048: *
049: * @author Takis Diakoumis
050: * @version $Revision: 1.10 $
051: * @date $Date: 2006/09/05 11:57:53 $
052: */
053: public class UIUtils {
054:
055: /** the active colour for text */
056: private static Color defaultActiveTextColour;
057:
058: /** the active colour for backgrounds */
059: private static Color defaultActiveBackgroundColour;
060:
061: /** the inactive colour for backgrounds */
062: private static Color defaultInactiveBackgroundColour;
063:
064: /** True if checked for windows yet. */
065: private static boolean checkedWindows;
066:
067: /** True if running on Windows. */
068: private static boolean isWindows;
069:
070: /** True if checked for mac yet. */
071: private static boolean checkedMac;
072:
073: /** True if running on Mac. */
074: private static boolean isMac;
075:
076: /**
077: * Convenience method for consistent border colour.
078: *
079: * @return the system default border colour
080: */
081: public static Color getDefaultBorderColour() {
082: return UIManager.getColor("controlShadow");
083: }
084:
085: /**
086: * Returns true if running on Mac.
087: */
088: public static boolean isMac() {
089: if (!checkedMac) {
090: String osName = System.getProperty("os.name");
091: if (osName != null && osName.indexOf("Mac") != -1) {
092: isMac = true;
093: }
094: checkedMac = true;
095: }
096: return isMac;
097: }
098:
099: /**
100: * Returns true if running on Windows.
101: */
102: public static boolean isWindows() {
103: if (!checkedWindows) {
104: String osName = System.getProperty("os.name");
105: if (osName != null && osName.indexOf("Windows") != -1) {
106: isWindows = true;
107: }
108: checkedWindows = true;
109: }
110: return isWindows;
111: }
112:
113: /**
114: * Returns whether the current applied look and feel is
115: * the SmoothGradientLookAndFeel default look and feel.
116: *
117: * @return true | false
118: */
119: public static boolean isDefaultLookAndFeel() {
120: return (UIManager.getLookAndFeel() instanceof SmoothGradientLookAndFeel);
121: //|| usingOcean();
122: }
123:
124: /**
125: * Returns whether the current applied look and feel is
126: * an instance of GTK look and feel.
127: *
128: * @return true | false
129: */
130: public static boolean isGtkLookAndFeel() {
131: if (isWindows() || isMac()) {
132: return false;
133: }
134: return (UIManager.getLookAndFeel() instanceof com.sun.java.swing.plaf.gtk.GTKLookAndFeel);
135: }
136:
137: /**
138: * Returns whether the current applied look and feel is
139: * the MetalLookAndFeel
140: *
141: * @return true | false
142: */
143: public static boolean isMetalLookAndFeel() {
144: return UIManager.getLookAndFeel() instanceof MetalLookAndFeel;
145: }
146:
147: /**
148: * Returns whether the current applied look and feel is
149: * the MotifLookAndFeel
150: *
151: * @return true | false
152: */
153: public static boolean isMotifLookAndFeel() {
154: return UIManager.getLookAndFeel() instanceof MotifLookAndFeel;
155: }
156:
157: /**
158: * Returns whether the current applied look and feel is
159: * the WindowsLookAndFeel
160: *
161: * @return true | false
162: */
163: public static boolean isWindowsLookAndFeel() {
164: return UIManager.getLookAndFeel() instanceof WindowsLookAndFeel;
165: }
166:
167: /**
168: * Returns true if we're using the Ocean Theme under the
169: * MetalLookAndFeel.
170: */
171: public static boolean usingOcean() {
172: if (isMetalLookAndFeel()) {
173: MetalLookAndFeel laf = (MetalLookAndFeel) UIManager
174: .getLookAndFeel();
175: return (laf.getCurrentTheme() instanceof OceanTheme);
176: }
177: return false;
178: }
179:
180: public static Color getDefaultInactiveBackgroundColour() {
181: if (defaultInactiveBackgroundColour == null) {
182: defaultInactiveBackgroundColour = UIManager
183: .getColor("control");
184: }
185: return defaultInactiveBackgroundColour;
186: }
187:
188: public static Color getInverse(Color colour) {
189: int red = 255 - colour.getRed();
190: int green = 255 - colour.getGreen();
191: int blue = 255 - colour.getBlue();
192: return new Color(red, green, blue);
193: }
194:
195: public static Color getDefaultActiveBackgroundColour() {
196: if (defaultActiveBackgroundColour == null) {
197: if (!isWindowsLookAndFeel()) {
198: Color color = UIManager.getColor("activeCaptionBorder");
199: if (color == null) {
200: color = UIManager.getColor("controlShadow");
201: }
202: defaultActiveBackgroundColour = getBrighter(color, 0.85);
203: } else {
204: defaultActiveBackgroundColour = UIManager
205: .getColor("controlLtHighlight");
206: }
207: }
208: return defaultActiveBackgroundColour;
209: }
210:
211: public static Color getDefaultActiveTextColour() {
212: if (defaultActiveTextColour == null) {
213: if (!isWindowsLookAndFeel()) {
214: defaultActiveTextColour = UIManager
215: .getColor("activeCaptionText");
216: if (defaultActiveTextColour == null) {
217: // default to black text
218: defaultActiveTextColour = Color.BLACK;
219: }
220: } else {
221: defaultActiveTextColour = UIManager
222: .getColor("controlText");
223: }
224: }
225: return defaultActiveTextColour;
226: }
227:
228: public static Color getDarker(Color color, double factor) {
229: return new Color(Math.max((int) (color.getRed() * factor), 0),
230: Math.max((int) (color.getGreen() * factor), 0), Math
231: .max((int) (color.getBlue() * factor), 0));
232: }
233:
234: public static Color getBrighter(Color color, double factor) {
235: int r = color.getRed();
236: int g = color.getGreen();
237: int b = color.getBlue();
238:
239: int i = (int) (1.0 / (1.0 - factor));
240: if (r == 0 && g == 0 && b == 0) {
241: return new Color(i, i, i);
242: }
243: if (r > 0 && r < i)
244: r = i;
245: if (g > 0 && g < i)
246: g = i;
247: if (b > 0 && b < i)
248: b = i;
249:
250: return new Color(Math.min((int) (r / factor), 255), Math.min(
251: (int) (g / factor), 255), Math.min((int) (b / factor),
252: 255));
253: }
254:
255: // Cached Access to Icons ***********************************************************
256:
257: private static Icon checkBoxIcon;
258: private static Icon checkBoxMenuItemIcon;
259: private static Icon radioButtonMenuItemIcon;
260: private static Icon menuArrowIcon;
261: private static Icon expandedTreeIcon;
262: private static Icon collapsedTreeIcon;
263:
264: /**
265: * Answers an <code>Icon</code> used for <code>JCheckBox</code>es.
266: */
267: /*
268: static Icon getCheckBoxIcon() {
269: if (checkBoxIcon == null) {
270: checkBoxIcon = new CheckBoxIcon();
271: }
272: return checkBoxIcon;
273: }
274: */
275:
276: /**
277: * Answers an <code>Icon</code> used for <code>JCheckButtonMenuItem</code>s.
278: */
279: static Icon getCheckBoxMenuItemIcon() {
280: if (checkBoxMenuItemIcon == null) {
281: checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
282: }
283: return checkBoxMenuItemIcon;
284: }
285:
286: /**
287: * Answers an <code>Icon</code> used for <code>JRadioButtonMenuItem</code>s.
288: */
289: /*
290: static Icon getRadioButtonMenuItemIcon() {
291: if (radioButtonMenuItemIcon == null) {
292: radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
293: }
294: return radioButtonMenuItemIcon;
295: }
296: */
297:
298: /**
299: * Answers an <code>Icon</code> used for arrows in <code>JMenu</code>s.
300: */
301: /*
302: static Icon getMenuArrowIcon() {
303: if (menuArrowIcon == null) {
304: menuArrowIcon = new MenuArrowIcon();
305: }
306: return menuArrowIcon;
307: }
308: */
309:
310: /**
311: * Answers an <code>Icon</code> used in <code>JTree</code>s.
312: */
313: public static Icon getExpandedTreeIcon() {
314: if (expandedTreeIcon == null) {
315: expandedTreeIcon = new ExpandedTreeIcon();
316: }
317: return expandedTreeIcon;
318: }
319:
320: /**
321: * Answers an <code>Icon</code> used in <code>JTree</code>s.
322: */
323: public static Icon getCollapsedTreeIcon() {
324: if (collapsedTreeIcon == null) {
325: collapsedTreeIcon = new CollapsedTreeIcon();
326: }
327: return collapsedTreeIcon;
328: }
329:
330: private static class CheckBoxMenuItemIcon implements Icon,
331: UIResource, Serializable {
332:
333: private static final int SIZE = 13;
334:
335: public int getIconWidth() {
336: return SIZE;
337: }
338:
339: public int getIconHeight() {
340: return SIZE;
341: }
342:
343: public void paintIcon(Component c, Graphics g, int x, int y) {
344: JMenuItem b = (JMenuItem) c;
345: if (b.isSelected()) {
346: drawCheck(g, x, y + 1);
347: }
348: }
349: }
350:
351: // Helper method utilized by the CheckBoxIcon and the CheckBoxMenuItemIcon.
352: private static void drawCheck(Graphics g, int x, int y) {
353: g.translate(x, y);
354: g.drawLine(3, 5, 3, 5);
355: g.fillRect(3, 6, 2, 2);
356: g.drawLine(4, 8, 9, 3);
357: g.drawLine(5, 8, 9, 4);
358: g.drawLine(5, 9, 9, 5);
359: g.translate(-x, -y);
360: }
361:
362: /**
363: * The minus sign button icon used in trees
364: */
365: private static class ExpandedTreeIcon implements Icon, Serializable {
366:
367: protected static final int SIZE = 9;
368: protected static final int HALF_SIZE = 4;
369:
370: public void paintIcon(Component c, Graphics g, int x, int y) {
371: Color backgroundColor = c.getBackground();
372:
373: g.setColor(backgroundColor != null ? backgroundColor
374: : Color.white);
375: g.fillRect(x, y, SIZE - 1, SIZE - 1);
376: g.setColor(Color.gray);
377: g.drawRect(x, y, SIZE - 1, SIZE - 1);
378: g.setColor(Color.black);
379: g.drawLine(x + 2, y + HALF_SIZE, x + (SIZE - 3), y
380: + HALF_SIZE);
381: }
382:
383: public int getIconWidth() {
384: return SIZE;
385: }
386:
387: public int getIconHeight() {
388: return SIZE;
389: }
390: }
391:
392: /**
393: * The plus sign button icon used in trees.
394: */
395: private static class CollapsedTreeIcon extends ExpandedTreeIcon {
396: public void paintIcon(Component c, Graphics g, int x, int y) {
397: super .paintIcon(c, g, x, y);
398: g.drawLine(x + HALF_SIZE, y + 2, x + HALF_SIZE, y
399: + (SIZE - 3));
400: }
401: }
402:
403: private UIUtils() {
404: }
405: }
|