Internationalization and enums

H

Hayward Hulick

It appears that Java enums are not of much use when Internationalization
(I18n) is a concern. The values are hardcoded and can't be changed without
recompiling. While variables could be added to include the I18n information
in the enum class, all related methods and variables would have to be
re-coded for each enum since enums can't be subclassed. Can anyone suggest
a way around this problem? If not, I guess I'll just have to create my own
class with static final values.

Hayward Hulick
 
B

Bent C Dalager

It appears that Java enums are not of much use when Internationalization
(I18n) is a concern. The values are hardcoded and can't be changed without
recompiling. While variables could be added to include the I18n information
in the enum class, all related methods and variables would have to be
re-coded for each enum since enums can't be subclassed. Can anyone suggest
a way around this problem? If not, I guess I'll just have to create my own
class with static final values.

It's not entirely clear why i18n conflicts with enums in your case,
but if I were to guess I would say that your problems may be solved by
overriding toString() in the enum class to ensure that it supports
i18n.

I am assuming that what you are trying to internationalize is program
output rather than the source code itself.

Cheers
Bent D
 
T

Thomas Fritsch

Hayward said:
It appears that Java enums are not of much use when Internationalization
(I18n) is a concern. The values are hardcoded and can't be changed without
recompiling. While variables could be added to include the I18n information
in the enum class, all related methods and variables would have to be
re-coded for each enum since enums can't be subclassed. Can anyone suggest
a way around this problem? If not, I guess I'll just have to create my own
class with static final values.
I suggest to override your enum's toString() method, so that it returns
a locale-dependent String.
There is more info in the API docs of Enum#toString,
ResourceBundle#getBundle and PropertyResourceBundle.
Below is a simple example for this approach.
When I run it (on my german system) I get an output with german Strings:
MERCURY: Merkur
VENUS: Venus
EARTH: Erde
MARS: Mars

// File de/tfritsch/Planet.java
package de.tfritsch;

import java.util.ResourceBundle;

public enum Planet {
MERCURY, VENUS, EARTH, MARS;

/** Resources for the default locale */
private static final ResourceBundle res =
ResourceBundle.getBundle("de.tfritsch.Res");

/** @return the locale-dependent name of the planet */
public String toString() {
return res.getString(name() + ".string");
}

/** Tests the toString() method for all constants. */
public static void main(String[] args) {
for (Planet value : values()) {
System.out.println(value.name() + ": " + value);
}
}
}


# File de/tfritsch/Res.properties
# default language (english) resources
MERCURY.string=Mercury
VENUS.string=Venus
EARTH.string=Earth
MARS.string=Mars


# File de/tfritsch/Res_de.properties
# german language resources
MERCURY.string=Merkur
VENUS.string=Venus
EARTH.string=Erde
MARS.string=Mars

.... (and so for French, Spanish, Russian, ...)
 
W

Wojtek

Hayward Hulick wrote :
It appears that Java enums are not of much use when Internationalization
(I18n) is a concern. The values are hardcoded and can't be changed without
recompiling. While variables could be added to include the I18n information
in the enum class, all related methods and variables would have to be
re-coded for each enum since enums can't be subclassed. Can anyone suggest a
way around this problem? If not, I guess I'll just have to create my own
class with static final values.

Hayward Hulick

public SomeClass
{
public enum MyEnum
{
VALUE_ONE("I18N_Key.for.one"),
VALUE_TWO("I18N_Key.for.two");

private String i18NKey;

private MyEnum(String i18N)
{
i18NKey = i18n;
}

public static String getI18NKey()
{
return i18NKey;
}
}
}


.....

String key = MyEnum.VALUE_ONE.getI18NKey();
.....
 
W

Wojtek

Hayward Hulick wrote :
It appears that Java enums are not of much use when Internationalization
(I18n) is a concern. The values are hardcoded and can't be changed without
recompiling. While variables could be added to include the I18n
information in the enum class, all related methods and variables would have
to be re-coded for each enum since enums can't be subclassed. Can anyone
suggest a way around this problem? If not, I guess I'll just have to
create my own class with static final values.

