I was thinking about using enum
type to manage i18n in a Java game I'm developing but I was curious about performance issues that can occur when working with enums that have lots of elements (thousands I think).
Actually I'm trying something like:
public enum Text {
STRING1,
STRING2,
STRING3;
public String text() {
return text;
}
public String setText() {
this.text = text;
}
}
Then to load them I can just fill the fields:
static
{
Text.STRING1.setText("My localized string1");
Text.STRING2.setText("My localized string2");
Text.STRING3.setText("My localized string3");
}
Of course when I'll have to manage many languages I'll load them from a file.
What I'm asking is
Text.STRING1.text()
). So it should be constant complexity or maybe they are just replaced during the compiling phase..Thanks
Found and adapted a nice mix of enums and ResourceBundle:
public enum Text {
YELL, SWEAR, BEG, GREET /* and more */ ;
/** Resources for the default locale */
private static final ResourceBundle res =
ResourceBundle.getBundle("com.example.Messages");
/** @return the locale-dependent message */
public String toString() {
return res.getString(name() + ".string");
}
}
# File com/example/Messages.properties
# default language (english) resources
YELL.string=HEY!
SWEAR.string=§$%&
BEG.string=Pleeeeeease!
GREET.string=Hello player!
# File com/example/Messages_de.properties
# german language resources
YELL.string=HEY!
SWEAR.string=%&$§
BEG.string=Biiiiiitte!
GREET.string=Hallo Spieler!
You're probably better off using the java.util.ResourceBundle
class. It is designed to solve exactly this problem.
To answer your questions:
I hate to hijack to topic, but relying on enums for i18n is going to eventually paint you into a corner. Java has proper i18n support, even going so far as to have a tutorial for it.
although java has i18n support using ResourceBundle I do not think that idea to use enum for this purpose is so bad. I believe that these 2 approaches can be merged. You can create enum Texts
that contains all your text identifiers. You can create resource bundles for each supported language and use the same identifiers in this bundle.
Then implement getText()
method in the enum as following:
return ResourceBundle.getBundle("texts").getString(name());
So, you do not have to care about the initialization of texts for each language. The standard mechanism cares about this.
Now you use in code the enums and enjoy all features of bundles. You can also create unit test that verifies that all enum members have appropriate lines in bundle and vice versa to avoid garbage in your bundles.
I will probably use this approach in my next project. Thank you for the idea!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With