Class ResourceMap
ResourceMaps are typically obtained with the ApplicationContext
getResourceMap
method
which lazily creates per Application, package, and class ResourceMaps that
are linked together with the ResourceMap parent property.
An individual ResourceMap provides read-only access to all of the resources defined by the ResourceBundles named when the ResourceMap was created as well as all of its parent ResourceMaps. Resources are retrieved with the getObject method which requires both the name of the resource and its expected type. The latter is used to convert strings if neccessary. Converted values are cached. As a convenience, getObject wrapper methods for common GUI types, like getFont, and getColor, are provided.
The getObject method scans raw string resource values for ${resourceName} variable substitutions before performing string conversion. Variables named this way can refer to String resources defined anywhere in their ResourceMap or any parent ResourceMap. The special variable ${null} means that the value of the resource will be null.
ResourceMaps can be used to "inject" resource values into Swing
component properties and into object fields. The
injectComponents method uses Component names (Component.setName(java.lang.String)
) to match resources names with properties. The
injectFields method sets fields that have been tagged with
the @Resource annotation to the value of resources
with the same name.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
Unchecked exception thrown byinjectFields(java.lang.Object)
when an error occurs while attempting to set a field (a field that had been marked with @Resource).static class
Unchecked exception thrown bygetObject(java.lang.String, java.lang.Class)
when resource lookup fails, for example because string conversion fails.static class
Unchecked exception thrown byinjectComponent(java.awt.Component)
andinjectComponents(java.awt.Component)
when a property value specified by a resource can not be set. -
Constructor Summary
ConstructorsConstructorDescriptionResourceMap
(ResourceMap parent, ClassLoader classLoader, String... bundleNames) Just a convenience version of the constructor for the common case where there's only one bundle name.ResourceMap
(ResourceMap parent, ClassLoader classLoader, List<String> bundleNames) Creates a ResourceMap that contains all of the resources defined in the namedResourceBundle
s as well as (recursively) the parent ResourceMap. -
Method Summary
Modifier and TypeMethodDescriptionboolean
containsKey
(String key) Returns true if this resourceMap or its parent (recursively) contains the specified key.protected boolean
By default this method is used bygetObject
to see if a resource is defined by this ResourceMap.final Boolean
getBoolean
(String key) A convenience method that's shorthand for calling: getObject(key, Boolean.class).Returns the names of the ResourceBundles that define the resources contained by this ResourceMap.final Byte
A convenience method that's shorthand for calling: getObject(key, Byte.class).Returns the ClassLoader used to load the ResourceBundles for this ResourceMap.final Color
A convenience method that's shorthand for calling: getObject(key, Color.class).final Double
A convenience method that's shorthand for calling: getObject(key, Double.class).final Float
A convenience method that's shorthand for calling: getObject(key, Float.class).final Font
A convenience method that's shorthand for calling: getObject(key, Font.class).final Icon
A convenience method that's shorthand for calling: getObject(key, Icon.class).final ImageIcon
getImageIcon
(String key) A convenience method that's shorthand for calling: getObject(key, ImageIcon.class).final Integer
getInteger
(String key) A convenience method that's shorthand for calling: getObject(key, Integer.class).getKeyCode
(String key) A convenience method that's shorthand for calling: getKeyStroke(key).getKeyCode().final KeyStroke
getKeyStroke
(String key) A convenience method that's shorthand for calling: getObject(key, KeyStroke.class).final Long
A convenience method that's shorthand for calling: getObject(key, Long.class).Returns the value of the resource named key, or null if no resource with that name exists.Returns the parent ResourceMap, or null.protected Object
getResource
(String key) By default this method is used bygetObject
to look up resource values in the internal representation of theResourceBundles
named when this ResourceMap was constructed.By default this method is used bykeySet
to get the names of the resources defined in this ResourceMap.Returns the resources directory that contains all of the ResourceBundles in this ResourceMap.final Short
A convenience method that's shorthand for calling: getObject(key, Short.class).If no arguments are specified, return the String value of the resource named key.void
injectComponent
(Component target) Set each property in target to the value of the resource named componentName.propertyName, where componentName is the value of the target component's name property, i.e.void
injectComponents
(Component root) AppliesinjectComponent(java.awt.Component)
to each Component in the hierarchy with root root.void
injectFields
(Object target) Set each field with a @Resource annotation in the target object, to the value of a resource whose name is the simple name of the target class followed by "." followed by the name of the field.keySet()
Return a unmodifiableSet
that contains all of the keys in this ResourceMap and (recursively) its parent ResourceMaps.protected void
putResource
(String key, Object value) By default this method is used bygetObject
to cache values that have been retrieved, evaluated (as in ${key} expressions), and string converted.
-
Constructor Details
-
ResourceMap
Creates a ResourceMap that contains all of the resources defined in the namedResourceBundle
s as well as (recursively) the parent ResourceMap. The parent may be null. Typically just one ResourceBundle is specified however one might name additional ResourceBundles that contain platform or Swing look and feel specific resources. When multiple bundles are named, a resource defined in bundlen will overide the same resource defined in bundles0..n-1. In other words bundles named later in the argument list take precendence over the bundles named earlier.ResourceBundles are loaded with the specified ClassLoader. If classLoader is null, an IllegalArgumentException is thrown.
At least one bundleName must be specified and all of the bundleNames must be non-empty strings, or an IllegalArgumentException is thrown. The bundles are listed in priority order, highest priority first. In other words, resources in the the first ResourceBundle named first, shadow resources with the same name later in the list.
All of the bundleNames must share a common package prefix. The package prefix implicitly specifies the resources directory (see
getResourcesDir()
). For example, the resources directory for bundle names "myapp.resources.foo" and "myapp.resources.bar", would be "myapp/resources/". If bundle names don't share a common package prefix, then an IllegalArgumentException is thrown.- Parameters:
parent
- parent ResourceMap or nullclassLoader
- the ClassLoader to be used to load the ResourceBundlebundleNames
- names of the ResourceBundle to be loaded- Throws:
IllegalArgumentException
- if classLoader or any bundleName is null, if no bundleNames are specified, if any bundleName is an empty (zero length) String, or if all of the bundleNames don't have a common package prefix- See Also:
-
ResourceMap
Just a convenience version of the constructor for the common case where there's only one bundle name. Defined as:this(parent, classLoader, Arrays.asList(bundleNames))
.
-
-
Method Details
-
getParent
Returns the parent ResourceMap, or null. Logically, this ResourceMap contains all of the resources defined here and (recursively) in the parent.- Returns:
- the parent ResourceMap or null
-
getBundleNames
Returns the names of the ResourceBundles that define the resources contained by this ResourceMap.- Returns:
- the names of the ResourceBundles in this ResourceMap
-
getClassLoader
Returns the ClassLoader used to load the ResourceBundles for this ResourceMap.- Returns:
- the classLoader constructor argument
-
getResourcesDir
Returns the resources directory that contains all of the ResourceBundles in this ResourceMap. It can be used with the the classLoader property to load files from the resources directory. For example:String filename = myResourceMap.getResourcesDir() + "myIcon.png"; URL url = myResourceMap.getClassLoader().getResource(filename); new ImageIcon(iconURL);
- Returns:
- the the resources directory for this ResourceMap
-
keySet
Return a unmodifiableSet
that contains all of the keys in this ResourceMap and (recursively) its parent ResourceMaps.- Returns:
- all of the keys in this ResourceMap and its parent
- See Also:
-
containsKey
Returns true if this resourceMap or its parent (recursively) contains the specified key.- Returns:
- true if this resourceMap or its parent contains the specified key.
- See Also:
-
getResourceKeySet
By default this method is used bykeySet
to get the names of the resources defined in this ResourceMap. This method lazily loads the ResourceBundles named by the constructor.The protected
getResource
,putResource
, andcontainsResourceKey
,getResourceKeySet
abstract the internal representation of this ResourceMap's list ofResourceBundles
. Most applications can ignore them.- Returns:
- the names of the resources defined in this ResourceMap
- See Also:
-
containsResourceKey
By default this method is used bygetObject
to see if a resource is defined by this ResourceMap. This method lazily loads the ResourceBundles named by the constructor.The protected
getResource
,putResource
, andcontainsResourceKey
,getResourceKeySet
abstract the internal representation of this ResourceMap's list ofResourceBundles
. Most applications can ignore them.If
key
is null, an IllegalArgumentException is thrown.- Parameters:
key
- the name of the resource- Returns:
- true if a resource named
key
is defined in this ResourceMap - See Also:
-
getResource
By default this method is used bygetObject
to look up resource values in the internal representation of theResourceBundles
named when this ResourceMap was constructed. If a resource namedkey
isdefined
then its value is returned, otherwise null. ThegetResource
method lazily loads the ResourceBundles named by the constructor.The protected
getResource
,putResource
, andcontainsResourceKey
,getResourceKeySet
abstract the internal representation of this ResourceMap's list ofResourceBundles
. Most applications can ignore them.If
key
is null, an IllegalArgumentException is thrown.- Parameters:
key
- the name of the resource- Returns:
- the value of the resource named
key
(can be null) - See Also:
-
putResource
By default this method is used bygetObject
to cache values that have been retrieved, evaluated (as in ${key} expressions), and string converted. A subclass could override this method to defeat caching or to refine the caching strategy. TheputResource
method lazily loads ResourceBundles.The protected
getResource
,putResource
, andcontainsResourceKey
,getResourceKeySet
abstract the internal representation of this ResourceMap's list ofResourceBundles
. Most applications can ignore them.If
key
is null, an IllegalArgumentException is thrown.- Parameters:
key
- the name of the resourcevalue
- the value of the resource (can be null)- See Also:
-
getObject
Returns the value of the resource named key, or null if no resource with that name exists. A resource exists if it's defined in this ResourceMap or (recursively) in the ResourceMap's parent.String resources may contain variables that name other resources. Each ${variable-key} variable is replaced with the value of a string resource named variable-key. For example, given the following resources:
Application.title = My Application ErrorDialog.title = Error: ${application.title} WarningDialog.title = Warning: ${application.title}
The value of "WarningDialog.title" would be "Warning: My Application". To include "${" in a resource, insert a backslash before the "$". For example, the value of escString in the example below, would be "${hello}":escString = \\${hello}
Note that, in a properties file, the backslash character is used for line continuation, so we've had to escape that too. If the value of a resource is the special variable ${null}, then the resource will be removed from this ResourceMap.The value returned by getObject will be of the specified type. If a string valued resource exists for key, and type is not String.class, the value will be converted using a ResourceConverter and the ResourceMap entry updated with the converted value.
If the named resource exists and an error occurs during lookup, then a ResourceMap.LookupException is thrown. This can happen if string conversion fails, or if resource parameters can't be evaluated, or if the existing resource is of the wrong type.
An IllegalArgumentException is thrown if key or type are null.
- Parameters:
key
- resource nametype
- resource type- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key or type are null- See Also:
-
getString
If no arguments are specified, return the String value of the resource named key. This is equivalent to calling getObject(key, String.class) If arguments are provided, then the type of the resource named key is assumed to beformat
string, which is applied to the arguments if it's non null. For example, given the following resourceshello = Hello %s
then the value of getString("hello", "World") would be "Hello World".- Returns:
- the String value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getBoolean
A convenience method that's shorthand for calling: getObject(key, Boolean.class).- Parameters:
key
- the name of the resource- Returns:
- the Boolean value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getInteger
A convenience method that's shorthand for calling: getObject(key, Integer.class).- Parameters:
key
- the name of the resource- Returns:
- the Integer value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getLong
A convenience method that's shorthand for calling: getObject(key, Long.class).- Parameters:
key
- the name of the resource- Returns:
- the Long value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getShort
A convenience method that's shorthand for calling: getObject(key, Short.class).- Parameters:
key
- the name of the resource- Returns:
- the Short value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getByte
A convenience method that's shorthand for calling: getObject(key, Byte.class).- Parameters:
key
- the name of the resource- Returns:
- the Byte value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getFloat
A convenience method that's shorthand for calling: getObject(key, Float.class).- Parameters:
key
- the name of the resource- Returns:
- the Float value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getDouble
A convenience method that's shorthand for calling: getObject(key, Double.class).- Parameters:
key
- the name of the resource- Returns:
- the Double value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getIcon
A convenience method that's shorthand for calling: getObject(key, Icon.class). This method relies on the ImageIcon ResourceConverter that's registered by this class. SeegetImageIcon(java.lang.String)
for more information.- Parameters:
key
- the name of the resource- Returns:
- the Icon value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getImageIcon
A convenience method that's shorthand for calling: getObject(key, ImageIcon.class). This method relies on the ImageIcon ResourceConverter that's registered by this class.If the resource named key is a String, it should name an image file to be found in the resources subdirectory that also contains the ResourceBundle (typically a ".properties" file) that was used to create the corresponding ResourceMap.
For example, given the ResourceMap produced by Application.getClass(com.mypackage.MyClass.class), and a ResourceBundle called MyClass.properties in com.mypackage.resources:
openIcon = myOpenIcon.png
then resourceMap.getIcon("openIcon") would load the image file called "myOpenIcon.png" from the resources subdirectory, effectively like this:String filename = myResourceMap.getResourcesDir() + "myOpenIcon.png"; URL url = myResourceMap.getClassLoader().getResource(filename); new ImageIcon(iconURL);
- Parameters:
key
- the name of the resource- Returns:
- the ImageIcon value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getFont
A convenience method that's shorthand for calling: getObject(key, Font.class). This method relies on the Font ResourceConverter that's registered by this class. Font resources may be defined with strings that are recognized byFont.decode(java.lang.String)
, face-STYLE-size. For example:myFont = Arial-PLAIN-12
- Parameters:
key
- the name of the resource- Returns:
- the Font value of the resource named key
- See Also:
-
getColor
A convenience method that's shorthand for calling: getObject(key, Color.class). This method relies on the Color ResourceConverter that's registered by this class. It defines an improved version of Color.decode() that supports colors with an alpha channel and comma separated RGB[A] values. Legal format for color resources are:myHexRGBColor = #RRGGBB myHexAlphaRGBColor = #AARRGGBB myRGBColor = R, G, B myAlphaRGBColor = R, G, B, A
The first two examples, with the leading "#" encode the color with 3 or 4 hex values and the latter with integer values between 0 and 255. In both cases the value represented by "A" is the color's (optional) alpha channel.- Parameters:
key
- the name of the resource- Returns:
- the Color value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- ResourceConverter is null- See Also:
-
getKeyStroke
A convenience method that's shorthand for calling: getObject(key, KeyStroke.class). This method relies on the KeyStroke ResourceConverter that's registered by this class and usesKeyStroke.getKeyStroke(char)
to convert strings.- Parameters:
key
- the name of the resource- Returns:
- the KeyStroke value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
getKeyCode
A convenience method that's shorthand for calling: getKeyStroke(key).getKeyCode(). If there's no resource named key then null is returned.- Parameters:
key
- the name of the resource- Returns:
- the KeyCode value of the resource named key
- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionIllegalArgumentException
- if key is null- See Also:
-
injectComponent
Set each property in target to the value of the resource named componentName.propertyName, where componentName is the value of the target component's name property, i.e. the value of target.getName(). The type of the resource must match the type of the corresponding property. Properties that aren't defined by a resource aren't set.For example, given a button configured like this:
myButton = new JButton(); myButton.setName("myButton");
And a ResourceBundle properties file with the following resources:myButton.text = Hello World myButton.foreground = 0, 0, 0 myButton.preferredSize = 256, 256
Then injectComponent(myButton) would initialize myButton's text, foreground, and preferredSize properties to Hello World, new Color(0,0,0), and new Dimension(256,256) respectively.This method calls
getObject(java.lang.String, java.lang.Class)
to look up resources and it usesIntrospector.getBeanInfo(java.lang.Class<?>)
to find the target component's properties.If target is null an IllegalArgumentException is thrown. If a resource is found that matches the target component's name but the corresponding property can't be set, an (unchecked)
ResourceMap.PropertyInjectionException
is thrown.- Parameters:
target
- the Component to inject- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionResourceMap.PropertyInjectionException
- if a property specified by a resource can't be setIllegalArgumentException
- if target is null- See Also:
-
injectComponents
AppliesinjectComponent(java.awt.Component)
to each Component in the hierarchy with root root.- Parameters:
root
- the root of the component hierarchy- Throws:
ResourceMap.PropertyInjectionException
- if a property specified by a resource can't be setIllegalArgumentException
- if target is null- See Also:
-
injectFields
Set each field with a @Resource annotation in the target object, to the value of a resource whose name is the simple name of the target class followed by "." followed by the name of the field. If the key @Resource parameter is specified, then a resource with that name is used instead. Array valued fields can also be initialized with resources whose names end with "[index]". For example:class MyClass { @Resource String sOne; @Resource(key="sTwo") String s2; @Resource int[] numbers = new int[2]; }
Given the previous class and the following resource file:MyClass.sOne = One sTwo = Two MyClass.numbers[0] = 10 MyClass.numbers[1] = 11
Then injectFields(new MyClass()) would initialize the MyClass sOne field to "One", the s2 field to "Two", and the two elements of the numbers array to 10 and 11.If target is null an IllegalArgumentException is thrown. If an error occurs during resource lookup, then an unchecked LookupException is thrown. If a target field marked with @Resource can't be set, then an unchecked InjectFieldException is thrown.
- Parameters:
target
- the object whose fields will be initialized- Throws:
ResourceMap.LookupException
- if an error occurs during lookup or string conversionResourceMap.InjectFieldException
- if a field can't be setIllegalArgumentException
- if target is null- See Also:
-