Search code examples
javaswingpropertiesresourcebundleexternalizing

how to store Usability related values (Font, Dimension, Color,...) in properties file using ResoucesBundles


I'm able to fetch the Strings using a properties file and ResourceBundle class using ResourceBundle.getString(). And even able to fetch int and float objects also using:

int a = (int) ResourceBundle.getObject("IntKey");
float b = (float) ResourceBundle.getObject("FloatKey");

But I want to know to how to fetch some complex objects like fonts?

Font font = (Font) ResourceBundle.getObject("FontKey"); 

But how to store the Font values in properties file? can I store the object like: new Font("Tahoma", Font.PLAIN, 12); into a key:value of a properties file.

Update 1:

@doublesharp your answer is fine. Actually I'm not extending ResourceBundle class to override handleGetObjects() method. My implemention is as shown below:

public class Usability {

    private static final String BUNDLE_NAME = "com.upgrade.utility.resources.Usability";

    private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);

    private Usability() {}

    public static String get(String key, Object ... args) {

        String value = null;
        try {
            value = RESOURCE_BUNDLE.getString(key);
            
            for (Object var : args) {
                if (var != null) {
                    try {
                        value = value.replaceFirst("@", var.toString());
                    } catch (Exception e) {}
                }
            }
        } catch (MissingResourceException e) {
            value = '!' + key + '!';
        }
        return value;
    }
    
    public static Font getFont(String key){
        Font value = null;
        try {
            String fontName = (String) RESOURCE_BUNDLE.getString(key+ ".Name");
            Integer fontStyle = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".Style"));
            Integer fontSize = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".Size"));
            value = new Font(fontName, fontStyle, fontSize);
        } catch (MissingResourceException e) {
            value = new Font("Tahoma", Font.PLAIN, 11);
        }catch (NullPointerException npe) {
            value = new Font("Tahoma", Font.PLAIN, 11);
        }
        
        System.out.println("Font"+ value);
        return value;
        
    }
}

How Can I use your method in this case? I'm new to JAVA, can you please tell me how to modify my implementation to use the method handleGetObjects() ?

Update 2:

@doublesharp: From your last comment, I've modified like this, But getting Class Cast exception in 3rd line of Usability class.

public class Usability {

    private static final String BUNDLE_NAME = "com.upgrade.utility.resources.Usability";

    public static final MyResourceBundle RESOURCE_BUNDLE = (MyResourceBundle) MyResourceBundle.getBundle(BUNDLE_NAME);

    private Usability() {}

    public static String get(String key, Object ... args) {

        String value = null;
        try {
            value = RESOURCE_BUNDLE.getString(key);
            
            for (Object var : args) {
                if (var != null) {
                    try {
                        value = value.replaceFirst("@", var.toString());
                    } catch (Exception e) {}
                }
            }
        } catch (MissingResourceException e) {
            value = '!' + key + '!';
        }
        return value;
    }
    
}

My extended ResourceBunlde class is:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

public class MyResourceBundle extends ResourceBundle{

    @Override
    public Object handleGetObject(String key) {
       if (key.contains("Font")) {
           return getFont(key);
       } else if (key.contains("color")){
           return getColor(key);
       }else if (key.contains("Dimension")){
           return getDimension(key);
       }
    return this.getObject(key);
    }
    
     public Font getFont(String key){
            Font value = null;
            try {
                String fontName = (String) this.getString(key+ ".Name");
                Integer fontStyle = Integer.parseInt(this.getString(key+ ".Style"));
                Integer fontSize = Integer.parseInt(this.getString(key+ ".Size"));
                value = new Font(fontName, fontStyle, fontSize);
            } catch (MissingResourceException e) {
                value = new Font("Tahoma", Font.PLAIN, 11);
            }catch (NullPointerException npe) {
                value = new Font("Tahoma", Font.PLAIN, 11);
            }
            return value;
        }
     
