在java中想要根据不同的环境设置不同的字符,可以使用下面的这种方法:
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class Messages {
private static final String BUNDLE_NAME ="messages"; //$NON-NLS-1$
private static final ResourceBundleRESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
private Messages() {
}
public static String getString(String key){
try {
returnRESOURCE_BUNDLE.getString(key);
} catch(MissingResourceException e) {
return '!' +key + '!';
}
}
publicstatic String getText(String key, String argument1)
{
return getText(key, argument1, null);
}
publicstatic String getText(String key, String argument1, Stringargument2)
{
return getText(key, argument1, argument2, null);
}
publicstatic String getText(String key, String argument1, Stringargument2, String argument3)
{
String as[] = new String[3];
as[0] = argument1;
as[1] = argument2;
as[2] = argument3;
return getText(key, as);
}
// Supportany numbers arguments
publicstatic String getText(String key, String[] arguments)
{
if(RESOURCE_BUNDLE == null)
return null;
try
{
String message = RESOURCE_BUNDLE.getString(key);
return MessageFormat.format(message, arguments);
}
catch(MissingResourceException missingresourceexception)
{
return null;
}
}
}
编写messages.properties,上面的类会自动读取里面的变量:
如:
toolItemLoadCode = Load
view = View
程序中使用:
toolItemLoadCode.setToolTipText(Messages.getString("view"));
在这里有一个要注意的问题,那就是messages.properties文件的放置位置,有的时候会出现下面的错误:
java.util.MissingResourceException: Can't find bundle for basename
解决解释如下:
Solve java.util.MissingResourceException: Can't findbundle for base name com...config, locale zh_CN
atjava.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:836)
atjava.util.ResourceBundle.getBundleImpl(ResourceBundle.java:805)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:576)
You know java is looking for a properties file in a specificlocale. You may be baffled whyjava keeps complaining it can't find a properties file that isright there. A few things tokeep in mind when debugging this type of errors:
- These resource properties files are loaded by classloader,similar to java classes. So youneed to include them in your runtime classpath.
- These resources have fully-qualified-resource-name, similar toa fully-qualified-class-name, excerpt you can't import a resourceinto your java source file. Why? because its name takes the form of a string.
ResourceBundle.getBundle("config")
tells theclassloader to load a resource named "config"
with default package (that is, nopackage). It does NOT mean aresource in the current package that has the referencingclass.
ResourceBundle.getBundle("com.cheng.scrap.config")
tells the classloader to load a resource named "config"
with package "com.cheng.scrap."
Itsfully-qualified-resource-name is "com.cheng.scrap.config"
For instance, you have a project like
C:\ws\netbeans5\scrap>
| build.xml
+---build
| \---classes
| \---com
| \---cheng
| \---scrap
| Scrap.class
|
+---src
| \---com
| \---cheng
| \---scrap
| config.properties
| Scrap.java
For this statement in Scrap.java:ResourceBundle config =ResourceBundle.getBundle("config");
to work, you willneed to cp src\com\cheng\scrap\config.propertiesbuild\classes\
such that config.properties
is directly underclasses
, and at the same levelas com
. Alternatively, you can put config.properties
into a config.jar
such that config.properties
is at the root ofconfig.jar
without anysubdirectories, and include config.jar
in the classpath.
For this statement in Scrap.java:ResourceBundle config =ResourceBundle.getBundle("com.cheng.scrap.config");
to work, you will needto cpsrc\com\cheng\scrap\config.propertiesbuild\classes\
com\cheng\scrap\
such thatconfig.properties
is directlyunder classes
\
com\cheng\scrap\
,and at the same level as scrap
. Alternatively, you can put com\cheng\scrap\
config.properties
(along with the long subdirectories) into a config.jar
, andinclude config.jar
in theclasspath.
You may be wondering why it is made soconfusing? The benefits aretwo-fold, as I see it:
- Location transparency. Atruntime, config.properties is NOT a file, it's just a a loadableresource. config.properites maynot exist in your project at all, and the person who wroteScrap.java may have never seen thisresource. A URLClassLoader canfind it in a network path or URL atruntime. This is especiallyimportant for server-side components such as EJB, Servlet, JSP,etc, who are normally not allowed to access filesystems. When you askclassloaders for a resource, its physical location becomesirrelevant.
- Namespace mechanism. Havinga package allows multiple packages to have resources with the sameshort name without causing conflicts. This is no different fromjava packages and xml namespaces.