I'm refactoring an existing Java desktop application to load internationalized UI text labels from a .properties file. When in the application lifecycle is the appropriate time to load the properties file and populate the strings in memory? The existing implementation defines each component's label as e.g.: public static final String foo = "bar";
It seems inefficient to load the text in the constructor (since it'll be shared among all instances), but doing everything in a static {...}
block doesn't seem remotely sane either. What's the best practice here?
views:
48answers:
4In most applications i've seen, the properties are loaded from a file before starting to construct the main UI. These properties are loaded in a ResourceBundle which will either be
- static
- given as argument to each constructor
I would suggest to load resources lazily. Basically, create a function to get your resource bundle which loads it if it isn't there yet. Than use it to retrieve your resources.
Another way to do so, without changing the code of panels, is to use some kind of "resource injection".
The following libraries perform that, among other things:
- fuse: does just that (but I never tested it and the project seems dead now)
- Swing Application Framework: does a lot of things including resource injection. Maybe worth a check at source code to take out what is relevant for you. Note that the project is also dead, and the source code is quite messy (maybe not easy to extract relevant code)
- Guts-GUI: is a full GUI framework, including resource injection, but it is based on Guice. If you know a bit about Guice, then the source code for resource injection should be easy to understand and extract from the project.
In most cases, resource injection is based on the name given to each component (this is how Swing App Framework and Guts-GUI work, for Fuse I am not sure). If components are not named properly, you also have some options to automatically name them (without changing the source code of panels). I have implemented such an approach in a Guts-GUI package, you may also want to take a look at it.
Then resource injection is normally called just before displaying your frame or dialog (that would be the only code location that have to be modified in your current source, easy if code for opening dialogs/frames has been centralized in one class and not spread all around).
I would opt for lazy loading. When you load everything beforehand you just increase application startup time and may even risk to load stuff that is not even needed (any more).
This static thing, you mentioned, by the way, would effectively end up in lazy loading anyway, since the JVM does lazy loading for classes. Also: when you use ResourceBundles, keep in mind that they do some internal caching, so defining a
public static final String labelText= "hello world";
or, worse, initializing it from a resourcebundle is rather pointless.
Further read: