| /* UIDefaults.java -- database for all settings and interface bindings. |
| Copyright (C) 2002, 2004, 2005 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., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 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.Dimension; |
| import java.awt.Font; |
| import java.awt.Insets; |
| import java.beans.PropertyChangeListener; |
| import java.beans.PropertyChangeSupport; |
| import java.lang.reflect.Method; |
| import java.util.Hashtable; |
| import java.util.LinkedList; |
| import java.util.ListIterator; |
| import java.util.Locale; |
| import java.util.MissingResourceException; |
| import java.util.ResourceBundle; |
| |
| import javax.swing.border.Border; |
| import javax.swing.plaf.ComponentUI; |
| |
| /** |
| * UIDefaults is a database where all settings and interface bindings are |
| * stored into. A PLAF implementation fills one of these (see for example |
| * plaf/basic/BasicLookAndFeel.java) with "ButtonUI" -> new BasicButtonUI(). |
| * |
| * @author Ronald Veldema (rveldema@cs.vu.nl) |
| */ |
| public class UIDefaults extends Hashtable |
| { |
| private LinkedList bundles; |
| private Locale defaultLocale; |
| private PropertyChangeSupport propertyChangeSupport; |
| |
| public static interface ActiveValue |
| { |
| Object createValue(UIDefaults table); |
| } |
| |
| public static class LazyInputMap implements LazyValue |
| { |
| Object[] bind; |
| public LazyInputMap(Object[] bindings) |
| { |
| bind = bindings; |
| } |
| public Object createValue(UIDefaults table) |
| { |
| InputMap im = new InputMap (); |
| for (int i = 0; 2*i+1 < bind.length; ++i) |
| { |
| im.put (KeyStroke.getKeyStroke ((String) bind[2*i]), |
| bind[2*i+1]); |
| } |
| return im; |
| } |
| } |
| |
| public static interface LazyValue |
| { |
| Object createValue(UIDefaults table); |
| } |
| |
| public static class ProxyLazyValue implements LazyValue |
| { |
| LazyValue inner; |
| public ProxyLazyValue(String s) |
| { |
| final String className = s; |
| inner = new LazyValue () |
| { |
| public Object createValue (UIDefaults table) |
| { |
| try |
| { |
| return Class |
| .forName(className) |
| .getConstructor(new Class[] {}) |
| .newInstance(new Object[] {}); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| }; |
| } |
| |
| public ProxyLazyValue(String c, String m) |
| { |
| final String className = c; |
| final String methodName = m; |
| inner = new LazyValue () |
| { |
| public Object createValue (UIDefaults table) |
| { |
| try |
| { |
| return Class |
| .forName (className) |
| .getMethod (methodName, new Class[] {}) |
| .invoke (null, new Object[] {}); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| }; |
| } |
| |
| public ProxyLazyValue(String c, Object[] os) |
| { |
| final String className = c; |
| final Object[] objs = os; |
| final Class[] clss = new Class[objs.length]; |
| for (int i = 0; i < objs.length; ++i) |
| { |
| clss[i] = objs[i].getClass(); |
| } |
| inner = new LazyValue() |
| { |
| public Object createValue(UIDefaults table) |
| { |
| try |
| { |
| return Class |
| .forName(className) |
| .getConstructor(clss) |
| .newInstance(objs); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| }; |
| } |
| |
| public ProxyLazyValue(String c, String m, Object[] os) |
| { |
| final String className = c; |
| final String methodName = m; |
| final Object[] objs = os; |
| final Class[] clss = new Class[objs.length]; |
| for (int i = 0; i < objs.length; ++i) |
| { |
| clss[i] = objs[i].getClass(); |
| } |
| inner = new LazyValue() |
| { |
| public Object createValue(UIDefaults table) |
| { |
| try |
| { |
| return Class |
| .forName(className) |
| .getMethod(methodName, clss) |
| .invoke(null, objs); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| }; |
| } |
| |
| public Object createValue(UIDefaults table) |
| { |
| return inner.createValue(table); |
| } |
| } |
| |
| private static final long serialVersionUID = 7341222528856548117L; |
| |
| public UIDefaults() |
| { |
| bundles = new LinkedList(); |
| defaultLocale = Locale.getDefault(); |
| propertyChangeSupport = new PropertyChangeSupport(this); |
| } |
| |
| public UIDefaults(Object[] entries) |
| { |
| this(); |
| |
| for (int i = 0; (2 * i + 1) < entries.length; ++i) |
| put(entries[2 * i], entries[2 * i + 1]); |
| } |
| |
| public Object get(Object key) |
| { |
| return this.get(key, getDefaultLocale()); |
| } |
| |
| public Object get(Object key, Locale loc) |
| { |
| Object obj = null; |
| |
| if (super.containsKey(key)) |
| { |
| obj = super.get(key); |
| } |
| else if (key instanceof String) |
| { |
| String keyString = (String) key; |
| ListIterator i = bundles.listIterator(0); |
| while (i.hasNext()) |
| { |
| String bundle_name = (String) i.next(); |
| ResourceBundle res = |
| ResourceBundle.getBundle(bundle_name, loc); |
| if (res != null) |
| { |
| try |
| { |
| obj = res.getObject(keyString); |
| break; |
| } |
| catch (MissingResourceException me) |
| { |
| // continue, this bundle has no such key |
| } |
| } |
| } |
| } |
| |
| // now we've found the object, resolve it. |
| // nb: LazyValues aren't supported in resource bundles, so it's correct |
| // to insert their results in the locale-less hashtable. |
| |
| if (obj == null) |
| return null; |
| |
| if (obj instanceof LazyValue) |
| { |
| Object resolved = ((LazyValue) obj).createValue(this); |
| super.remove(key); |
| super.put(key, resolved); |
| return resolved; |
| } |
| else if (obj instanceof ActiveValue) |
| { |
| return ((ActiveValue) obj).createValue(this); |
| } |
| |
| return obj; |
| } |
| |
| public Object put(Object key, Object value) |
| { |
| Object old; |
| if (value != null) |
| old = super.put(key, value); |
| else |
| old = super.remove(key); |
| if (key instanceof String && old != value) |
| firePropertyChange((String) key, old, value); |
| return old; |
| } |
| |
| public void putDefaults(Object[] entries) |
| { |
| for (int i = 0; (2 * i + 1) < entries.length; ++i) |
| { |
| super.put(entries[2 * i], entries[2 * i + 1]); |
| } |
| firePropertyChange("UIDefaults", null, null); |
| } |
| |
| public Font getFont(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Font ? (Font) o : null; |
| } |
| |
| public Font getFont(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Font ? (Font) o : null; |
| } |
| |
| public Color getColor(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Color ? (Color) o : null; |
| } |
| |
| public Color getColor(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Color ? (Color) o : null; |
| } |
| |
| public Icon getIcon(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Icon ? (Icon) o : null; |
| } |
| |
| public Icon getIcon(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Icon ? (Icon) o : null; |
| } |
| |
| public Border getBorder(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Border ? (Border) o : null; |
| } |
| |
| public Border getBorder(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Border ? (Border) o : null; |
| } |
| |
| public String getString(Object key) |
| { |
| Object o = get(key); |
| return o instanceof String ? (String) o : null; |
| } |
| |
| public String getString(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof String ? (String) o : null; |
| } |
| |
| public int getInt(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Integer ? ((Integer) o).intValue() : 0; |
| } |
| |
| public int getInt(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Integer ? ((Integer) o).intValue() : 0; |
| } |
| |
| public boolean getBoolean(Object key) |
| { |
| return Boolean.TRUE.equals(get(key)); |
| } |
| |
| public boolean getBoolean(Object key, Locale l) |
| { |
| return Boolean.TRUE.equals(get(key, l)); |
| } |
| |
| public Insets getInsets(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Insets ? (Insets) o : null; |
| } |
| |
| public Insets getInsets(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Insets ? (Insets) o : null; |
| } |
| |
| public Dimension getDimension(Object key) |
| { |
| Object o = get(key); |
| return o instanceof Dimension ? (Dimension) o : null; |
| } |
| |
| public Dimension getDimension(Object key, Locale l) |
| { |
| Object o = get(key, l); |
| return o instanceof Dimension ? (Dimension) o : null; |
| } |
| |
| public Class getUIClass(String id, ClassLoader loader) |
| { |
| String className = (String) get (id); |
| if (className == null) |
| return null; |
| try |
| { |
| if (loader != null) |
| return loader.loadClass (className); |
| return Class.forName (className); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| |
| public Class getUIClass(String id) |
| { |
| return getUIClass (id, null); |
| } |
| |
| protected void getUIError(String msg) |
| { |
| System.err.println ("UIDefaults.getUIError: " + msg); |
| } |
| |
| public ComponentUI getUI(JComponent target) |
| { |
| String classId = target.getUIClassID (); |
| Class cls = getUIClass (classId); |
| if (cls == null) |
| { |
| getUIError ("failed to locate UI class:" + classId); |
| return null; |
| } |
| |
| Method factory; |
| |
| try |
| { |
| factory = cls.getMethod ("createUI", new Class[] { JComponent.class } ); |
| } |
| catch (NoSuchMethodException nme) |
| { |
| getUIError ("failed to locate createUI method on " + cls.toString ()); |
| return null; |
| } |
| |
| try |
| { |
| return (ComponentUI) factory.invoke (null, new Object[] { target }); |
| } |
| catch (java.lang.reflect.InvocationTargetException ite) |
| { |
| getUIError ("InvocationTargetException ("+ ite.getTargetException() |
| +") calling createUI(...) on " + cls.toString ()); |
| return null; |
| } |
| catch (Exception e) |
| { |
| getUIError ("exception calling createUI(...) on " + cls.toString ()); |
| return null; |
| } |
| } |
| |
| public void addPropertyChangeListener(PropertyChangeListener listener) |
| { |
| propertyChangeSupport.addPropertyChangeListener(listener); |
| } |
| |
| public void removePropertyChangeListener(PropertyChangeListener listener) |
| { |
| propertyChangeSupport.removePropertyChangeListener(listener); |
| } |
| |
| public PropertyChangeListener[] getPropertyChangeListeners() |
| { |
| return propertyChangeSupport.getPropertyChangeListeners(); |
| } |
| |
| protected void firePropertyChange(String property, |
| Object oldValue, Object newValue) |
| { |
| propertyChangeSupport.firePropertyChange(property, oldValue, newValue); |
| } |
| |
| public void addResourceBundle(String name) |
| { |
| bundles.addFirst(name); |
| } |
| |
| public void removeResourceBundle(String name) |
| { |
| bundles.remove(name); |
| } |
| |
| public void setDefaultLocale(Locale loc) |
| { |
| defaultLocale = loc; |
| } |
| |
| public Locale getDefaultLocale() |
| { |
| return defaultLocale; |
| } |
| } |