Hayward Hulick

public SomeClass
{
public enum MyEnum
{
VALUE_ONE("I18N_Key.for.one"),
VALUE_TWO("I18N_Key.for.two");

private String i18NKey;

private MyEnum(String i18N)
{
i18NKey = i18n;
}

public String getI18NKey()
{
return i18NKey;
}
}
}


.....

String key = MyEnum.VALUE_ONE.getI18NKey();
.....
 
T

Thomas Fritsch

Wojtek said:
public SomeClass
{
public enum MyEnum
{
VALUE_ONE("I18N_Key.for.one"),
VALUE_TWO("I18N_Key.for.two");

private String i18NKey;

private MyEnum(String i18N)
{
i18NKey = i18n;
}

public String getI18NKey()
{
return i18NKey;
}
}
}


....

String key = MyEnum.VALUE_ONE.getI18NKey();
....
There is no need to introduce an additional variable (i18NKey) as key.
You can use the programmatic name ("VALUE_ON", "VALUE_TWO") as key:
String key = MyEnum.VALUE_ONE.name();
 
H

Hayward Hulick

Thomas Fritsch said:
Hayward said:
It appears that Java enums are not of much use when
Internationalization (I18n) is a concern. The values are hardcoded and
can't be changed without recompiling. While variables could be added to
include the I18n information in the enum class, all related methods and
variables would have to be re-coded for each enum since enums can't be
subclassed. Can anyone suggest a way around this problem? If not, I
guess I'll just have to create my own class with static final values.
I suggest to override your enum's toString() method, so that it returns a
locale-dependent String.
There is more info in the API docs of Enum#toString,
ResourceBundle#getBundle and PropertyResourceBundle.
Below is a simple example for this approach.
When I run it (on my german system) I get an output with german Strings:
MERCURY: Merkur
VENUS: Venus
EARTH: Erde
MARS: Mars

// File de/tfritsch/Planet.java
package de.tfritsch;

import java.util.ResourceBundle;

public enum Planet {
MERCURY, VENUS, EARTH, MARS;

/** Resources for the default locale */
private static final ResourceBundle res =
ResourceBundle.getBundle("de.tfritsch.Res");

/** @return the locale-dependent name of the planet */
public String toString() {
return res.getString(name() + ".string");
}

/** Tests the toString() method for all constants. */
public static void main(String[] args) {
for (Planet value : values()) {
System.out.println(value.name() + ": " + value);
}
}
}


# File de/tfritsch/Res.properties
# default language (english) resources
MERCURY.string=Mercury
VENUS.string=Venus
EARTH.string=Earth
MARS.string=Mars


# File de/tfritsch/Res_de.properties
# german language resources
MERCURY.string=Merkur
VENUS.string=Venus
EARTH.string=Erde
MARS.string=Mars

... (and so for French, Spanish, Russian, ...)

Thank you. Your solution is a lot simpler than the one I came up with,
and doesn't involve a lot of extra code to be repeated in every enum.
Thanks again.

Hayward
 
R

Roedy Green

It appears that Java enums are not of much use when Internationalization
(I18n) is a concern. The values are hardcoded and can't be changed without
recompiling. While variables could be added to include the I18n information
in the enum class, all related methods and variables would have to be
re-coded for each enum since enums can't be subclassed. Can anyone suggest
a way around this problem? If not, I guess I'll just have to create my own
class with static final values.

the enum name appears only inside code. It is merely a default for
external use. You can write your own internationalised enum toString
or valueOf
 
W

Wojtek

Thomas Fritsch wrote :
There is no need to introduce an additional variable (i18NKey) as key.
You can use the programmatic name ("VALUE_ON", "VALUE_TWO") as key:
String key = MyEnum.VALUE_ONE.name();

Not if you organize your I18N.

Mine looks a lot like:

report.finance.yearly.total

and

system.admin.control.blockLogin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Fixing "typos" in enums... 18
Enums: Properties vs. Methods 33
enums and modifiers 5
masks and enums 21
I don't understand enums 14
enums and scope 5
enums 6
Question about Typesafe Enums 8

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top