2015-05-05 Yvan Roux <yvan.roux@linaro.org>
[official-gcc.git] / libjava / classpath / javax / swing / UIDefaults.java
blob904b4c2b8515a0d73d24f32afbc698ef6abb88fc
1 /* UIDefaults.java -- database for all settings and interface bindings.
2 Copyright (C) 2002, 2004, 2005 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.lang.reflect.Method;
48 import java.util.Hashtable;
49 import java.util.LinkedList;
50 import java.util.ListIterator;
51 import java.util.Locale;
52 import java.util.MissingResourceException;
53 import java.util.ResourceBundle;
55 import javax.swing.border.Border;
56 import javax.swing.plaf.ComponentUI;
57 import javax.swing.plaf.InputMapUIResource;
59 /**
60 * UIDefaults is a database where all settings and interface bindings are
61 * stored into. A PLAF implementation fills one of these (see for example
62 * plaf/basic/BasicLookAndFeel.java) with "ButtonUI" -&gt; new BasicButtonUI().
64 * @author Ronald Veldema (rveldema@cs.vu.nl)
66 public class UIDefaults extends Hashtable<Object, Object>
69 /** Our ResourceBundles. */
70 private LinkedList bundles;
72 /** The default locale. */
73 private Locale defaultLocale;
75 /** We use this for firing PropertyChangeEvents. */
76 private PropertyChangeSupport propertyChangeSupport;
78 /**
79 * Used for lazy instantiation of UIDefaults values so that they are not
80 * all loaded when a Swing application starts up, but only the values that
81 * are really needed. An <code>ActiveValue</code> is newly instantiated
82 * every time when the value is requested, as opposed to the normal
83 * {@link LazyValue} that is only instantiated once.
85 public static interface ActiveValue
87 Object createValue(UIDefaults table);
90 public static class LazyInputMap implements LazyValue
92 Object[] bind;
93 public LazyInputMap(Object[] bindings)
95 bind = bindings;
97 public Object createValue(UIDefaults table)
99 InputMapUIResource im = new InputMapUIResource();
100 for (int i = 0; 2 * i + 1 < bind.length; ++i)
102 Object curr = bind[2 * i];
103 if (curr instanceof KeyStroke)
104 im.put((KeyStroke) curr, bind[2 * i + 1]);
105 else
106 im.put(KeyStroke.getKeyStroke((String) curr),
107 bind[2 * i + 1]);
109 return im;
114 * Used for lazy instantiation of UIDefaults values so that they are not
115 * all loaded when a Swing application starts up, but only the values that
116 * are really needed. A <code>LazyValue</code> is only instantiated once,
117 * as opposed to the {@link ActiveValue} that is newly created every time
118 * it is requested.
120 public static interface LazyValue
122 Object createValue(UIDefaults table);
125 public static class ProxyLazyValue implements LazyValue
127 LazyValue inner;
128 public ProxyLazyValue(String s)
130 final String className = s;
131 inner = new LazyValue()
133 public Object createValue(UIDefaults table)
137 return Class
138 .forName(className)
139 .getConstructor(new Class[] {})
140 .newInstance(new Object[] {});
142 catch (Exception e)
144 return null;
150 public ProxyLazyValue(String c, String m)
152 final String className = c;
153 final String methodName = m;
154 inner = new LazyValue()
156 public Object createValue(UIDefaults table)
160 return Class
161 .forName(className)
162 .getMethod(methodName, new Class[] {})
163 .invoke(null, new Object[] {});
165 catch (Exception e)
167 return null;
173 public ProxyLazyValue(String c, Object[] os)
175 final String className = c;
176 final Object[] objs = os;
177 final Class[] clss = new Class[objs.length];
178 for (int i = 0; i < objs.length; ++i)
180 clss[i] = objs[i].getClass();
182 inner = new LazyValue()
184 public Object createValue(UIDefaults table)
188 return Class
189 .forName(className)
190 .getConstructor(clss)
191 .newInstance(objs);
193 catch (Exception e)
195 return null;
201 public ProxyLazyValue(String c, String m, Object[] os)
203 final String className = c;
204 final String methodName = m;
205 final Object[] objs = os;
206 final Class[] clss = new Class[objs.length];
207 for (int i = 0; i < objs.length; ++i)
209 clss[i] = objs[i].getClass();
211 inner = new LazyValue()
213 public Object createValue(UIDefaults table)
217 return Class
218 .forName(className)
219 .getMethod(methodName, clss)
220 .invoke(null, objs);
222 catch (Exception e)
224 return null;
230 public Object createValue(UIDefaults table)
232 return inner.createValue(table);
236 /** Our serialVersionUID for serialization. */
237 private static final long serialVersionUID = 7341222528856548117L;
240 * Constructs a new empty UIDefaults instance.
242 public UIDefaults()
244 bundles = new LinkedList();
245 defaultLocale = Locale.getDefault();
246 propertyChangeSupport = new PropertyChangeSupport(this);
250 * Constructs a new UIDefaults instance and loads the specified entries.
251 * The entries are expected to come in pairs, that means
252 * <code>entries[0]</code> is a key, <code>entries[1]</code> is a value,
253 * <code>entries[2]</code> a key and so forth.
255 * @param entries the entries to initialize the UIDefaults instance with
257 public UIDefaults(Object[] entries)
259 this();
261 for (int i = 0; (2 * i + 1) < entries.length; ++i)
262 put(entries[2 * i], entries[2 * i + 1]);
266 * Returns the entry for the specified <code>key</code> in the default
267 * locale.
269 * @return the entry for the specified <code>key</code>
271 public Object get(Object key)
273 return this.get(key, getDefaultLocale());
277 * Returns the entry for the specified <code>key</code> in the Locale
278 * <code>loc</code>.
280 * @param key the key for which we return the value
281 * @param loc the locale
283 public Object get(Object key, Locale loc)
285 Object obj = null;
287 if (super.containsKey(key))
289 obj = super.get(key);
291 else if (key instanceof String)
293 String keyString = (String) key;
294 ListIterator i = bundles.listIterator(0);
295 while (i.hasNext())
297 String bundle_name = (String) i.next();
298 ResourceBundle res =
299 ResourceBundle.getBundle(bundle_name, loc);
300 if (res != null)
304 obj = res.getObject(keyString);
305 break;
307 catch (MissingResourceException me)
309 // continue, this bundle has no such key
315 // now we've found the object, resolve it.
316 // nb: LazyValues aren't supported in resource bundles, so it's correct
317 // to insert their results in the locale-less hashtable.
319 if (obj == null)
320 return null;
322 if (obj instanceof LazyValue)
324 Object resolved = ((LazyValue) obj).createValue(this);
325 super.remove(key);
326 super.put(key, resolved);
327 return resolved;
329 else if (obj instanceof ActiveValue)
331 return ((ActiveValue) obj).createValue(this);
334 return obj;
338 * Puts a key and value into this UIDefaults object.<br>
339 * In contrast to
340 * {@link java.util.Hashtable}s <code>null</code>-values are accepted
341 * here and treated like #remove(key).
342 * <br>
343 * This fires a PropertyChangeEvent with key as name and the old and new
344 * values.
346 * @param key the key to put into the map
347 * @param value the value to put into the map
349 * @return the old value for key or <code>null</code> if <code>key</code>
350 * had no value assigned
352 public Object put(Object key, Object value)
354 Object old = checkAndPut(key, value);
356 if (key instanceof String && old != value)
357 firePropertyChange((String) key, old, value);
358 return old;
362 * Puts a set of key-value pairs into the map.
363 * The entries are expected to come in pairs, that means
364 * <code>entries[0]</code> is a key, <code>entries[1]</code> is a value,
365 * <code>entries[2]</code> a key and so forth.
366 * <br>
367 * If a value is <code>null</code> it is treated like #remove(key).
368 * <br>
369 * This unconditionally fires a PropertyChangeEvent with
370 * <code>&apos;UIDefaults&apos;</code> as name and <code>null</code> for
371 * old and new value.
373 * @param entries the entries to be put into the map
375 public void putDefaults(Object[] entries)
377 for (int i = 0; (2 * i + 1) < entries.length; ++i)
379 checkAndPut(entries[2 * i], entries[2 * i + 1]);
381 firePropertyChange("UIDefaults", null, null);
385 * Checks the value for <code>null</code> and put it into the Hashtable, if
386 * it is not <code>null</code>. If the value is <code>null</code> then
387 * remove the corresponding key.
389 * @param key the key to put into this UIDefauls table
390 * @param value the value to put into this UIDefaults table
392 * @return the old value for <code>key</code>
394 private Object checkAndPut(Object key, Object value)
396 Object old;
398 if (value != null)
399 old = super.put(key, value);
400 else
401 old = super.remove(key);
403 return old;
407 * Returns a font entry for the default locale.
409 * @param key the key to the requested entry
411 * @return the font entry for <code>key</code> or null if no such entry
412 * exists
414 public Font getFont(Object key)
416 Object o = get(key);
417 return o instanceof Font ? (Font) o : null;
421 * Returns a font entry for a specic locale.
423 * @param key the key to the requested entry
424 * @param locale the locale to the requested entry
426 * @return the font entry for <code>key</code> or null if no such entry
427 * exists
429 public Font getFont(Object key, Locale locale)
431 Object o = get(key, locale);
432 return o instanceof Font ? (Font) o : null;
436 * Returns a color entry for the default locale.
438 * @param key the key to the requested entry
440 * @return the color entry for <code>key</code> or null if no such entry
441 * exists
443 public Color getColor(Object key)
445 Object o = get(key);
446 return o instanceof Color ? (Color) o : null;
450 * Returns a color entry for a specic locale.
452 * @param key the key to the requested entry
453 * @param locale the locale to the requested entry
455 * @return the color entry for <code>key</code> or null if no such entry
456 * exists
458 public Color getColor(Object key, Locale locale)
460 Object o = get(key, locale);
461 return o instanceof Color ? (Color) o : null;
465 * Returns an icon entry for the default locale.
467 * @param key the key to the requested entry
469 * @return the icon entry for <code>key</code> or null if no such entry
470 * exists
472 public Icon getIcon(Object key)
474 Object o = get(key);
475 return o instanceof Icon ? (Icon) o : null;
479 * Returns an icon entry for a specic locale.
481 * @param key the key to the requested entry
482 * @param locale the locale to the requested entry
484 * @return the icon entry for <code>key</code> or null if no such entry
485 * exists
487 public Icon getIcon(Object key, Locale locale)
489 Object o = get(key, locale);
490 return o instanceof Icon ? (Icon) o : null;
494 * Returns a border entry for the default locale.
496 * @param key the key to the requested entry
498 * @return the border entry for <code>key</code> or null if no such entry
499 * exists
501 public Border getBorder(Object key)
503 Object o = get(key);
504 return o instanceof Border ? (Border) o : null;
508 * Returns a border entry for a specic locale.
510 * @param key the key to the requested entry
511 * @param locale the locale to the requested entry
513 * @return the border entry for <code>key</code> or null if no such entry
514 * exists
516 public Border getBorder(Object key, Locale locale)
518 Object o = get(key, locale);
519 return o instanceof Border ? (Border) o : null;
523 * Returns a string entry for the default locale.
525 * @param key the key to the requested entry
527 * @return the string entry for <code>key</code> or null if no such entry
528 * exists
530 public String getString(Object key)
532 Object o = get(key);
533 return o instanceof String ? (String) o : null;
537 * Returns a string entry for a specic locale.
539 * @param key the key to the requested entry
540 * @param locale the locale to the requested entry
542 * @return the string entry for <code>key</code> or null if no such entry
543 * exists
545 public String getString(Object key, Locale locale)
547 Object o = get(key, locale);
548 return o instanceof String ? (String) o : null;
552 * Returns an integer entry for the default locale.
554 * @param key the key to the requested entry
556 * @return the integer entry for <code>key</code> or null if no such entry
557 * exists
559 public int getInt(Object key)
561 Object o = get(key);
562 return o instanceof Integer ? ((Integer) o).intValue() : 0;
566 * Returns an integer entry for a specic locale.
568 * @param key the key to the requested entry
569 * @param locale the locale to the requested entry
571 * @return the integer entry for <code>key</code> or null if no such entry
572 * exists
574 public int getInt(Object key, Locale locale)
576 Object o = get(key, locale);
577 return o instanceof Integer ? ((Integer) o).intValue() : 0;
581 * Returns a boolean entry for the default locale.
583 * @param key the key to the requested entry
585 * @return The boolean entry for <code>key</code> or <code>false</code> if no
586 * such entry exists.
588 public boolean getBoolean(Object key)
590 return Boolean.TRUE.equals(get(key));
594 * Returns a boolean entry for a specic locale.
596 * @param key the key to the requested entry
597 * @param locale the locale to the requested entry
599 * @return the boolean entry for <code>key</code> or null if no such entry
600 * exists
602 public boolean getBoolean(Object key, Locale locale)
604 return Boolean.TRUE.equals(get(key, locale));
608 * Returns an insets entry for the default locale.
610 * @param key the key to the requested entry
612 * @return the insets entry for <code>key</code> or null if no such entry
613 * exists
615 public Insets getInsets(Object key)
617 Object o = get(key);
618 return o instanceof Insets ? (Insets) o : null;
622 * Returns an insets entry for a specic locale.
624 * @param key the key to the requested entry
625 * @param locale the locale to the requested entry
627 * @return the boolean entry for <code>key</code> or null if no such entry
628 * exists
630 public Insets getInsets(Object key, Locale locale)
632 Object o = get(key, locale);
633 return o instanceof Insets ? (Insets) o : null;
637 * Returns a dimension entry for the default locale.
639 * @param key the key to the requested entry
641 * @return the dimension entry for <code>key</code> or null if no such entry
642 * exists
644 public Dimension getDimension(Object key)
646 Object o = get(key);
647 return o instanceof Dimension ? (Dimension) o : null;
651 * Returns a dimension entry for a specic locale.
653 * @param key the key to the requested entry
654 * @param locale the locale to the requested entry
656 * @return the boolean entry for <code>key</code> or null if no such entry
657 * exists
659 public Dimension getDimension(Object key, Locale locale)
661 Object o = get(key, locale);
662 return o instanceof Dimension ? (Dimension) o : null;
666 * Returns the ComponentUI class that renders a component. <code>id</code>
667 * is the ID for which the String value of the classname is stored in
668 * this UIDefaults map.
670 * @param id the ID of the UI class
671 * @param loader the ClassLoader to use
673 * @return the UI class for <code>id</code>
675 public Class<? extends ComponentUI> getUIClass(String id, ClassLoader loader)
677 String className = (String) get(id);
678 if (className == null)
679 return null;
682 if (loader == null)
683 loader = ClassLoader.getSystemClassLoader();
684 return (Class<? extends ComponentUI>) loader.loadClass (className);
686 catch (Exception e)
688 return null;
693 * Returns the ComponentUI class that renders a component. <code>id</code>
694 * is the ID for which the String value of the classname is stored in
695 * this UIDefaults map.
697 * @param id the ID of the UI class
699 * @return the UI class for <code>id</code>
701 public Class<? extends ComponentUI> getUIClass(String id)
703 return getUIClass (id, null);
707 * If a key is requested in #get(key) that has no value, this method
708 * is called before returning <code>null</code>.
710 * @param msg the error message
712 protected void getUIError(String msg)
714 System.err.println ("UIDefaults.getUIError: " + msg);
718 * Returns the {@link ComponentUI} for the specified {@link JComponent}.
720 * @param target the component for which the ComponentUI is requested
722 * @return the {@link ComponentUI} for the specified {@link JComponent}
724 public ComponentUI getUI(JComponent target)
726 String classId = target.getUIClassID ();
727 Class cls = getUIClass (classId);
728 if (cls == null)
730 getUIError ("failed to locate UI class:" + classId);
731 return null;
734 Method factory;
738 factory = cls.getMethod ("createUI", new Class[] { JComponent.class } );
740 catch (NoSuchMethodException nme)
742 getUIError ("failed to locate createUI method on " + cls.toString ());
743 return null;
748 return (ComponentUI) factory.invoke (null, new Object[] { target });
750 catch (java.lang.reflect.InvocationTargetException ite)
752 getUIError ("InvocationTargetException ("+ ite.getTargetException()
753 +") calling createUI(...) on " + cls.toString ());
754 return null;
756 catch (Exception e)
758 getUIError ("exception calling createUI(...) on " + cls.toString ());
759 return null;
764 * Adds a {@link PropertyChangeListener} to this UIDefaults map.
765 * Registered PropertyChangeListener are notified when values
766 * are beeing put into this UIDefaults map.
768 * @param listener the PropertyChangeListener to add
770 public void addPropertyChangeListener(PropertyChangeListener listener)
772 propertyChangeSupport.addPropertyChangeListener(listener);
776 * Removes a PropertyChangeListener from this UIDefaults map.
778 * @param listener the PropertyChangeListener to remove
780 public void removePropertyChangeListener(PropertyChangeListener listener)
782 propertyChangeSupport.removePropertyChangeListener(listener);
786 * Returns an array of all registered PropertyChangeListeners.
788 * @return all registered PropertyChangeListeners
790 public PropertyChangeListener[] getPropertyChangeListeners()
792 return propertyChangeSupport.getPropertyChangeListeners();
796 * Fires a PropertyChangeEvent.
798 * @param property the property name
799 * @param oldValue the old value
800 * @param newValue the new value
802 protected void firePropertyChange(String property,
803 Object oldValue, Object newValue)
805 propertyChangeSupport.firePropertyChange(property, oldValue, newValue);
809 * Adds a ResourceBundle for localized values.
811 * @param name the name of the ResourceBundle to add
813 public void addResourceBundle(String name)
815 bundles.addFirst(name);
819 * Removes a ResourceBundle.
821 * @param name the name of the ResourceBundle to remove
823 public void removeResourceBundle(String name)
825 bundles.remove(name);
829 * Sets the current locale to <code>loc</code>.
831 * @param loc the Locale to be set
833 public void setDefaultLocale(Locale loc)
835 defaultLocale = loc;
839 * Returns the current default locale.
841 * @return the current default locale
843 public Locale getDefaultLocale()
845 return defaultLocale;