     public Color getColor(String key){
            Color value = null;
            try {
                Integer R = Integer.parseInt(this.getString(key+ ".R"));
                Integer G = Integer.parseInt(this.getString(key+ ".G"));
                Integer B = Integer.parseInt(this.getString(key+ ".B"));
                value = new Color(R, G, B);
            } catch (MissingResourceException e) {
//              value = new Color("Tahoma", Font.PLAIN, 11);
            }catch (NullPointerException npe) {
//              value = new Color("Tahoma", Font.PLAIN, 11);
            }
            return value;
        }
     
     public Dimension getDimension(String key){
            Dimension value = null;
            try {
                Integer X = Integer.parseInt(this.getString(key+ ".X"));
                Integer Y = Integer.parseInt(this.getString(key+ ".Y"));
                value = new Dimension(X, Y);
            } catch (MissingResourceException e) {
//              value = new Color("Tahoma", Font.PLAIN, 11);
            }catch (NullPointerException npe) {
//              value = new Color("Tahoma", Font.PLAIN, 11);
            }
            return value;
        }

    @Override
    public Enumeration<String> getKeys() {
        return null;
    }
    
}

How to resolve this exception?

And also Is there problem in my answer? using which I was just calling like

Usability.getFont("JPanelUpgradeTypeScreen.ElementLabelFont");

But using your answer techinque, I need to call it like (Type conversion is needed in call) :

(Font)Usability.RESOURCE_BUNDLE.handleGetObject("JPanelUpgradeTypeScreen.ElementLabelFont");

Solution

  • In a class I've defined the following functions, which I call whenever I need to access the usability related valus. All the usability related values are stored at a common place (properties file).

    private static final String BUNDLE_NAME = "com.testApp.resources.properties.Usability";
    
    private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
    
        public static Font getFont(String key){
            Font value = null;
            try {
                String fontName = (String) RESOURCE_BUNDLE.getString(key+ ".Name");
                Integer fontStyle = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".Style"));
                Integer fontSize = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".Size"));
                value = new Font(fontName, fontStyle, fontSize);
            } catch (MissingResourceException e) {
                value = new Font("Tahoma", Font.PLAIN, 11);
            }catch (NullPointerException npe) {
                value = new Font("Tahoma", Font.PLAIN, 11);
            }
            return value;
        }
    
        public static Color getColor(String key){
            Color value = null;
            try {
                Integer R = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".R"));
                Integer G = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".G"));
                Integer B = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".B"));
                value = new Color(R, G, B);
            } catch (MissingResourceException e) {
    //            value = new Color("Tahoma", Font.PLAIN, 11);
            }catch (NullPointerException npe) {
    //          value = new Color("Tahoma", Font.PLAIN, 11);
            }
            return value;
        }
    
     public static Dimension getDimension(String key){
            Dimension value = null;
            try {
                Integer X = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".X"));
                Integer Y = Integer.parseInt(RESOURCE_BUNDLE.getString(key+ ".Y"));
                value = new Dimension(X, Y);
            } catch (MissingResourceException e) {
    //            value = new Color("Tahoma", Font.PLAIN, 11);
            }catch (NullPointerException npe) {
    //          value = new Color("Tahoma", Font.PLAIN, 11);
            }
            return value;
        }
    }
    

    In properties file which I'm maintaining for usability related values the properties are defined as below:

    #BLACK
    ElementLabelFont.Color.R=4
    ElementLabelFont.Color.G=4
    ElementLabelFont.Color.B=4
    
    #ScreenPanel dimension
    ScreenPanel.Dimension.X=632
    ScreenPanel.Dimension.Y=625
    
    #Font of jCheckBoxYesAgreement
    JPanelPreUpgradeStepsScreen.jCheckBoxYesAgreement.Font.Name=Tahoma
    JPanelPreUpgradeStepsScreen.jCheckBoxYesAgreement.Font.Style=0
    JPanelPreUpgradeStepsScreen.jCheckBoxYesAgreement.Font.Size=12