Managing resources in the Swing Application Framework (JSR 296)


Instead of loading and working with ResourceBundle files directly, you will use the ResourceManager and ResourceMap framework classes to manage resources. A ResourceMap contains the resources defined in a specific ResourceBundle implementation. A map also contains links to its parent chain of ResoureMap objects. The parent chain for any class includes the ResourceMap for that specific class, the application subclass to which the class belongs, and all superclasses of your application up to the base Application class.

The ResourceManager is responsible for creating ResourceMaps and their parent chains when you request resources. You will use the ApplicationContext to retrieve ResourceManager and ResourceMap objects.

You have three options for working with resources:

  1. manually load and use ResourceMap objects and their resources
  2. use the framework to automatically inject resources into the UI components that need them
  3. use the framework to automatically inject resources into the object fields that need need them

Covering all three options is a bit much for one blog post, but I can let you know about manual resource management. Maybe the remaining methods are the seeds of another blog entry…maybe an article?

Manual Resource Management

The ApplicationContext class provides access to the ResourceManager and its ResourceMap instances. Retrieve the ApplicationContext using the static getInstance method. Then you can use the context to retrieve a ResourceManager and a ResourceMap. Use the ResourceMap object to retrieve resources for your application or specific class. The following example shows how to retrieve resources and apply them to UI components.

public class HelloWorld extends SingleFrameApplication {
    JLabel label;
    ResourceMap resource;
    protected void initialize(String[] args) {
        ApplicationContext ctxt = ApplicationContext.getInstance();  
        ResourceManager mgr = ctxt.getResourceManager();
        resource = mgr.getResourceMap(HelloWorld.class);
    protected void startup() {
        label = new JLabel();
        String helloText = (String) resource.getObject("helloLabel", String.class);
        // You can optionally use the convenience methods that cast resources for you
        Color backgroundColor = resource.getColor("color");
        String title = resource.getString("title");

You can also retrieve retrieve ResourceMap objects using the convenience method in the ApplicationContext instance:

resource = ctxt.getResourceMap(HelloWorld.class);

The HelloWorld class uses three resources: a label’s text, a color for the label background, and text for the frame’s window title. It gets those resources from a ResourceBundle for the HelloWorld class. You know that because the application gets a ResourceMap instance for a specific class, the HelloWorld.class, as shown in this code line:

resource = mgr.getResourceMap(HelloWorld.class);

You provide the Class instance that represents either your Application subclass or a specific class in your application. The ResourceManager will search and load a ResourceMap that holds the resources defined in a resources subpackage below the HelloWorld class. In this case the ResourceBundle implementation is a file at resources/ The following code shows part of the file.

helloLabel = Hello, world!
color = #AABBCC
title = HelloWorld with Resources

The next figure shows the HelloWorld application. Each of the resources — the window title, the label text, and the label background color — were manually retrieved and applied to each specific component. When you use manual resource management, you are responsible for providing code to perform all steps of retrieving and using the resources in the appropriate component.

That’s it. Now you can create ResourceMap objects that map onto ResourceBundle implementations for your entire application or for a specific class. You can load those maps, and you can retrieve resources from them. You know there’s a better way right? Yep, there is. But that information will have to wait until next time. Or you could find out right now if you check out the JSR 296 reference implementation.

Leave a Reply

Your email address will not be published. Required fields are marked *