-
Notifications
You must be signed in to change notification settings - Fork 2
Languages
This library contains a small language system. At the time of writing it consists of two classes:
- MessageProvider
- I18N
This interface is used to abstract most of the workings of the language, so you can easily change the implementation. Sadly only true to an extend, as the copyDefaultLanguages
method is defined in I18N, as this is an interface. But I digress.
The methods are all commented with Javadoc. Not much to add.
This class is a bit more fun. It uses Java's I18N inside.
The only methods visible to you outside the package should be the ones defined by the superinterface. Everything else should be considered a poor choice, maybe a bug and should be done better before anything burns down.
This is a bit trickier. It requires a few things:
Locale currentLanguage
String basePackage
Path savePath
ClassLoader callerClassLoader
Category defaultCategory
Category... more
I will tackle them one by one.
- This is the language it should use
- This is the path to the package where all language files are in
- This is the path to the directory where the files should be saved, for the user to be editable.
- This is the
ClassLoader
of the caller. It is needed to be able to access the guts of another jar file. - This is the default category to use.
- These are more categories.
Now you may have a few questions: "the package where all language files are in"? What are language files? Why a package??
Well, let me explain this.
- A package with your language files. Just a plain old java package
-
Language files. This are files ending on ".proprties". They normally consist of three parts:
- The "Category" (It is the name. I renamed it. Sue me.)
- This can be anything. It is just an identifier to make it possible for you to find it. A typical name could be "Messages".
- The language
- This is the part that tells the system which language is inside the file. It has the following format:
Category_<language tag>.properties
. The language tag for english is "en". So that would be "Messages_en.properties". If you are from Germany, it could be as specific as "Messages_de_DE.properties". There can be pretty much anything, as long as there is a locale for it.
- And ".properties"
- A simple extension.
So your project could look like this: ``` main `- java `- `- resources `- language `- Messages_en.properties `- Messages.properties ```
The Messages.properties
is special. It is a fallback. Every language will eventually end up redirecting here. So having a <Category>.properties
file ensures that every possible language will be translated, even if it fallbacks to the language in there. Always provide it, probably in english.
A lookup looks first in the appropiate language file and then moves closer to `.properties` as it doesn't find a key. So defining it in a more general save file will make it availlabe to all children, without redefining it. This can reduce the file size of the more special languages.
### Usage:
Once you set it up, you can just use one of the method prefixed with "tr" to translate a key. To translate a key called "Test_key" and to color the message that is there, use I18N#tr("Test_key", <Category or blank for default>);
.
**Cooler aspects of the Usage**
-
Variables
It can replace variables. Yay. They have a special format:{<index>}
. An example is{0}
. So consider the following language file:
not_enough_money= You are too broke. Sorry. You only have {0} and need {1}.
Now, if you translate it, you can pass two extra arguments:
I18N#tr("not_enough_money", <Category or blank for default>, 65.66, 89.02425);
This will print "You are too broke. Sorry. You only have 65.66 and need 89.02425".
Not really pretty, is it? You might say this is unfair, I inputed ugly numbers. Truth is a double or float isn't nice. But we can do better! `not_enough_money= You are too broke. Sorry. You only have {0,number,$ #.##} and need {1,number,$ #.##}.` This will print: "You are too broke. Sorry. You only have $ 65.66 and need $ 89.02" A lot better, right?
"number" tells it it is a number and let's you specify a normal `DecimalFormat` pattern. See [here](https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html) for all possibilities.
-
Reference
As of @Rayzr's request you can cross-reference.
So if you have the two keys
Key_one= This is key one
Key_two= This is key two
You can add a third key:
Key_three= [[Key_one]] says "[[Key_two]]"
The result? `This is key one says "This is key two"`
Replacing a variable **doesn't** work in referenced keys.
-
Multi line
If you want a multi-line value, you can use the "\n" escape sequence. If you want that the value spans multiple lines in your editor, add a backslash at the end of the line:
this.is.a.key= This is a multiline \n \
key \n \
And another