Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.swing;
   27   
   28   import java.awt.Font;
   29   import java.awt.event.InputEvent;
   30   import java.awt.event.KeyEvent;
   31   import java.awt.Color;
   32   import java.awt.Component;
   33   import java.awt.SystemColor;
   34   import java.awt.Toolkit;
   35   import sun.awt.SunToolkit;
   36   
   37   import javax.swing.text;
   38   import javax.swing.border;
   39   import javax.swing.plaf;
   40   
   41   import java.net.URL;
   42   import sun.swing.SwingUtilities2;
   43   import sun.swing.DefaultLayoutStyle;
   44   import sun.swing.ImageIconUIResource;
   45   
   46   import java.util.StringTokenizer;
   47   
   48   
   49   /**
   50    * {@code LookAndFeel}, as the name implies, encapsulates a look and
   51    * feel. Beyond installing a look and feel most developers never need to
   52    * interact directly with {@code LookAndFeel}. In general only developers
   53    * creating a custom look and feel need to concern themselves with this class.
   54    * <p>
   55    * Swing is built upon the foundation that each {@code JComponent}
   56    * subclass has an implementation of a specific {@code ComponentUI}
   57    * subclass. The {@code ComponentUI} is often referred to as "the ui",
   58    * "component ui", or "look and feel delegate". The {@code ComponentUI}
   59    * subclass is responsible for providing the look and feel specific
   60    * functionality of the component. For example, {@code JTree} requires
   61    * an implementation of the {@code ComponentUI} subclass {@code
   62    * TreeUI}. The implementation of the specific {@code
   63    * ComponentUI} subclass is provided by the {@code LookAndFeel}. Each
   64    * {@code JComponent} subclass identifies the {@code ComponentUI}
   65    * subclass it requires by way of the {@code JComponent} method {@code
   66    * getUIClassID}.
   67    * <p>
   68    * Each {@code LookAndFeel} implementation must provide
   69    * an implementation of the appropriate {@code ComponentUI} subclass by
   70    * specifying a value for each of Swing's ui class ids in the {@code
   71    * UIDefaults} object returned from {@code getDefaults}. For example,
   72    * {@code BasicLookAndFeel} uses {@code BasicTreeUI} as the concrete
   73    * implementation for {@code TreeUI}. This is accomplished by {@code
   74    * BasicLookAndFeel} providing the key-value pair {@code
   75    * "TreeUI"-"javax.swing.plaf.basic.BasicTreeUI"}, in the
   76    * {@code UIDefaults} returned from {@code getDefaults}. Refer to
   77    * {@link UIDefaults#getUI(JComponent)} for defails on how the implementation
   78    * of the {@code ComponentUI} subclass is obtained.
   79    * <p>
   80    * When a {@code LookAndFeel} is installed the {@code UIManager} does
   81    * not check that an entry exists for all ui class ids. As such,
   82    * random exceptions will occur if the current look and feel has not
   83    * provided a value for a particular ui class id and an instance of
   84    * the {@code JComponent} subclass is created.
   85    *
   86    * <h2>Recommendations for Look and Feels</h2>
   87    *
   88    * As noted in {@code UIManager} each {@code LookAndFeel} has the opportunity
   89    * to provide a set of defaults that are layered in with developer and
   90    * system defaults. Some of Swing's components require the look and feel
   91    * to provide a specific set of defaults. These are documented in the
   92    * classes that require the specific default.
   93    *
   94    * <h3><a name="#defaultRecommendation">ComponentUIs and defaults</a></h2>
   95    *
   96    * All {@code ComponentUIs} typically need to set various properties
   97    * on the {@code JComponent} the {@code ComponentUI} is providing the
   98    * look and feel for. This is typically done when the {@code
   99    * ComponentUI} is installed on the {@code JComponent}. Setting a
  100    * property should only be done if the developer has not set the
  101    * property. For non-primitive values it is recommended that the
  102    * {@code ComponentUI} only change the property on the {@code
  103    * JComponent} if the current value is {@code null} or implements
  104    * {@code UIResource}. If the current value is {@code null} or
  105    * implements {@code UIResource} it indicates the property has not
  106    * been set by the developer, and the ui is free to change it.  For
  107    * example, {@code BasicButtonUI.installDefaults} only changes the
  108    * font on the {@code JButton} if the return value from {@code
  109    * button.getFont()} is {@code null} or implements {@code
  110    * UIResource}. On the other hand if {@code button.getFont()} returned
  111    * a {@code non-null} value that did not implement {@code UIResource}
  112    * then {@code BasicButtonUI.installDefaults} would not change the
  113    * {@code JButton}'s font.
  114    * <p>
  115    * For primitive values, such as {@code opaque}, the method {@code
  116    * installProperty} should be invoked.  {@code installProperty} only changes
  117    * the correspoding property if the value has not been changed by the
  118    * developer.
  119    * <p>
  120    * {@code ComponentUI} implementations should use the various install methods
  121    * provided by this class as they handle the necessary checking and install
  122    * the property using the recommended guidelines.
  123    * <p>
  124    * <h3><a name="exceptions"></a>Exceptions</h3>
  125    *
  126    * All of the install methods provided by {@code LookAndFeel} need to
  127    * access the defaults if the value of the property being changed is
  128    * {@code null} or a {@code UIResource}. For example, installing the
  129    * font does the following:
  130    * <pre>
  131    *   JComponent c;
  132    *   Font font = c.getFont();
  133    *   if (font == null || (font instanceof UIResource)) {
  134    *       c.setFont(UIManager.getFont("fontKey"));
  135    *   }
  136    * </pre>
  137    * If the font is {@code null} or a {@code UIResource}, the
  138    * defaults table is queried with the key {@code fontKey}. All of
  139    * {@code UIDefault's} get methods throw a {@code
  140    * NullPointerException} if passed in {@code null}. As such, unless
  141    * otherwise noted each of the various install methods of {@code
  142    * LookAndFeel} throw a {@code NullPointerException} if the current
  143    * value is {@code null} or a {@code UIResource} and the supplied
  144    * defaults key is {@code null}. In addition, unless otherwise specified
  145    * all of the {@code install} methods throw a {@code NullPointerException} if
  146    * a {@code null} component is passed in.
  147    *
  148    * @author Tom Ball
  149    * @author Hans Muller
  150    */
  151   public abstract class LookAndFeel
  152   {
  153   
  154       /**
  155        * Convenience method for setting a component's foreground
  156        * and background color properties with values from the
  157        * defaults.  The properties are only set if the current
  158        * value is either {@code null} or a {@code UIResource}.
  159        *
  160        * @param c component to set the colors on
  161        * @param defaultBgName key for the background
  162        * @param defaultFgName key for the foreground
  163        *
  164        * @see #installColorsAndFont
  165        * @see UIManager#getColor
  166        * @throws NullPointerException as described in
  167        *         <a href="#exceptions">exceptions</a>
  168        */
  169       public static void installColors(JComponent c,
  170                                        String defaultBgName,
  171                                        String defaultFgName)
  172       {
  173           Color bg = c.getBackground();
  174           if (bg == null || bg instanceof UIResource) {
  175               c.setBackground(UIManager.getColor(defaultBgName));
  176           }
  177   
  178           Color fg = c.getForeground();
  179           if (fg == null || fg instanceof UIResource) {
  180               c.setForeground(UIManager.getColor(defaultFgName));
  181           }
  182       }
  183   
  184   
  185       /**
  186        * Convenience method for setting a component's foreground,
  187        * background and font properties with values from the
  188        * defaults.  The properties are only set if the current
  189        * value is either {@code null} or a {@code UIResource}.
  190        *
  191        * @param c component set to the colors and font on
  192        * @param defaultBgName key for the background
  193        * @param defaultFgName key for the foreground
  194        * @param defaultFontName key for the font
  195        * @throws NullPointerException as described in
  196        *         <a href="#exceptions">exceptions</a>
  197        *
  198        * @see #installColors
  199        * @see UIManager#getColor
  200        * @see UIManager#getFont
  201        */
  202       public static void installColorsAndFont(JComponent c,
  203                                            String defaultBgName,
  204                                            String defaultFgName,
  205                                            String defaultFontName) {
  206           Font f = c.getFont();
  207           if (f == null || f instanceof UIResource) {
  208               c.setFont(UIManager.getFont(defaultFontName));
  209           }
  210   
  211           installColors(c, defaultBgName, defaultFgName);
  212       }
  213   
  214   
  215       /**
  216        * Convenience method for setting a component's border property with
  217        * a value from the defaults. The border is only set if the border is
  218        * {@code null} or an instance of {@code UIResource}.
  219        *
  220        * @param c component to set the border on
  221        * @param defaultBorderName key specifying the border
  222        * @throws NullPointerException as described in
  223        *         <a href="#exceptions">exceptions</a>
  224        */
  225       public static void installBorder(JComponent c, String defaultBorderName) {
  226           Border b = c.getBorder();
  227           if (b == null || b instanceof UIResource) {
  228               c.setBorder(UIManager.getBorder(defaultBorderName));
  229           }
  230       }
  231   
  232   
  233       /**
  234        * Convenience method for uninstalling a border. If the border of
  235        * the component is a {@code UIResource}, it is set to {@code
  236        * null}.
  237        *
  238        * @param c component to uninstall the border on
  239        * @throws NullPointerException if {@code c} is {@code null}
  240        */
  241       public static void uninstallBorder(JComponent c) {
  242           if (c.getBorder() instanceof UIResource) {
  243               c.setBorder(null);
  244           }
  245       }
  246   
  247       /**
  248        * Convenience method for installing a property with the specified name
  249        * and value on a component if that property has not already been set
  250        * by the developer.  This method is intended to be used by
  251        * ui delegate instances that need to specify a default value for a
  252        * property of primitive type (boolean, int, ..), but do not wish
  253        * to override a value set by the client.  Since primitive property
  254        * values cannot be wrapped with the {@code UIResource} marker, this method
  255        * uses private state to determine whether the property has been set
  256        * by the client.
  257        *
  258        * @throws IllegalArgumentException if the specified property is not
  259        *         one which can be set using this method
  260        * @throws ClassCastException if the property value has not been set
  261        *         by the developer and the type does not match the property's type
  262        * @throws NullPointerException if {@code c} is {@code null}, or the
  263        *         named property has not been set by the developer and
  264        *         {@code propertyValue} is {@code null}
  265        * @param c target component to set the property on
  266        * @param propertyName name of the property to set
  267        * @param propertyValue value of the property
  268        * @since 1.5
  269        */
  270       public static void installProperty(JComponent c,
  271                                          String propertyName, Object propertyValue) {
  272           // this is a special case because the JPasswordField's ancestor heirarchy
  273           // includes a class outside of javax.swing, thus we cannot call setUIProperty
  274           // directly.
  275           if (SunToolkit.isInstanceOf(c, "javax.swing.JPasswordField")) {
  276               if (!((JPasswordField)c).customSetUIProperty(propertyName, propertyValue)) {
  277                   c.setUIProperty(propertyName, propertyValue);
  278               }
  279           } else {
  280               c.setUIProperty(propertyName, propertyValue);
  281           }
  282       }
  283   
  284       /**
  285        * Convenience method for building an array of {@code
  286        * KeyBindings}. While this method is not deprecated, developers
  287        * should instead use {@code ActionMap} and {@code InputMap} for
  288        * supplying key bindings.
  289        * <p>
  290        * This method returns an array of {@code KeyBindings}, one for each
  291        * alternating {@code key-action} pair in {@code keyBindingList}.
  292        * A {@code key} can either be a {@code String} in the format
  293        * specified by the <code>KeyStroke.getKeyStroke</code> method, or
  294        * a {@code KeyStroke}. The {@code action} part of the pair is a
  295        * {@code String} that corresponds to the name of the {@code
  296        * Action}.
  297        * <p>
  298        * The following example illustrates creating a {@code KeyBinding} array
  299        * from six alternating {@code key-action} pairs:
  300        * <pre>
  301        *  JTextComponent.KeyBinding[] multilineBindings = makeKeyBindings( new Object[] {
  302        *          "UP", DefaultEditorKit.upAction,
  303        *        "DOWN", DefaultEditorKit.downAction,
  304        *     "PAGE_UP", DefaultEditorKit.pageUpAction,
  305        *   "PAGE_DOWN", DefaultEditorKit.pageDownAction,
  306        *       "ENTER", DefaultEditorKit.insertBreakAction,
  307        *         "TAB", DefaultEditorKit.insertTabAction
  308        *  });
  309        * </pre>
  310        * If {@code keyBindingList's} length is odd, the last element is
  311        * ignored.
  312        * <p>
  313        * Supplying a {@code null} value for either the {@code key} or
  314        * {@code action} part of the {@code key-action} pair results in
  315        * creating a {@code KeyBinding} with the corresponding value
  316        * {@code null}. As other parts of Swing's expect {@code non-null} values
  317        * in a {@code KeyBinding}, you should avoid supplying {@code null} as
  318        * either the {@code key} or {@code action} part of the {@code key-action}
  319        * pair.
  320        *
  321        * @param keyBindingList an array of {@code key-action} pairs
  322        * @return an array of {@code KeyBindings}
  323        * @throws NullPointerException if {@code keyBindingList} is {@code null}
  324        * @throws ClassCastException if the {@code key} part of the pair is
  325        *         not a {@code KeyStroke} or {@code String}, or the
  326        *         {@code action} part of the pair is not a {@code String}
  327        * @see ActionMap
  328        * @see InputMap
  329        * @see KeyStroke#getKeyStroke
  330        */
  331       public static JTextComponent.KeyBinding[] makeKeyBindings(Object[] keyBindingList)
  332       {
  333           JTextComponent.KeyBinding[] rv = new JTextComponent.KeyBinding[keyBindingList.length / 2];
  334   
  335           for(int i = 0; i < rv.length; i ++) {
  336               Object o = keyBindingList[2 * i];
  337               KeyStroke keystroke = (o instanceof KeyStroke)
  338                   ? (KeyStroke) o
  339                   : KeyStroke.getKeyStroke((String) o);
  340               String action = (String) keyBindingList[2 * i + 1];
  341               rv[i] = new JTextComponent.KeyBinding(keystroke, action);
  342           }
  343   
  344           return rv;
  345       }
  346   
  347       /**
  348        * Creates a {@code InputMapUIResource} from <code>keys</code>. This is
  349        * a convenience method for creating a new {@code InputMapUIResource},
  350        * invoking {@code loadKeyBindings(map, keys)}, and returning the
  351        * {@code InputMapUIResource}.
  352        *
  353        * @param keys alternating pairs of {@code keystroke-action key}
  354        *        pairs as described in {@link #loadKeyBindings}
  355        * @return newly created and populated {@code InputMapUIResource}
  356        * @see #loadKeyBindings
  357        *
  358        * @since 1.3
  359        */
  360       public static InputMap makeInputMap(Object[] keys) {
  361           InputMap retMap = new InputMapUIResource();
  362           loadKeyBindings(retMap, keys);
  363           return retMap;
  364       }
  365   
  366       /**
  367        * Creates a {@code ComponentInputMapUIResource} from
  368        * <code>keys</code>. This is a convenience method for creating a
  369        * new {@code ComponentInputMapUIResource}, invoking {@code
  370        * loadKeyBindings(map, keys)}, and returning the {@code
  371        * ComponentInputMapUIResource}.
  372        *
  373        * @param c component to create the {@code ComponentInputMapUIResource}
  374        *          with
  375        * @param keys alternating pairs of {@code keystroke-action key}
  376        *        pairs as described in {@link #loadKeyBindings}
  377        * @return newly created and populated {@code InputMapUIResource}
  378        * @throws IllegalArgumentException if {@code c} is {@code null}
  379        *
  380        * @see #loadKeyBindings
  381        * @see ComponentInputMapUIResource
  382        *
  383        * @since 1.3
  384        */
  385       public static ComponentInputMap makeComponentInputMap(JComponent c,
  386                                                             Object[] keys) {
  387           ComponentInputMap retMap = new ComponentInputMapUIResource(c);
  388           loadKeyBindings(retMap, keys);
  389           return retMap;
  390       }
  391   
  392   
  393       /**
  394        * Populates an {@code InputMap} with the specified bindings.
  395        * The bindings are supplied as a list of alternating
  396        * {@code keystroke-action key} pairs. The {@code keystroke} is either
  397        * an instance of {@code KeyStroke}, or a {@code String}
  398        * that identifies the {@code KeyStroke} for the binding. Refer
  399        * to {@code KeyStroke.getKeyStroke(String)} for the specific
  400        * format. The {@code action key} part of the pair is the key
  401        * registered in the {@code InputMap} for the {@code KeyStroke}.
  402        * <p>
  403        * The following illustrates loading an {@code InputMap} with two
  404        * {@code key-action} pairs:
  405        * <pre>
  406        *   LookAndFeel.loadKeyBindings(inputMap, new Object[] {
  407        *     "control X", "cut",
  408        *     "control V", "paste"
  409        *   });
  410        * </pre>
  411        * <p>
  412        * Supplying a {@code null} list of bindings ({@code keys}) does not
  413        * change {@code retMap} in any way.
  414        * <p>
  415        * Specifying a {@code null} {@code action key} results in
  416        * removing the {@code keystroke's} entry from the {@code InputMap}.
  417        * A {@code null} {@code keystroke} is ignored.
  418        *
  419        * @param retMap {@code InputMap} to add the {@code key-action}
  420        *               pairs to
  421        * @param keys bindings to add to {@code retMap}
  422        * @throws NullPointerException if {@code keys} is
  423        *         {@code non-null}, not empty, and {@code retMap} is
  424        *         {@code null}
  425        *
  426        * @see KeyStroke#getKeyStroke(String)
  427        * @see InputMap
  428        *
  429        * @since 1.3
  430        */
  431       public static void loadKeyBindings(InputMap retMap, Object[] keys) {
  432           if (keys != null) {
  433               for (int counter = 0, maxCounter = keys.length;
  434                    counter < maxCounter; counter++) {
  435                   Object keyStrokeO = keys[counter++];
  436                   KeyStroke ks = (keyStrokeO instanceof KeyStroke) ?
  437                                   (KeyStroke)keyStrokeO :
  438                                   KeyStroke.getKeyStroke((String)keyStrokeO);
  439                   retMap.put(ks, keys[counter]);
  440               }
  441           }
  442       }
  443   
  444       /**
  445        * Creates and returns a {@code UIDefault.LazyValue} that loads an
  446        * image. The returned value is an implementation of {@code
  447        * UIDefaults.LazyValue}. When {@code createValue} is invoked on
  448        * the returned object, the image is loaded. If the image is {@code
  449        * non-null}, it is then wrapped in an {@code Icon} that implements {@code
  450        * UIResource}. The image is loaded using {@code
  451        * Class.getResourceAsStream(gifFile)}.
  452        * <p>
  453        * This method does not check the arguments in any way. It is
  454        * strongly recommended that {@code non-null} values are supplied else
  455        * exceptions may occur when {@code createValue} is invoked on the
  456        * returned object.
  457        *
  458        * @param baseClass {@code Class} used to load the resource
  459        * @param gifFile path to the image to load
  460        * @return a {@code UIDefaults.LazyValue}; when resolved the
  461        *         {@code LazyValue} loads the specified image
  462        * @see UIDefaults.LazyValue
  463        * @see Icon
  464        * @see Class#getResourceAsStream(String)
  465        */
  466       public static Object makeIcon(final Class<?> baseClass, final String gifFile) {
  467           return SwingUtilities2.makeIcon(baseClass, baseClass, gifFile);
  468       }
  469   
  470       /**
  471        * Returns the <code>LayoutStyle</code> for this look
  472        * and feel.  This never returns {@code null}.
  473        * <p>
  474        * You generally don't use the <code>LayoutStyle</code> from
  475        * the look and feel, instead use the <code>LayoutStyle</code>
  476        * method <code>getInstance</code>.
  477        *
  478        * @see LayoutStyle#getInstance
  479        * @return the <code>LayoutStyle</code> for this look and feel
  480        * @since 1.6
  481        */
  482       public LayoutStyle getLayoutStyle() {
  483           return DefaultLayoutStyle.getInstance();
  484       }
  485   
  486       /**
  487        * Invoked when the user attempts an invalid operation,
  488        * such as pasting into an uneditable <code>JTextField</code>
  489        * that has focus. The default implementation beeps. Subclasses
  490        * that wish different behavior should override this and provide
  491        * the additional feedback.
  492        *
  493        * @param component the <code>Component</code> the error occurred in,
  494        *                  may be <code>null</code>
  495        *                  indicating the error condition is not directly
  496        *                  associated with a <code>Component</code>
  497        * @since 1.4
  498        */
  499       public void provideErrorFeedback(Component component) {
  500           Toolkit toolkit = null;
  501           if (component != null) {
  502               toolkit = component.getToolkit();
  503           } else {
  504               toolkit = Toolkit.getDefaultToolkit();
  505           }
  506           toolkit.beep();
  507       } // provideErrorFeedback()
  508   
  509       /**
  510        * Returns the value of the specified system desktop property by
  511        * invoking <code>Toolkit.getDefaultToolkit().getDesktopProperty()</code>.
  512        * If the value of the specified property is {@code null},
  513        * {@code fallbackValue} is returned.
  514        *
  515        * @param systemPropertyName the name of the system desktop property being queried
  516        * @param fallbackValue the object to be returned as the value if the system value is null
  517        * @return the current value of the desktop property
  518        *
  519        * @see java.awt.Toolkit#getDesktopProperty
  520        *
  521        * @since 1.4
  522        */
  523       public static Object getDesktopPropertyValue(String systemPropertyName, Object fallbackValue) {
  524           Object value = Toolkit.getDefaultToolkit().getDesktopProperty(systemPropertyName);
  525           if (value == null) {
  526               return fallbackValue;
  527           } else if (value instanceof Color) {
  528               return new ColorUIResource((Color)value);
  529           } else if (value instanceof Font) {
  530               return new FontUIResource((Font)value);
  531           }
  532           return value;
  533       }
  534   
  535       /**
  536        * Returns an <code>Icon</code> with a disabled appearance.
  537        * This method is used to generate a disabled <code>Icon</code> when
  538        * one has not been specified.  For example, if you create a
  539        * <code>JButton</code> and only specify an <code>Icon</code> via
  540        * <code>setIcon</code> this method will be called to generate the
  541        * disabled <code>Icon</code>. If {@code null} is passed as
  542        * <code>icon</code> this method returns {@code null}.
  543        * <p>
  544        * Some look and feels might not render the disabled {@code Icon}, in which
  545        * case they will ignore this.
  546        *
  547        * @param component {@code JComponent} that will display the {@code Icon},
  548        *         may be {@code null}
  549        * @param icon {@code Icon} to generate the disabled icon from
  550        * @return disabled {@code Icon}, or {@code null} if a suitable
  551        *         {@code Icon} can not be generated
  552        * @since 1.5
  553        */
  554       public Icon getDisabledIcon(JComponent component, Icon icon) {
  555           if (icon instanceof ImageIcon) {
  556               return new ImageIconUIResource(GrayFilter.
  557                      createDisabledImage(((ImageIcon)icon).getImage()));
  558           }
  559           return null;
  560       }
  561   
  562       /**
  563        * Returns an <code>Icon</code> for use by disabled
  564        * components that are also selected. This method is used to generate an
  565        * <code>Icon</code> for components that are in both the disabled and
  566        * selected states but do not have a specific <code>Icon</code> for this
  567        * state.  For example, if you create a <code>JButton</code> and only
  568        * specify an <code>Icon</code> via <code>setIcon</code> this method
  569        * will be called to generate the disabled and selected
  570        * <code>Icon</code>. If {@code null} is passed as <code>icon</code> this
  571        * methods returns {@code null}.
  572        * <p>
  573        * Some look and feels might not render the disabled and selected
  574        * {@code Icon}, in which case they will ignore this.
  575        *
  576        * @param component {@code JComponent} that will display the {@code Icon},
  577        *        may be {@code null}
  578        * @param icon {@code Icon} to generate disabled and selected icon from
  579        * @return disabled and selected icon, or {@code null} if a suitable
  580        *         {@code Icon} can not be generated.
  581        * @since 1.5
  582        */
  583       public Icon getDisabledSelectedIcon(JComponent component, Icon icon) {
  584           return getDisabledIcon(component, icon);
  585       }
  586   
  587       /**
  588        * Return a short string that identifies this look and feel, e.g.
  589        * "CDE/Motif".  This string should be appropriate for a menu item.
  590        * Distinct look and feels should have different names, e.g.
  591        * a subclass of MotifLookAndFeel that changes the way a few components
  592        * are rendered should be called "CDE/Motif My Way"; something
  593        * that would be useful to a user trying to select a L&F from a list
  594        * of names.
  595        *
  596        * @return short identifier for the look and feel
  597        */
  598       public abstract String getName();
  599   
  600   
  601       /**
  602        * Return a string that identifies this look and feel.  This string
  603        * will be used by applications/services that want to recognize
  604        * well known look and feel implementations.  Presently
  605        * the well known names are "Motif", "Windows", "Mac", "Metal".  Note
  606        * that a LookAndFeel derived from a well known superclass
  607        * that doesn't make any fundamental changes to the look or feel
  608        * shouldn't override this method.
  609        *
  610        * @return identifier for the look and feel
  611        */
  612       public abstract String getID();
  613   
  614   
  615       /**
  616        * Return a one line description of this look and feel implementation,
  617        * e.g. "The CDE/Motif Look and Feel".   This string is intended for
  618        * the user, e.g. in the title of a window or in a ToolTip message.
  619        *
  620        * @return short description for the look and feel
  621        */
  622       public abstract String getDescription();
  623   
  624   
  625       /**
  626        * Returns {@code true} if the <code>LookAndFeel</code> returned
  627        * <code>RootPaneUI</code> instances support providing {@code Window}
  628        * decorations in a <code>JRootPane</code>.
  629        * <p>
  630        * The default implementation returns {@code false}, subclasses that
  631        * support {@code Window} decorations should override this and return
  632        * {@code true}.
  633        *
  634        * @return {@code true} if the {@code RootPaneUI} instances created by
  635        *         this look and feel support client side decorations
  636        * @see JDialog#setDefaultLookAndFeelDecorated
  637        * @see JFrame#setDefaultLookAndFeelDecorated
  638        * @see JRootPane#setWindowDecorationStyle
  639        * @since 1.4
  640        */
  641       public boolean getSupportsWindowDecorations() {
  642           return false;
  643       }
  644   
  645       /**
  646        * If the underlying platform has a "native" look and feel, and
  647        * this is an implementation of it, return {@code true}.  For
  648        * example, when the underlying platform is Solaris running CDE
  649        * a CDE/Motif look and feel implementation would return {@code
  650        * true}.
  651        *
  652        * @return {@code true} if this look and feel represents the underlying
  653        *         platform look and feel
  654        */
  655       public abstract boolean isNativeLookAndFeel();
  656   
  657   
  658       /**
  659        * Return {@code true} if the underlying platform supports and or permits
  660        * this look and feel.  This method returns {@code false} if the look
  661        * and feel depends on special resources or legal agreements that
  662        * aren't defined for the current platform.
  663        *
  664        *
  665        * @return {@code true} if this is a supported look and feel
  666        * @see UIManager#setLookAndFeel
  667        */
  668       public abstract boolean isSupportedLookAndFeel();
  669   
  670   
  671       /**
  672        * Initializes the look and feel. While this method is public,
  673        * it should only be invoked by the {@code UIManager} when a
  674        * look and feel is installed as the current look and feel. This
  675        * method is invoked before the {@code UIManager} invokes
  676        * {@code getDefaults}. This method is intended to perform any
  677        * initialization for the look and feel. Subclasses
  678        * should do any one-time setup they need here, rather than
  679        * in a static initializer, because look and feel class objects
  680        * may be loaded just to discover that {@code isSupportedLookAndFeel()}
  681        * returns {@code false}.
  682        *
  683        * @see #uninitialize
  684        * @see UIManager#setLookAndFeel
  685        */
  686       public void initialize() {
  687       }
  688   
  689   
  690       /**
  691        * Uninitializes the look and feel. While this method is public,
  692        * it should only be invoked by the {@code UIManager} when
  693        * the look and feel is uninstalled. For example,
  694        * {@code UIManager.setLookAndFeel} invokes this when the look and
  695        * feel is changed.
  696        * <p>
  697        * Subclasses may choose to free up some resources here.
  698        *
  699        * @see #initialize
  700        * @see UIManager#setLookAndFeel
  701        */
  702       public void uninitialize() {
  703       }
  704   
  705       /**
  706        * Returns the look and feel defaults. While this method is public,
  707        * it should only be invoked by the {@code UIManager} when the
  708        * look and feel is set as the current look and feel and after
  709        * {@code initialize} has been invoked.
  710        *
  711        * @return the look and feel defaults
  712        * @see #initialize
  713        * @see #uninitialize
  714        * @see UIManager#setLookAndFeel
  715        */
  716       public UIDefaults getDefaults() {
  717           return null;
  718       }
  719   
  720       /**
  721        * Returns a string that displays and identifies this
  722        * object's properties.
  723        *
  724        * @return a String representation of this object
  725        */
  726       public String toString() {
  727           return "[" + getDescription() + " - " + getClass().getName() + "]";
  728       }
  729   }

Home » openjdk-7 » javax » swing » [javadoc | source]