Merged gcj-eclipse branch to trunk.
[official-gcc.git] / libjava / classpath / javax / swing / UIManager.java
blob3b1b3f72b387b0881daa3ba94fd4df5ebb0f3fb5
1 /* UIManager.java --
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
39 package javax.swing;
41 import java.awt.Color;
42 import java.awt.Dimension;
43 import java.awt.Font;
44 import java.awt.Insets;
45 import java.beans.PropertyChangeListener;
46 import java.beans.PropertyChangeSupport;
47 import java.io.Serializable;
48 import java.util.Enumeration;
49 import java.util.Locale;
51 import javax.swing.border.Border;
52 import javax.swing.plaf.ComponentUI;
53 import javax.swing.plaf.metal.MetalLookAndFeel;
55 /**
56 * Manages the current {@link LookAndFeel} and any auxiliary {@link LookAndFeel}
57 * instances.
59 public class UIManager implements Serializable
61 /**
62 * Represents the basic information about a {@link LookAndFeel} (LAF), so
63 * that a list of installed LAFs can be presented without actually loading
64 * the LAF class(es).
66 public static class LookAndFeelInfo
68 String name, clazz;
70 /**
71 * Creates a new instance.
73 * @param name the look and feel name.
74 * @param clazz the look and feel class name.
76 public LookAndFeelInfo(String name,
77 String clazz)
79 this.name = name;
80 this.clazz = clazz;
83 /**
84 * Returns the name of the look and feel.
86 * @return The name of the look and feel.
88 public String getName()
90 return name;
93 /**
94 * Returns the fully qualified class name for the {@link LookAndFeel}.
96 * @return The fully qualified class name for the {@link LookAndFeel}.
98 public String getClassName()
100 return clazz;
104 * Returns a String representation of the LookAndFeelInfo object.
106 * @return a String representation of the LookAndFeelInfo object
108 public String toString()
110 StringBuffer s = new StringBuffer();
111 s.append(getClass().getName());
112 s.append('[');
113 s.append(getName());
114 s.append(' ');
115 s.append(getClassName());
116 s.append(']');
117 return s.toString();
122 * A UIDefaults subclass that multiplexes between itself and a 'fallback'
123 * UIDefaults instance. This is used to protect the L&F UIDefaults from beeing
124 * overwritten by applications.
126 private static class MultiplexUIDefaults
127 extends UIDefaults
129 private class MultiplexEnumeration
130 implements Enumeration
132 Enumeration[] enums;
133 int i;
134 MultiplexEnumeration(Enumeration e1, Enumeration e2)
136 enums = new Enumeration[]{ e1, e2 };
137 i = 0;
140 public boolean hasMoreElements()
142 return enums[i].hasMoreElements() || i < enums.length - 1;
145 public Object nextElement()
147 Object val = enums[i].nextElement();
148 if (! enums[i].hasMoreElements() && i < enums.length - 1)
149 i++;
150 return val;
155 UIDefaults fallback;
158 * Creates a new <code>MultiplexUIDefaults</code> instance with
159 * <code>d</code> as the fallback defaults.
161 * @param d the fallback defaults (<code>null</code> not permitted).
163 MultiplexUIDefaults(UIDefaults d)
165 if (d == null)
166 throw new NullPointerException();
167 fallback = d;
170 public Object get(Object key)
172 Object val = super.get(key);
173 if (val == null)
174 val = fallback.get(key);
175 return val;
178 public Object get(Object key, Locale l)
180 Object val = super.get(key, l);
181 if (val == null)
182 val = fallback.get(key, l);
183 return val;
186 public Object remove(Object key)
188 Object val = super.remove(key);
189 if (val == null)
190 val = fallback.remove(key);
191 return val;
194 public int size()
196 return super.size() + fallback.size();
199 public Enumeration keys()
201 return new MultiplexEnumeration(super.keys(), fallback.keys());
204 public Enumeration elements()
206 return new MultiplexEnumeration(super.elements(), fallback.elements());
210 private static final long serialVersionUID = -5547433830339189365L;
212 /** The installed look and feel(s). */
213 static LookAndFeelInfo [] installed = {
214 new LookAndFeelInfo("Metal", "javax.swing.plaf.metal.MetalLookAndFeel"),
215 new LookAndFeelInfo("GNU", "gnu.javax.swing.plaf.gnu.GNULookAndFeel")
218 /** The installed auxiliary look and feels. */
219 static LookAndFeel[] auxLookAndFeels;
221 /** The current look and feel. */
222 static LookAndFeel currentLookAndFeel;
224 static MultiplexUIDefaults currentUIDefaults;
226 static UIDefaults lookAndFeelDefaults;
228 /** Property change listener mechanism. */
229 static PropertyChangeSupport listeners
230 = new PropertyChangeSupport(UIManager.class);
232 static
234 String defaultlaf = System.getProperty("swing.defaultlaf");
235 try
237 if (defaultlaf != null)
239 setLookAndFeel(defaultlaf);
241 else
243 setLookAndFeel(new MetalLookAndFeel());
246 catch (Exception ex)
248 System.err.println("cannot initialize Look and Feel: " + defaultlaf);
249 System.err.println("error: " + ex.toString());
250 ex.printStackTrace();
251 System.err.println("falling back to Metal Look and Feel");
254 setLookAndFeel(new MetalLookAndFeel());
256 catch (Exception ex2)
258 throw (Error) new AssertionError("There must be no problem installing"
259 + " the MetalLookAndFeel.")
260 .initCause(ex2);
266 * Creates a new instance of the <code>UIManager</code>. There is no need
267 * to construct an instance of this class, since all methods are static.
269 public UIManager()
271 // Do nothing here.
275 * Add a <code>PropertyChangeListener</code> to the listener list.
277 * @param listener the listener to add
279 public static void addPropertyChangeListener(PropertyChangeListener listener)
281 listeners.addPropertyChangeListener(listener);
285 * Remove a <code>PropertyChangeListener</code> from the listener list.
287 * @param listener the listener to remove
289 public static void removePropertyChangeListener(PropertyChangeListener
290 listener)
292 listeners.removePropertyChangeListener(listener);
296 * Returns an array of all added <code>PropertyChangeListener</code> objects.
298 * @return an array of listeners
300 * @since 1.4
302 public static PropertyChangeListener[] getPropertyChangeListeners()
304 return listeners.getPropertyChangeListeners();
308 * Add a {@link LookAndFeel} to the list of auxiliary look and feels.
310 * @param laf the auxiliary look and feel (<code>null</code> not permitted).
312 * @throws NullPointerException if <code>laf</code> is <code>null</code>.
314 * @see #getAuxiliaryLookAndFeels()
316 public static void addAuxiliaryLookAndFeel(LookAndFeel laf)
318 if (laf == null)
319 throw new NullPointerException("Null 'laf' argument.");
320 if (auxLookAndFeels == null)
322 auxLookAndFeels = new LookAndFeel[1];
323 auxLookAndFeels[0] = laf;
324 return;
327 LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length + 1];
328 System.arraycopy(auxLookAndFeels, 0, temp, 0, auxLookAndFeels.length);
329 auxLookAndFeels = temp;
330 auxLookAndFeels[auxLookAndFeels.length - 1] = laf;
334 * Removes a {@link LookAndFeel} (LAF) from the list of auxiliary LAFs.
336 * @param laf the LAF to remove.
338 * @return <code>true</code> if the LAF was removed, and <code>false</code>
339 * otherwise.
341 public static boolean removeAuxiliaryLookAndFeel(LookAndFeel laf)
343 if (auxLookAndFeels == null)
344 return false;
345 int count = auxLookAndFeels.length;
346 if (count == 1 && auxLookAndFeels[0] == laf)
348 auxLookAndFeels = null;
349 return true;
351 for (int i = 0; i < count; i++)
353 if (auxLookAndFeels[i] == laf)
355 LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length - 1];
356 if (i == 0)
358 System.arraycopy(auxLookAndFeels, 1, temp, 0, count - 1);
360 else if (i == count - 1)
362 System.arraycopy(auxLookAndFeels, 0, temp, 0, count - 1);
364 else
366 System.arraycopy(auxLookAndFeels, 0, temp, 0, i);
367 System.arraycopy(auxLookAndFeels, i + 1, temp, i,
368 count - i - 1);
370 auxLookAndFeels = temp;
371 return true;
374 return false;
378 * Returns an array (possibly <code>null</code>) containing the auxiliary
379 * {@link LookAndFeel}s that are in use. These are used by the
380 * {@link javax.swing.plaf.multi.MultiLookAndFeel} class.
382 * @return The auxiliary look and feels (possibly <code>null</code>).
384 * @see #addAuxiliaryLookAndFeel(LookAndFeel)
386 public static LookAndFeel[] getAuxiliaryLookAndFeels()
388 return auxLookAndFeels;
392 * Returns an object from the {@link UIDefaults} table for the current
393 * {@link LookAndFeel}.
395 * @param key the key.
397 * @return The object.
399 public static Object get(Object key)
401 return getDefaults().get(key);
405 * Returns an object from the {@link UIDefaults} table for the current
406 * {@link LookAndFeel}.
408 * @param key the key.
410 * @return The object.
412 * @since 1.4
414 public static Object get(Object key, Locale locale)
416 return getDefaults().get(key, locale);
420 * Returns a boolean value from the defaults table. If there is no value
421 * for the specified key, or the value is not an instance of {@link Boolean},
422 * this method returns <code>false</code>.
424 * @param key the key (<code>null</code> not permitted).
426 * @return The boolean value associated with the specified key.
428 * @throws NullPointerException if <code>key</code> is <code>null</code>.
430 * @since 1.4
432 public static boolean getBoolean(Object key)
434 Object value = get(key);
435 if (value instanceof Boolean)
436 return ((Boolean) value).booleanValue();
437 return false;
441 * Returns a boolean value from the defaults table. If there is no value
442 * for the specified key, or the value is not an instance of {@link Boolean},
443 * this method returns <code>false</code>.
445 * @param key the key (<code>null</code> not permitted).
446 * @param locale the locale.
448 * @return The boolean value associated with the specified key.
450 * @throws NullPointerException if <code>key</code> is <code>null</code>.
452 * @since 1.4
454 public static boolean getBoolean(Object key, Locale locale)
456 Object value = get(key, locale);
457 if (value instanceof Boolean)
458 return ((Boolean) value).booleanValue();
459 return false;
463 * Returns a border from the defaults table.
465 * @param key the key (<code>null</code> not permitted).
467 * @return The border associated with the given key, or <code>null</code>.
469 * @throws NullPointerException if <code>key</code> is <code>null</code>.
471 public static Border getBorder(Object key)
473 Object value = get(key);
474 if (value instanceof Border)
475 return (Border) value;
476 return null;
480 * Returns a border from the defaults table.
482 * @param key the key (<code>null</code> not permitted).
483 * @param locale the locale.
485 * @return The border associated with the given key, or <code>null</code>.
487 * @throws NullPointerException if <code>key</code> is <code>null</code>.
489 * @since 1.4
491 public static Border getBorder(Object key, Locale locale)
493 Object value = get(key, locale);
494 if (value instanceof Border)
495 return (Border) value;
496 return null;
500 * Returns a drawing color from the defaults table.
502 * @param key the key (<code>null</code> not permitted).
504 * @return The color associated with the given key, or <code>null</code>.
506 * @throws NullPointerException if <code>key</code> is <code>null</code>.
508 public static Color getColor(Object key)
510 Object value = get(key);
511 if (value instanceof Color)
512 return (Color) value;
513 return null;
517 * Returns a drawing color from the defaults table.
519 * @param key the key (<code>null</code> not permitted).
520 * @param locale the locale.
522 * @return The color associated with the given key, or <code>null</code>.
524 * @throws NullPointerException if <code>key</code> is <code>null</code>.
526 * @since 1.4
528 public static Color getColor(Object key, Locale locale)
530 Object value = get(key, locale);
531 if (value instanceof Color)
532 return (Color) value;
533 return null;
537 * The fully qualified class name of the cross platform (Metal) look and feel.
538 * This string can be passed to Class.forName()
540 * @return <code>"javax.swing.plaf.metal.MetalLookAndFeel"</code>
542 public static String getCrossPlatformLookAndFeelClassName()
544 return "javax.swing.plaf.metal.MetalLookAndFeel";
548 * Returns the default values for this look and feel.
550 * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
552 public static UIDefaults getDefaults()
554 if (currentUIDefaults == null)
555 currentUIDefaults = new MultiplexUIDefaults(new UIDefaults());
556 return currentUIDefaults;
560 * Returns a dimension from the defaults table.
562 * @param key the key (<code>null</code> not permitted).
564 * @return The color associated with the given key, or <code>null</code>.
566 * @throws NullPointerException if <code>key</code> is <code>null</code>.
568 public static Dimension getDimension(Object key)
570 Object value = get(key);
571 if (value instanceof Dimension)
572 return (Dimension) value;
573 return null;
577 * Returns a dimension from the defaults table.
579 * @param key the key (<code>null</code> not permitted).
580 * @param locale the locale.
582 * @return The color associated with the given key, or <code>null</code>.
584 * @throws NullPointerException if <code>key</code> is <code>null</code>.
585 * @since 1.4
587 public static Dimension getDimension(Object key, Locale locale)
589 Object value = get(key, locale);
590 if (value instanceof Dimension)
591 return (Dimension) value;
592 return null;
596 * Retrieves a font from the defaults table of the current
597 * LookAndFeel.
599 * @param key an Object that specifies the font. Typically,
600 * this is a String such as
601 * <code>TitledBorder.font</code>.
603 * @return The font associated with the given key, or <code>null</code>.
605 * @throws NullPointerException if <code>key</code> is <code>null</code>.
607 public static Font getFont(Object key)
609 Object value = get(key);
610 if (value instanceof Font)
611 return (Font) value;
612 return null;
616 * Retrieves a font from the defaults table of the current
617 * LookAndFeel.
619 * @param key an Object that specifies the font. Typically,
620 * this is a String such as
621 * <code>TitledBorder.font</code>.
622 * @param locale the locale.
624 * @return The font associated with the given key, or <code>null</code>.
626 * @throws NullPointerException if <code>key</code> is <code>null</code>.
628 * @since 1.4
630 public static Font getFont(Object key, Locale locale)
632 Object value = get(key, locale);
633 if (value instanceof Font)
634 return (Font) value;
635 return null;
639 * Returns an icon from the defaults table.
641 * @param key the key (<code>null</code> not permitted).
643 * @return The icon associated with the given key, or <code>null</code>.
645 * @throws NullPointerException if <code>key</code> is <code>null</code>.
647 public static Icon getIcon(Object key)
649 Object value = get(key);
650 if (value instanceof Icon)
651 return (Icon) value;
652 return null;
656 * Returns an icon from the defaults table.
658 * @param key the key (<code>null</code> not permitted).
659 * @param locale the locale.
661 * @return The icon associated with the given key, or <code>null</code>.
663 * @throws NullPointerException if <code>key</code> is <code>null</code>.
664 * @since 1.4
666 public static Icon getIcon(Object key, Locale locale)
668 Object value = get(key, locale);
669 if (value instanceof Icon)
670 return (Icon) value;
671 return null;
675 * Returns an Insets object from the defaults table.
677 * @param key the key (<code>null</code> not permitted).
679 * @return The insets associated with the given key, or <code>null</code>.
681 * @throws NullPointerException if <code>key</code> is <code>null</code>.
683 public static Insets getInsets(Object key)
685 Object o = get(key);
686 if (o instanceof Insets)
687 return (Insets) o;
688 else
689 return null;
693 * Returns an Insets object from the defaults table.
695 * @param key the key (<code>null</code> not permitted).
696 * @param locale the locale.
698 * @return The insets associated with the given key, or <code>null</code>.
700 * @throws NullPointerException if <code>key</code> is <code>null</code>.
701 * @since 1.4
703 public static Insets getInsets(Object key, Locale locale)
705 Object o = get(key, locale);
706 if (o instanceof Insets)
707 return (Insets) o;
708 else
709 return null;
713 * Returns an array containing information about the {@link LookAndFeel}s
714 * that are installed.
716 * @return A list of the look and feels that are available (installed).
718 public static LookAndFeelInfo[] getInstalledLookAndFeels()
720 return installed;
724 * Returns the integer value of the {@link Integer} associated with the
725 * given key. If there is no value, or the value is not an instance of
726 * {@link Integer}, this method returns 0.
728 * @param key the key (<code>null</code> not permitted).
730 * @return The integer value associated with the given key, or 0.
732 public static int getInt(Object key)
734 Object x = get(key);
735 if (x instanceof Integer)
736 return ((Integer) x).intValue();
737 return 0;
741 * Returns the integer value of the {@link Integer} associated with the
742 * given key. If there is no value, or the value is not an instance of
743 * {@link Integer}, this method returns 0.
745 * @param key the key (<code>null</code> not permitted).
746 * @param locale the locale.
748 * @return The integer value associated with the given key, or 0.
750 * @since 1.4
752 public static int getInt(Object key, Locale locale)
754 Object x = get(key, locale);
755 if (x instanceof Integer)
756 return ((Integer) x).intValue();
757 return 0;
761 * Returns the current look and feel (which may be <code>null</code>).
763 * @return The current look and feel.
765 * @see #setLookAndFeel(LookAndFeel)
767 public static LookAndFeel getLookAndFeel()
769 return currentLookAndFeel;
773 * Returns the <code>UIDefaults</code> table of the currently active
774 * look and feel.
776 * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
778 public static UIDefaults getLookAndFeelDefaults()
780 return lookAndFeelDefaults;
784 * Returns the {@link String} associated with the given key. If the value
785 * is not a {@link String}, this method returns <code>null</code>.
787 * @param key the key (<code>null</code> not permitted).
789 * @return The string associated with the given key, or <code>null</code>.
791 public static String getString(Object key)
793 Object s = get(key);
794 if (s instanceof String)
795 return (String) s;
796 return null;
800 * Returns the {@link String} associated with the given key. If the value
801 * is not a {@link String}, this method returns <code>null</code>.
803 * @param key the key (<code>null</code> not permitted).
804 * @param locale the locale.
806 * @return The string associated with the given key, or <code>null</code>.
808 * @since 1.4
810 public static String getString(Object key, Locale locale)
812 Object s = get(key, locale);
813 if (s instanceof String)
814 return (String) s;
815 return null;
819 * Returns the name of the {@link LookAndFeel} class that implements the
820 * native systems look and feel if there is one, otherwise the name
821 * of the default cross platform LookAndFeel class.
823 * @return The fully qualified class name for the system look and feel.
825 * @see #getCrossPlatformLookAndFeelClassName()
827 public static String getSystemLookAndFeelClassName()
829 return getCrossPlatformLookAndFeelClassName();
833 * Returns UI delegate from the current {@link LookAndFeel} that renders the
834 * target component.
836 * @param target the target component.
838 public static ComponentUI getUI(JComponent target)
840 return getDefaults().getUI(target);
844 * Creates a new look and feel and adds it to the current array.
846 * @param name the look and feel name.
847 * @param className the fully qualified name of the class that implements the
848 * look and feel.
850 public static void installLookAndFeel(String name, String className)
852 installLookAndFeel(new LookAndFeelInfo(name, className));
856 * Adds the specified look and feel to the current array and then calls
857 * setInstalledLookAndFeels(javax.swing.UIManager.LookAndFeelInfo[]).
859 public static void installLookAndFeel(LookAndFeelInfo info)
861 LookAndFeelInfo[] newInstalled = new LookAndFeelInfo[installed.length + 1];
862 System.arraycopy(installed, 0, newInstalled, 0, installed.length);
863 newInstalled[newInstalled.length - 1] = info;
864 setInstalledLookAndFeels(newInstalled);
868 * Stores an object in the defaults table.
870 * @param key the key.
871 * @param value the value.
873 public static Object put(Object key, Object value)
875 return getDefaults().put(key, value);
879 * Replaces the current array of installed LookAndFeelInfos.
881 public static void setInstalledLookAndFeels(UIManager.LookAndFeelInfo[] infos)
883 installed = infos;
887 * Sets the current {@link LookAndFeel}.
889 * @param newLookAndFeel the new look and feel (<code>null</code> permitted).
891 * @throws UnsupportedLookAndFeelException if the look and feel is not
892 * supported on the current platform.
894 * @see LookAndFeel#isSupportedLookAndFeel()
896 public static void setLookAndFeel(LookAndFeel newLookAndFeel)
897 throws UnsupportedLookAndFeelException
899 if (newLookAndFeel != null && ! newLookAndFeel.isSupportedLookAndFeel())
900 throw new UnsupportedLookAndFeelException(newLookAndFeel.getName()
901 + " not supported on this platform");
902 LookAndFeel oldLookAndFeel = currentLookAndFeel;
903 if (oldLookAndFeel != null)
904 oldLookAndFeel.uninitialize();
906 // Set the current default look and feel using a LookAndFeel object.
907 currentLookAndFeel = newLookAndFeel;
908 if (newLookAndFeel != null)
910 newLookAndFeel.initialize();
911 lookAndFeelDefaults = newLookAndFeel.getDefaults();
912 if (currentUIDefaults == null)
913 currentUIDefaults =
914 new MultiplexUIDefaults(lookAndFeelDefaults);
915 else
916 currentUIDefaults.fallback = lookAndFeelDefaults;
918 else
920 currentUIDefaults = null;
922 listeners.firePropertyChange("lookAndFeel", oldLookAndFeel, newLookAndFeel);
923 //revalidate();
924 //repaint();
928 * Set the current default look and feel using a class name.
930 * @param className the look and feel class name.
932 * @throws UnsupportedLookAndFeelException if the look and feel is not
933 * supported on the current platform.
935 * @see LookAndFeel#isSupportedLookAndFeel()
937 public static void setLookAndFeel(String className)
938 throws ClassNotFoundException, InstantiationException, IllegalAccessException,
939 UnsupportedLookAndFeelException
941 Class c = Class.forName(className, true,
942 Thread.currentThread().getContextClassLoader());
943 LookAndFeel a = (LookAndFeel) c.newInstance(); // throws class-cast-exception
944 setLookAndFeel(a);