GNU Classpath (0.95) | |
Frames | No Frames |
1: /* LookAndFeel.java -- 2: Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Color; 42: import java.awt.Component; 43: import java.awt.Font; 44: import java.awt.Toolkit; 45: import java.net.URL; 46: 47: import javax.swing.border.Border; 48: import javax.swing.plaf.ComponentInputMapUIResource; 49: import javax.swing.plaf.IconUIResource; 50: import javax.swing.plaf.InputMapUIResource; 51: import javax.swing.plaf.UIResource; 52: import javax.swing.plaf.metal.MetalLookAndFeel; 53: import javax.swing.text.JTextComponent; 54: 55: /** 56: * A <i>look-and-feel</i> controls most aspects of the appearance and 57: * operation of user interface components in <code>javax.swing</code>. A 58: * cross-platform look-and-feel (the {@link MetalLookAndFeel}) is provided. 59: * 60: * @see UIManager#getInstalledLookAndFeels() 61: * @see UIManager#setLookAndFeel(LookAndFeel) 62: */ 63: public abstract class LookAndFeel 64: { 65: /** 66: * Creates and returns a look-and-feel specific defaults table. This method 67: * is called once by {@link UIManager#setLookAndFeel(LookAndFeel)} and 68: * shouldn't be called again (as it creates a large table of defaults). 69: * 70: * @return The UI defaults. 71: */ 72: public UIDefaults getDefaults() 73: { 74: return null; 75: } 76: 77: /** 78: * Returns a description of the look and feel. 79: * 80: * @return A description of the look and feel. 81: */ 82: public abstract String getDescription(); 83: 84: /** 85: * Returns the value of <code>Toolkit.getDefaultToolkit() 86: * .getDesktopProperty(systemPropertyName)</code>, or 87: * <code>fallbackValue</code> if no such property is defined. 88: * 89: * @param systemPropertyName the system property name. 90: * @param fallbackValue the fallback value. 91: * 92: * @return The property value or <code>fallbackValue</code>. 93: */ 94: public static Object getDesktopPropertyValue(String systemPropertyName, 95: Object fallbackValue) 96: { 97: Object value = Toolkit.getDefaultToolkit().getDesktopProperty( 98: systemPropertyName); 99: return value != null ? value : fallbackValue; 100: } 101: 102: /** 103: * Returns an identifier for the look and feel. 104: * 105: * @return An identifier for the look and feel. 106: */ 107: public abstract String getID(); 108: 109: /** 110: * Returns the name for the look and feel. 111: * 112: * @return The name for the look and feel. 113: */ 114: public abstract String getName(); 115: 116: /** 117: * Returns <code>true</code> when the look-and-feel supports window 118: * decorations, and <code>false</code> otherwise. This default implementation 119: * always returns <code>false</code> and needs to be overridden when the 120: * derived look-and-feel supports this. 121: * 122: * @return <code>false</code>. 123: * 124: * @since 1.4 125: */ 126: public boolean getSupportsWindowDecorations() 127: { 128: return false; 129: } 130: 131: /** 132: * Initializes the look-and-feel. The 133: * {@link UIManager#setLookAndFeel(LookAndFeel)} method calls this method 134: * before the first call (and typically the only call) to 135: * {@link #getDefaults()}. This default implementation does nothing, but 136: * subclasses can override this behaviour. 137: */ 138: public void initialize() 139: { 140: // We do nothing here. This method is meant to be overridden by 141: // LookAndFeel implementations. 142: } 143: 144: /** 145: * Convenience method for installing a component's default {@link Border} 146: * object on the specified component if either the border is currently 147: * <code>null</code> or already an instance of {@link UIResource}. 148: * 149: * @param c the component (<code>null</code> not permitted). 150: * @param defaultBorderName the border name (for lookup in the UIDefaults 151: * table). 152: */ 153: public static void installBorder(JComponent c, String defaultBorderName) 154: { 155: Border b = c.getBorder(); 156: if (b == null || b instanceof UIResource) 157: c.setBorder(UIManager.getBorder(defaultBorderName)); 158: } 159: 160: /** 161: * Convenience method for initializing a component's foreground and 162: * background color properties with values from the current defaults table. 163: * 164: * @param c the component (<code>null</code> not permitted). 165: * @param defaultBgName the key for the background color in the UIDefaults 166: * table. 167: * @param defaultFgName the key for the foreground color in the UIDefaults 168: * table. 169: */ 170: public static void installColors(JComponent c, String defaultBgName, 171: String defaultFgName) 172: { 173: // Install background. 174: Color bg = c.getBackground(); 175: if (bg == null || bg instanceof UIResource) 176: c.setBackground(UIManager.getColor(defaultBgName)); 177: 178: // Install foreground. 179: Color fg = c.getForeground(); 180: if (fg == null || fg instanceof UIResource) 181: c.setForeground(UIManager.getColor(defaultFgName)); 182: } 183: 184: /** 185: * Convenience method for initializing a component's foreground, background 186: * and font properties with values from the current defaults table. 187: * 188: * @param component the component (<code>null</code> not permitted). 189: * @param defaultBgName the key for the background color in the UIDefaults 190: * table. 191: * @param defaultFgName the key for the foreground color in the UIDefaults 192: * table. 193: * @param defaultFontName the key for the font in the UIDefaults table. 194: */ 195: public static void installColorsAndFont(JComponent component, 196: String defaultBgName, 197: String defaultFgName, 198: String defaultFontName) 199: { 200: // Install colors. 201: installColors(component, defaultBgName, defaultFgName); 202: // Install font. 203: Font f = component.getFont(); 204: if (f == null || f instanceof UIResource) 205: component.setFont(UIManager.getFont(defaultFontName)); 206: } 207: 208: /** 209: * Returns <code>true</code> if the look-and-feel is the "native" 210: * look-and-feel for the current platform, and <code>false</code> otherwise. 211: * A native look-and-feel emulates the appearance and behaviour of the 212: * default windowing system on the host operating system. 213: * 214: * @return A flag indicating whether or not this is the native look and feel 215: * for the current platform. 216: */ 217: public abstract boolean isNativeLookAndFeel(); 218: 219: /** 220: * Returns <code>true</code> if the look-and-feel is supported on the 221: * current operating system, and <code>false</code> otherwise. This 222: * mechanism is provided so that it is possible to prevent a look-and-feel 223: * from being used on some operating systems (usually for legal, not 224: * technical, reasons). 225: * 226: * @return A flag indicating whether or not the look-and-feel is supported 227: * on the current platform. 228: */ 229: public abstract boolean isSupportedLookAndFeel(); 230: 231: /** 232: * Loads the bindings in keys into retMap. Does not remove existing entries 233: * from retMap. <code>keys</code> describes the InputMap, every even indexed 234: * item is either a KeyStroke or a String representing a KeyStroke and every 235: * odd indexed item is the Object associated with that KeyStroke in an 236: * ActionMap. 237: * 238: * @param retMap the InputMap into which we load bindings 239: * @param keys the Object array describing the InputMap as above 240: */ 241: public static void loadKeyBindings(InputMap retMap, Object[] keys) 242: { 243: if (keys == null) 244: return; 245: for (int i = 0; i < keys.length - 1; i += 2) 246: { 247: Object key = keys[i]; 248: KeyStroke keyStroke; 249: if (key instanceof KeyStroke) 250: keyStroke = (KeyStroke) key; 251: else 252: keyStroke = KeyStroke.getKeyStroke((String) key); 253: retMap.put(keyStroke, keys[i + 1]); 254: } 255: } 256: 257: /** 258: * Creates a ComponentInputMap from keys. 259: * <code>keys</code> describes the InputMap, every even indexed 260: * item is either a KeyStroke or a String representing a KeyStroke and every 261: * odd indexed item is the Object associated with that KeyStroke in an 262: * ActionMap. 263: * 264: * @param c the JComponent associated with the ComponentInputMap 265: * @param keys the Object array describing the InputMap as above 266: * 267: * @return A new input map. 268: */ 269: public static ComponentInputMap makeComponentInputMap(JComponent c, 270: Object[] keys) 271: { 272: ComponentInputMap retMap = new ComponentInputMapUIResource(c); 273: loadKeyBindings(retMap, keys); 274: return retMap; 275: } 276: 277: /** 278: * Utility method that creates a UIDefaults.LazyValue that creates an 279: * ImageIcon UIResource for the specified gifFile filename. 280: * 281: * @param baseClass the base class for accessing the icon resource. 282: * @param gifFile the file name. 283: * 284: * @return A {@link UIDefaults.LazyValue} that serves up an 285: * {@link IconUIResource}. 286: */ 287: public static Object makeIcon(Class<?> baseClass, String gifFile) 288: { 289: final URL file = baseClass.getResource(gifFile); 290: return new UIDefaults.LazyValue() 291: { 292: public Object createValue(UIDefaults table) 293: { 294: return new IconUIResource(new ImageIcon(file)); 295: } 296: }; 297: } 298: 299: /** 300: * Creates a InputMap from keys. 301: * <code>keys</code> describes the InputMap, every even indexed 302: * item is either a KeyStroke or a String representing a KeyStroke and every 303: * odd indexed item is the Object associated with that KeyStroke in an 304: * ActionMap. 305: * 306: * @param keys the Object array describing the InputMap as above 307: * 308: * @return A new input map. 309: */ 310: public static InputMap makeInputMap(Object[] keys) 311: { 312: InputMap retMap = new InputMapUIResource(); 313: loadKeyBindings(retMap, keys); 314: return retMap; 315: } 316: 317: /** 318: * Convenience method for building lists of KeyBindings. 319: * <code>keyBindingList</code> is an array of KeyStroke-Action pairs where 320: * even indexed elements are KeyStrokes or Strings representing KeyStrokes 321: * and odd indexed elements are the associated Actions. 322: * 323: * @param keyBindingList the array of KeyStroke-Action pairs 324: * @return a JTextComponent.KeyBinding array 325: */ 326: public static JTextComponent.KeyBinding[] makeKeyBindings( 327: Object[] keyBindingList) 328: { 329: JTextComponent.KeyBinding[] retBindings = 330: new JTextComponent.KeyBinding[keyBindingList.length / 2]; 331: for (int i = 0; i < keyBindingList.length - 1; i += 2) 332: { 333: KeyStroke stroke; 334: if (keyBindingList[i] instanceof KeyStroke) 335: stroke = (KeyStroke) keyBindingList[i]; 336: else 337: stroke = KeyStroke.getKeyStroke((String) keyBindingList[i]); 338: retBindings[i / 2] = new JTextComponent.KeyBinding(stroke, 339: (String) keyBindingList[i + 1]); 340: } 341: return retBindings; 342: } 343: 344: /** 345: * Invoked when the user attempts an invalid operation. The default 346: * implementation just beeps. Subclasses that wish to change this need to 347: * override this method. 348: * 349: * @param component the component the error occured in 350: */ 351: public void provideErrorFeedback(Component component) 352: { 353: Toolkit.getDefaultToolkit().beep(); 354: } 355: 356: /** 357: * Returns a string that displays and identifies this object's properties. 358: * 359: * @return string containing the description and class name. 360: */ 361: public String toString() 362: { 363: return getDescription() + " " + getClass().getName(); 364: } 365: 366: /** 367: * UIManager.setLookAndFeel calls this method just before we're replaced by 368: * a new default look and feel. 369: */ 370: public void uninitialize() 371: { 372: // We do nothing here. This method is meant to be overridden by 373: // LookAndFeel implementations. 374: } 375: 376: /** 377: * Convenience method for un-installing a component's default border on the 378: * specified component if the border is currently an instance of UIResource. 379: * 380: * @param c the component (<code>null</code> not permitted). 381: */ 382: public static void uninstallBorder(JComponent c) 383: { 384: if (c.getBorder() instanceof UIResource) 385: c.setBorder(null); 386: } 387: 388: /** 389: * This methods installs a UI property if it hasn't already been set by an 390: * application. This method is used by UI delegates that install a default 391: * value for a property with a primitive type but do not want to override 392: * a value that has been set by an application. 393: * 394: * The supported properties depend on the actual type of the component and 395: * are listed in the table below. The supported properties are of course 396: * inherited to subclasses. 397: * 398: * <table> 399: * <tr><th>Type</th><th>Supported properties</th></tr> 400: * <tr><td><code>JComponent</code></td> 401: * <td><code>opaque, autoscrolls</code></td></tr> 402: * <tr><td><code>AbstractButton</code></td> 403: * <td><code>borderPainted, rolloverEnabled, iconTextGap, 404: * contentAreaFilled</code></td></tr> 405: * <tr><td><code>JDesktopPane</code></td> 406: * <td><code>dragMode</code></td></tr> 407: * <tr><td><code>JSplitPane</code></td> 408: * <td><code>dividerSize, oneTouchExpandable</code></td></tr> 409: * <tr><td><code>JTable</code></td> 410: * <td><code>rowHeight</code></td></tr> 411: * <tr><td><code>JTree</code></td> 412: * <td><code>rowHeight, scrollsOnExpand, showsRootHandles</code></td></tr> 413: * </table> 414: * 415: * @param c the component to install the property to 416: * @param propertyName the name of the property 417: * @param value the value of the property 418: * 419: * @throws IllegalArgumentException if the specified property cannot be set 420: * by this method 421: * @throws ClassCastException if the property value does not match the 422: * property type 423: * @throws NullPointerException if <code>c</code> or 424: * <code>propertyValue</code> is <code>null</code> 425: * 426: * @since 1.5 427: */ 428: public static void installProperty(JComponent c, String propertyName, 429: Object value) 430: { 431: c.setUIProperty(propertyName, value); 432: } 433: }
GNU Classpath (0.95) |