如何使用ResoucesBundles在属性文件中存储与可用性相关的值(字体,尺寸,颜色......)

时间:2012-10-18 05:23:59

标签: java swing properties resourcebundle externalizing

我可以使用ResourceBundle.getString()使用属性文件和ResourceBundle类来获取字符串。甚至还可以使用以下方法获取int和float对象:

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

但我想知道如何获取像字体这样的复杂对象?

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

但是如何在属性文件中存储Font值?我可以将对象存储为:new Font("Tahoma", Font.PLAIN, 12);到一个键:属性文件的值。

更新1:

@doublesharp你的答案很好。实际上我没有扩展ResourceBundle类来覆盖handleGetObjects()方法。我的实现如下所示:

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;

    }
}

在这种情况下,我如何使用您的方法?我是JAVA的新手,你能告诉我如何修改我的实现以使用方法handleGetObjects()吗?

更新2:

@doublesharp:从你上次的评论来看,我已经修改过了,但是在可用性类的第3行获得了Class Cast异常。

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;
    }

}

我的扩展ResourceBunlde类是:

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;
    }

}

如何解决此异常?

在我的回答中是否存在问题?使用我刚刚调用的内容

Usability.getFont("JPanelUpgradeTypeScreen.ElementLabelFont");

但是使用你的答案技术,我需要调用它(在调用中需要类型转换):

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

5 个答案:

答案 0 :(得分:2)

不应在属性文件中初始化对象。您应该只在属性文件中使用常量值

答案 1 :(得分:0)

您需要覆盖实施的handleGetObject()方法。您不能将对象定义存储在属性文件中,但可以将其初始化参数存储为键,并在返回对象时使用它们。在此示例中,您将设置font-family(Tahoma等),font-type(用于映射到Font.BOLD等的文本值)和font-size的属性。调用MyResourceBundle.getObject("font")(扩展ResourceBundle的类)会调用handleGetObject()的实现,然后使用以前的值来创建对象:

@Override
public Object handleGetObject(String key) {
   if (key.equals("font")) {
      String family = this.getString("font-family");
      String strType = this.getString("font-type");
      int type;
      switch (strType){
          case "bold": Font.BOLD;
          default: type = Font.PLAIN;
      }
      int size = this.getInt("font-size");
      return new Font(family, type, size);
   } else {
      return null;
   }
}

答案 2 :(得分:0)

您可以序列化自定义对象,然后使用base64编码包装二进制代码,例如,您可以将其作为字符串写入属性

答案 3 :(得分:0)

从您的所有答案和评论中获取输入:这是答案,满足了我的要求:

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;   
    }

内部属性文件我存储为

#Usability
    DialogTextFont.Name=Tahoma
    DialogTextFont.Style=0
    DialogTextFont.Size=12

答案 4 :(得分:0)

在课程中,我定义了以下函数,每当我需要访问可用性相关的valus时,我都会调用它们。所有可用性相关值都存储在公共位置(属性文件)。

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;
    }
}

在我为可用性相关值维护的属性文件中,属性定义如下:

#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