| /* LookAndFeel.java -- |
| Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package javax.swing; |
| |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Font; |
| import java.awt.Toolkit; |
| import java.net.URL; |
| |
| import javax.swing.border.Border; |
| import javax.swing.plaf.ComponentInputMapUIResource; |
| import javax.swing.plaf.IconUIResource; |
| import javax.swing.plaf.InputMapUIResource; |
| import javax.swing.plaf.UIResource; |
| import javax.swing.plaf.metal.MetalLookAndFeel; |
| import javax.swing.text.JTextComponent; |
| |
| /** |
| * A <i>look-and-feel</i> controls most aspects of the appearance and |
| * operation of user interface components in <code>javax.swing</code>. A |
| * cross-platform look-and-feel (the {@link MetalLookAndFeel}) is provided. |
| * |
| * @see UIManager#getInstalledLookAndFeels() |
| * @see UIManager#setLookAndFeel(LookAndFeel) |
| */ |
| public abstract class LookAndFeel |
| { |
| /** |
| * Creates and returns a look-and-feel specific defaults table. This method |
| * is called once by {@link UIManager#setLookAndFeel(LookAndFeel)} and |
| * shouldn't be called again (as it creates a large table of defaults). |
| * |
| * @return The UI defaults. |
| */ |
| public UIDefaults getDefaults() |
| { |
| return null; |
| } |
| |
| /** |
| * Returns a description of the look and feel. |
| * |
| * @return A description of the look and feel. |
| */ |
| public abstract String getDescription(); |
| |
| /** |
| * Returns the value of <code>Toolkit.getDefaultToolkit() |
| * .getDesktopProperty(systemPropertyName)</code>, or |
| * <code>fallbackValue</code> if no such property is defined. |
| * |
| * @param systemPropertyName the system property name. |
| * @param fallbackValue the fallback value. |
| * |
| * @return The property value or <code>fallbackValue</code>. |
| */ |
| public static Object getDesktopPropertyValue(String systemPropertyName, |
| Object fallbackValue) |
| { |
| Object value = Toolkit.getDefaultToolkit().getDesktopProperty( |
| systemPropertyName); |
| return value != null ? value : fallbackValue; |
| } |
| |
| /** |
| * Returns an identifier for the look and feel. |
| * |
| * @return An identifier for the look and feel. |
| */ |
| public abstract String getID(); |
| |
| /** |
| * Returns the name for the look and feel. |
| * |
| * @return The name for the look and feel. |
| */ |
| public abstract String getName(); |
| |
| /** |
| * Returns <code>true</code> when the look-and-feel supports window |
| * decorations, and <code>false</code> otherwise. This default implementation |
| * always returns <code>false</code> and needs to be overridden when the |
| * derived look-and-feel supports this. |
| * |
| * @return <code>false</code>. |
| * |
| * @since 1.4 |
| */ |
| public boolean getSupportsWindowDecorations() |
| { |
| return false; |
| } |
| |
| /** |
| * Initializes the look-and-feel. The |
| * {@link UIManager#setLookAndFeel(LookAndFeel)} method calls this method |
| * before the first call (and typically the only call) to |
| * {@link #getDefaults()}. This default implementation does nothing, but |
| * subclasses can override this behaviour. |
| */ |
| public void initialize() |
| { |
| // We do nothing here. This method is meant to be overridden by |
| // LookAndFeel implementations. |
| } |
| |
| /** |
| * Convenience method for installing a component's default {@link Border} |
| * object on the specified component if either the border is currently |
| * <code>null</code> or already an instance of {@link UIResource}. |
| * |
| * @param c the component (<code>null</code> not permitted). |
| * @param defaultBorderName the border name (for lookup in the UIDefaults |
| * table). |
| */ |
| public static void installBorder(JComponent c, String defaultBorderName) |
| { |
| Border b = c.getBorder(); |
| if (b == null || b instanceof UIResource) |
| c.setBorder(UIManager.getBorder(defaultBorderName)); |
| } |
| |
| /** |
| * Convenience method for initializing a component's foreground and |
| * background color properties with values from the current defaults table. |
| * |
| * @param c the component (<code>null</code> not permitted). |
| * @param defaultBgName the key for the background color in the UIDefaults |
| * table. |
| * @param defaultFgName the key for the foreground color in the UIDefaults |
| * table. |
| */ |
| public static void installColors(JComponent c, String defaultBgName, |
| String defaultFgName) |
| { |
| // Install background. |
| Color bg = c.getBackground(); |
| if (bg == null || bg instanceof UIResource) |
| c.setBackground(UIManager.getColor(defaultBgName)); |
| |
| // Install foreground. |
| Color fg = c.getForeground(); |
| if (fg == null || fg instanceof UIResource) |
| c.setForeground(UIManager.getColor(defaultFgName)); |
| } |
| |
| /** |
| * Convenience method for initializing a component's foreground, background |
| * and font properties with values from the current defaults table. |
| * |
| * @param component the component (<code>null</code> not permitted). |
| * @param defaultBgName the key for the background color in the UIDefaults |
| * table. |
| * @param defaultFgName the key for the foreground color in the UIDefaults |
| * table. |
| * @param defaultFontName the key for the font in the UIDefaults table. |
| */ |
| public static void installColorsAndFont(JComponent component, |
| String defaultBgName, |
| String defaultFgName, |
| String defaultFontName) |
| { |
| // Install colors. |
| installColors(component, defaultBgName, defaultFgName); |
| // Install font. |
| Font f = component.getFont(); |
| if (f == null || f instanceof UIResource) |
| component.setFont(UIManager.getFont(defaultFontName)); |
| } |
| |
| /** |
| * Returns <code>true</code> if the look-and-feel is the "native" |
| * look-and-feel for the current platform, and <code>false</code> otherwise. |
| * A native look-and-feel emulates the appearance and behaviour of the |
| * default windowing system on the host operating system. |
| * |
| * @return A flag indicating whether or not this is the native look and feel |
| * for the current platform. |
| */ |
| public abstract boolean isNativeLookAndFeel(); |
| |
| /** |
| * Returns <code>true</code> if the look-and-feel is supported on the |
| * current operating system, and <code>false</code> otherwise. This |
| * mechanism is provided so that it is possible to prevent a look-and-feel |
| * from being used on some operating systems (usually for legal, not |
| * technical, reasons). |
| * |
| * @return A flag indicating whether or not the look-and-feel is supported |
| * on the current platform. |
| */ |
| public abstract boolean isSupportedLookAndFeel(); |
| |
| /** |
| * Loads the bindings in keys into retMap. Does not remove existing entries |
| * from retMap. <code>keys</code> describes the InputMap, every even indexed |
| * item is either a KeyStroke or a String representing a KeyStroke and every |
| * odd indexed item is the Object associated with that KeyStroke in an |
| * ActionMap. |
| * |
| * @param retMap the InputMap into which we load bindings |
| * @param keys the Object array describing the InputMap as above |
| */ |
| public static void loadKeyBindings(InputMap retMap, Object[] keys) |
| { |
| if (keys == null) |
| return; |
| for (int i = 0; i < keys.length - 1; i += 2) |
| { |
| Object key = keys[i]; |
| KeyStroke keyStroke; |
| if (key instanceof KeyStroke) |
| keyStroke = (KeyStroke) key; |
| else |
| keyStroke = KeyStroke.getKeyStroke((String) key); |
| retMap.put(keyStroke, keys[i + 1]); |
| } |
| } |
| |
| /** |
| * Creates a ComponentInputMap from keys. |
| * <code>keys</code> describes the InputMap, every even indexed |
| * item is either a KeyStroke or a String representing a KeyStroke and every |
| * odd indexed item is the Object associated with that KeyStroke in an |
| * ActionMap. |
| * |
| * @param c the JComponent associated with the ComponentInputMap |
| * @param keys the Object array describing the InputMap as above |
| * |
| * @return A new input map. |
| */ |
| public static ComponentInputMap makeComponentInputMap(JComponent c, |
| Object[] keys) |
| { |
| ComponentInputMap retMap = new ComponentInputMapUIResource(c); |
| loadKeyBindings(retMap, keys); |
| return retMap; |
| } |
| |
| /** |
| * Utility method that creates a UIDefaults.LazyValue that creates an |
| * ImageIcon UIResource for the specified gifFile filename. |
| * |
| * @param baseClass the base class for accessing the icon resource. |
| * @param gifFile the file name. |
| * |
| * @return A {@link UIDefaults.LazyValue} that serves up an |
| * {@link IconUIResource}. |
| */ |
| public static Object makeIcon(Class baseClass, String gifFile) |
| { |
| final URL file = baseClass.getResource(gifFile); |
| return new UIDefaults.LazyValue() |
| { |
| public Object createValue(UIDefaults table) |
| { |
| return new IconUIResource(new ImageIcon(file)); |
| } |
| }; |
| } |
| |
| /** |
| * Creates a InputMap from keys. |
| * <code>keys</code> describes the InputMap, every even indexed |
| * item is either a KeyStroke or a String representing a KeyStroke and every |
| * odd indexed item is the Object associated with that KeyStroke in an |
| * ActionMap. |
| * |
| * @param keys the Object array describing the InputMap as above |
| * |
| * @return A new input map. |
| */ |
| public static InputMap makeInputMap(Object[] keys) |
| { |
| InputMap retMap = new InputMapUIResource(); |
| loadKeyBindings(retMap, keys); |
| return retMap; |
| } |
| |
| /** |
| * Convenience method for building lists of KeyBindings. |
| * <code>keyBindingList</code> is an array of KeyStroke-Action pairs where |
| * even indexed elements are KeyStrokes or Strings representing KeyStrokes |
| * and odd indexed elements are the associated Actions. |
| * |
| * @param keyBindingList the array of KeyStroke-Action pairs |
| * @return a JTextComponent.KeyBinding array |
| */ |
| public static JTextComponent.KeyBinding[] makeKeyBindings( |
| Object[] keyBindingList) |
| { |
| JTextComponent.KeyBinding[] retBindings = |
| new JTextComponent.KeyBinding[keyBindingList.length / 2]; |
| for (int i = 0; i < keyBindingList.length - 1; i += 2) |
| { |
| KeyStroke stroke; |
| if (keyBindingList[i] instanceof KeyStroke) |
| stroke = (KeyStroke) keyBindingList[i]; |
| else |
| stroke = KeyStroke.getKeyStroke((String) keyBindingList[i]); |
| retBindings[i / 2] = new JTextComponent.KeyBinding(stroke, |
| (String) keyBindingList[i + 1]); |
| } |
| return retBindings; |
| } |
| |
| /** |
| * Invoked when the user attempts an invalid operation. The default |
| * implementation just beeps. Subclasses that wish to change this need to |
| * override this method. |
| * |
| * @param component the component the error occured in |
| */ |
| public void provideErrorFeedback(Component component) |
| { |
| Toolkit.getDefaultToolkit().beep(); |
| } |
| |
| /** |
| * Returns a string that displays and identifies this object's properties. |
| * |
| * @return string containing the description and class name. |
| */ |
| public String toString() |
| { |
| return getDescription() + " " + getClass().getName(); |
| } |
| |
| /** |
| * UIManager.setLookAndFeel calls this method just before we're replaced by |
| * a new default look and feel. |
| */ |
| public void uninitialize() |
| { |
| // We do nothing here. This method is meant to be overridden by |
| // LookAndFeel implementations. |
| } |
| |
| /** |
| * Convenience method for un-installing a component's default border on the |
| * specified component if the border is currently an instance of UIResource. |
| * |
| * @param c the component (<code>null</code> not permitted). |
| */ |
| public static void uninstallBorder(JComponent c) |
| { |
| if (c.getBorder() instanceof UIResource) |
| c.setBorder(null); |
| } |
| |
| /** |
| * This methods installs a UI property if it hasn't already been set by an |
| * application. This method is used by UI delegates that install a default |
| * value for a property with a primitive type but do not want to override |
| * a value that has been set by an application. |
| * |
| * The supported properties depend on the actual type of the component and |
| * are listed in the table below. The supported properties are of course |
| * inherited to subclasses. |
| * |
| * <table> |
| * <tr><th>Type</th><th>Supported properties</th></tr> |
| * <tr><td><code>JComponent</code></td> |
| * <td><code>opaque, autoscrolls</code></td></tr> |
| * <tr><td><code>AbstractButton</code></td> |
| * <td><code>borderPainted, rolloverEnabled, iconTextGap, |
| * contentAreaFilled</code></td></tr> |
| * <tr><td><code>JDesktopPane</code></td> |
| * <td><code>dragMode</code></td></tr> |
| * <tr><td><code>JSplitPane</code></td> |
| * <td><code>dividerSize, oneTouchExpandable</code></td></tr> |
| * <tr><td><code>JTable</code></td> |
| * <td><code>rowHeight</code></td></tr> |
| * <tr><td><code>JTree</code></td> |
| * <td><code>rowHeight, scrollsOnExpand, showsRootHandles</code></td></tr> |
| * </table> |
| * |
| * @param c the component to install the property to |
| * @param propertyName the name of the property |
| * @param value the value of the property |
| * |
| * @throws IllegalArgumentException if the specified property cannot be set |
| * by this method |
| * @throws ClassCastException if the property value does not match the |
| * property type |
| * @throws NullPointerException if <code>c</code> or |
| * <code>propertyValue</code> is <code>null</code> |
| * |
| * @since 1.5 |
| */ |
| public static void installProperty(JComponent c, String propertyName, |
| Object value) |
| { |
| c.setUIProperty(propertyName, value); |
| } |
| } |